# [Scipy-svn] r4694 - in trunk/scipy/cluster: . src tests

scipy-svn@scip... scipy-svn@scip...
Sun Sep 7 14:28:15 CDT 2008

Author: damian.eads
Date: 2008-09-07 14:28:06 -0500 (Sun, 07 Sep 2008)
New Revision: 4694

trunk/scipy/cluster/tests/cdist-X1.txt
trunk/scipy/cluster/tests/cdist-X2.txt
Modified:
trunk/scipy/cluster/distance.py
trunk/scipy/cluster/src/distance.c
trunk/scipy/cluster/src/distance.h
trunk/scipy/cluster/src/distance_wrap.c
trunk/scipy/cluster/tests/test_distance.py
Log:
Added cdist function for computing distances between two collections of vectors. Added tests for the cdist function.

Modified: trunk/scipy/cluster/distance.py
===================================================================
--- trunk/scipy/cluster/distance.py	2008-09-07 07:46:29 UTC (rev 4693)
+++ trunk/scipy/cluster/distance.py	2008-09-07 19:28:06 UTC (rev 4694)
@@ -796,7 +796,7 @@

def pdist(X, metric='euclidean', p=2, V=None, VI=None):
"""
-    Computes the distance between m original observations in
+    Computes the pairwise distances between m original observations in
n-dimensional space. Returns a condensed distance matrix Y.  For
each :math:$i$ and :math:$j$ (where :math:$i<j<n$), the
metric dist(u=X[i], v=X[j]) is computed and stored in the
@@ -1001,6 +1001,8 @@
dm = pdist(X, 'sokalsneath')

"""
+
+
#         21. Y = pdist(X, 'test_Y')
#
#           Computes the distance between all pairs of vectors in X
@@ -1131,7 +1133,7 @@
elif mstr == 'canberra':
_distance_wrap.pdist_canberra_wrap(_convert_to_double(X), dm)
elif mstr == 'braycurtis':
-            _distance_wrap.pdist_bray_curtis_wrap(_convert_to_bool(X), dm)
+            _distance_wrap.pdist_bray_curtis_wrap(_convert_to_double(X), dm)
elif mstr == 'yule':
_distance_wrap.pdist_yule_bool_wrap(_convert_to_bool(X), dm)
elif mstr == 'matching':
@@ -1204,6 +1206,7 @@
else:
raise TypeError('2nd argument metric must be a string identifier or a function.')
return dm
+
def squareform(X, force="no", checks=True):
"""
Converts a vector-form distance vector to a square-form distance
@@ -1497,3 +1500,456 @@
is_valid_y(Y, throw=True, name='Y')
d = int(np.ceil(np.sqrt(Y.shape[0] * 2)))
return d
+
+
+def cdist(XA, XB, metric='euclidean', p=2, V=None, VI=None):
+    """
+    Computes distance between each pair of observations between two
+    collections of vectors. XA is a :math:$m_A$ by :math:$n$
+    array while XB is a :math:$m_B$ by :math:$n$ array. A
+    :math:$m_A$ by :math:$m_B$ array is returned. An exception is
+    thrown if XA and XB do not have the same number of
+    columns.
+
+    A rectangular distance matrix Y is returned. For each :math:$i$
+    and :math:$j$, the metric dist(u=XA[i], v=XB[j]) is computed
+    and stored in the :math:ijth entry.
+
+
+    :Parameters:
+       XA : ndarray
+           An :math:$m_A$ by :math:$n$ array of :math:$m_A$
+           original observations in an n-dimensional space.
+       XB : ndarray
+           An :math:$m_B$ by :math:$n$ array of :math:$m_B$
+           original observations in an n-dimensional space.
+       metric : string or function
+           The distance metric to use. The distance function can
+           be 'braycurtis', 'canberra', 'chebyshev', 'cityblock',
+           'correlation', 'cosine', 'dice', 'euclidean', 'hamming',
+           'jaccard', 'kulsinski', 'mahalanobis', 'matching',
+           'minkowski', 'rogerstanimoto', 'russellrao', 'seuclidean',
+           'sokalmichener', 'sokalsneath', 'sqeuclidean', 'yule'.
+
+    :Returns:
+       Y : ndarray
+           A :math:$m_A$ by :math:$m_B$ distance matrix.
+
+    Calling Conventions
+    -------------------
+
+    1. Y = cdist(X, 'euclidean')
+
+       Computes the distance between m points using Euclidean distance
+       (2-norm) as the distance metric between the points. The points
+       are arranged as m n-dimensional row vectors in the matrix X.
+
+    2. Y = cdist(X, 'minkowski', p)
+
+       Computes the distances using the Minkowski distance
+       :math:$||u-v||_p$ (p-norm) where :math:$p \geq 1$.
+
+    3. Y = cdist(X, 'cityblock')
+
+       Computes the city block or Manhattan distance between the
+       points.
+
+    4. Y = cdist(X, 'seuclidean', V=None)
+
+       Computes the standardized Euclidean distance. The standardized
+       Euclidean distance between two n-vectors u and v is
+
+       .. math:
+
+          sqrt(\sum {(u_i-v_i)^2 / V[x_i]}).
+
+       V is the variance vector; V[i] is the variance computed over all
+          the i'th components of the points. If not passed, it is
+          automatically computed.
+
+    5. Y = cdist(X, 'sqeuclidean')
+
+       Computes the squared Euclidean distance ||u-v||_2^2 between
+       the vectors.
+
+    6. Y = cdist(X, 'cosine')
+
+       Computes the cosine distance between vectors u and v,
+
+       .. math:
+
+          \frac{1 - uv^T}
+               {{|u|}_2 {|v|}_2}
+
+       where |*|_2 is the 2 norm of its argument *.
+
+    7. Y = cdist(X, 'correlation')
+
+       Computes the correlation distance between vectors u and v. This is
+
+       .. math:
+
+          \frac{1 - (u - n{|u|}_1){(v - n{|v|}_1)}^T}
+               {{|(u - n{|u|}_1)|}_2 {|(v - n{|v|}_1)|}^T}
+
+       where :math:$|*|_1$ is the Manhattan (or 1-norm) of its
+       argument, and :math:$n$ is the common dimensionality of the
+       vectors.
+
+    8. Y = cdist(X, 'hamming')
+
+       Computes the normalized Hamming distance, or the proportion of
+       those vector elements between two n-vectors u and v
+       which disagree. To save memory, the matrix X can be of type
+       boolean.
+
+    9. Y = cdist(X, 'jaccard')
+
+       Computes the Jaccard distance between the points. Given two
+       vectors, u and v, the Jaccard distance is the
+       proportion of those elements u[i] and v[i] that
+       disagree where at least one of them is non-zero.
+
+    10. Y = cdist(X, 'chebyshev')
+
+       Computes the Chebyshev distance between the points. The
+       Chebyshev distance between two n-vectors u and v is the
+       maximum norm-1 distance between their respective elements. More
+       precisely, the distance is given by
+
+       .. math:
+
+          d(u,v) = max_i {|u_i-v_i|}.
+
+    11. Y = cdist(X, 'canberra')
+
+       Computes the Canberra distance between the points. The
+       Canberra distance between two points u and v is
+
+       .. math:
+
+         d(u,v) = \sum_u {|u_i-v_i|}
+                         {|u_i|+|v_i|}
+
+
+    12. Y = cdist(X, 'braycurtis')
+
+       Computes the Bray-Curtis distance between the points. The
+       Bray-Curtis distance between two points u and v is
+
+
+       .. math:
+
+            d(u,v) = \frac{\sum_i {u_i-v_i}}
+                          {\sum_i {u_i+v_i}}
+
+    13. Y = cdist(X, 'mahalanobis', VI=None)
+
+       Computes the Mahalanobis distance between the points. The
+       Mahalanobis distance between two points u and v is
+       :math:$(u-v)(1/V)(u-v)^T$ where :math:$(1/V)$ (the VI
+       variable) is the inverse covariance. If VI is not None,
+       VI will be used as the inverse covariance matrix.
+
+    14. Y = cdist(X, 'yule')
+
+       Computes the Yule distance between each pair of boolean
+       vectors. (see yule function documentation)
+
+    15. Y = cdist(X, 'matching')
+
+       Computes the matching distance between each pair of boolean
+       vectors. (see matching function documentation)
+
+    16. Y = cdist(X, 'dice')
+
+       Computes the Dice distance between each pair of boolean
+       vectors. (see dice function documentation)
+
+    17. Y = cdist(X, 'kulsinski')
+
+       Computes the Kulsinski distance between each pair of
+       boolean vectors. (see kulsinski function documentation)
+
+    18. Y = cdist(X, 'rogerstanimoto')
+
+       Computes the Rogers-Tanimoto distance between each pair of
+       boolean vectors. (see rogerstanimoto function documentation)
+
+    19. Y = cdist(X, 'russellrao')
+
+       Computes the Russell-Rao distance between each pair of
+       boolean vectors. (see russellrao function documentation)
+
+    20. Y = cdist(X, 'sokalmichener')
+
+       Computes the Sokal-Michener distance between each pair of
+       boolean vectors. (see sokalmichener function documentation)
+
+    21. Y = cdist(X, 'sokalsneath')
+
+       Computes the Sokal-Sneath distance between each pair of
+       boolean vectors. (see sokalsneath function documentation)
+
+    22. Y = cdist(X, f)
+
+       Computes the distance between all pairs of vectors in X
+       using the user supplied 2-arity function f. For example,
+       Euclidean distance between the vectors could be computed
+       as follows::
+
+         dm = cdist(X, (lambda u, v: np.sqrt(((u-v)*(u-v).T).sum())))
+
+       Note that you should avoid passing a reference to one of
+       the distance functions defined in this library. For example,::
+
+         dm = cdist(X, sokalsneath)
+
+       would calculate the pair-wise distances between the vectors in
+       X using the Python function sokalsneath. This would result in
+       sokalsneath being called :math:${n \choose 2}$ times, which
+       is inefficient. Instead, the optimized C version is more
+       efficient, and we call it using the following syntax.::
+
+         dm = cdist(X, 'sokalsneath')
+
+       """
+
+
+#         21. Y = cdist(X, 'test_Y')
+#
+#           Computes the distance between all pairs of vectors in X
+#           using the distance metric Y but with a more succint,
+#           verifiable, but less efficient implementation.
+
+
+    XA = np.asarray(XA)
+    XB = np.asarray(XB)
+
+    #if np.issubsctype(X, np.floating) and not np.issubsctype(X, np.double):
+    #    raise TypeError('Floating point arrays must be 64-bit (got %r).' %
+    #    (X.dtype.type,))
+
+    # The C code doesn't do striding.
+    [XA] = _copy_arrays_if_base_present([_convert_to_double(XA)])
+    [XB] = _copy_arrays_if_base_present([_convert_to_double(XB)])
+
+    s = XA.shape
+    sB = XB.shape
+
+    if len(s) != 2:
+        raise ValueError('XA must be a 2-dimensional array.');
+    if len(sB) != 2:
+        raise ValueError('XB must be a 2-dimensional array.');
+    if s[1] != sB[1]:
+        raise ValueError('XA and XB must have the same number of columns (i.e. feature dimension.)')
+
+    mA = s[0]
+    mB = sB[0]
+    n = s[1]
+    dm = np.zeros((mA, mB), dtype=np.double)
+
+    mtype = type(metric)
+    if mtype is types.FunctionType:
+        if metric == minkowski:
+            for i in xrange(0, mA):
+                for j in xrange(0, mB):
+                    dm[i, j] = minkowski(XA[i, :], XB[j, :], p)
+        elif metric == seuclidean:
+            for i in xrange(0, mA):
+                for j in xrange(0, mB):
+                    dm[i, j] = seuclidean(XA[i, :], XB[j, :], V)
+        elif metric == mahalanobis:
+            for i in xrange(0, mA):
+                for j in xrange(0, mB):
+                    dm[i, j] = mahalanobis(XA[i, :], XB[j, :], V)
+        else:
+            for i in xrange(0, mA):
+                for j in xrange(0, mB):
+                    dm[i, j] = metric(XA[i, :], XB[j, :])
+    elif mtype is types.StringType:
+        mstr = metric.lower()
+
+        #if XA.dtype != np.double and \
+        #       (mstr != 'hamming' and mstr != 'jaccard'):
+        #    TypeError('A double array must be passed.')
+        if mstr in set(['euclidean', 'euclid', 'eu', 'e']):
+            _distance_wrap.cdist_euclidean_wrap(_convert_to_double(XA),
+                                                _convert_to_double(XB), dm)
+        elif mstr in set(['sqeuclidean', 'sqe', 'sqeuclid']):
+            _distance_wrap.cdist_euclidean_wrap(_convert_to_double(XA),
+                                                _convert_to_double(XB), dm)
+            dm **= 2.0
+        elif mstr in set(['cityblock', 'cblock', 'cb', 'c']):
+            _distance_wrap.cdist_city_block_wrap(_convert_to_double(XA),
+                                                 _convert_to_double(XB), dm)
+        elif mstr in set(['hamming', 'hamm', 'ha', 'h']):
+            if XA.dtype == np.bool:
+                _distance_wrap.cdist_hamming_bool_wrap(_convert_to_bool(XA),
+                                                       _convert_to_bool(XB), dm)
+            else:
+                _distance_wrap.cdist_hamming_wrap(_convert_to_double(XA),
+                                                  _convert_to_double(XB), dm)
+        elif mstr in set(['jaccard', 'jacc', 'ja', 'j']):
+            if XA.dtype == np.bool:
+                _distance_wrap.cdist_jaccard_bool_wrap(_convert_to_bool(XA),
+                                                       _convert_to_bool(XB), dm)
+            else:
+                _distance_wrap.cdist_jaccard_wrap(_convert_to_double(XA),
+                                                  _convert_to_double(XB), dm)
+        elif mstr in set(['chebychev', 'chebyshev', 'cheby', 'cheb', 'ch']):
+            _distance_wrap.cdist_chebyshev_wrap(_convert_to_double(XA),
+                                                _convert_to_double(XB), dm)
+        elif mstr in set(['minkowski', 'mi', 'm']):
+            _distance_wrap.cdist_minkowski_wrap(_convert_to_double(XA),
+                                                _convert_to_double(XB), dm, p)
+        elif mstr in set(['seuclidean', 'se', 's']):
+            if V is not None:
+                V = np.asarray(V)
+                if type(V) != np.ndarray:
+                    raise TypeError('Variance vector V must be a numpy array')
+                if V.dtype != np.double:
+                    raise TypeError('Variance vector V must contain doubles.')
+                if len(V.shape) != 1:
+                    raise ValueError('Variance vector V must be one-dimensional.')
+                if V.shape[0] != n:
+                    raise ValueError('Variance vector V must be of the same dimension as the vectors on which the distances are computed.')
+                # The C code doesn't do striding.
+                [VV] = _copy_arrays_if_base_present([_convert_to_double(V)])
+            else:
+                X = np.vstack([XA, XB])
+                VV = np.var(X, axis=0, ddof=1)
+                X = None
+                del X
+            _distance_wrap.cdist_seuclidean_wrap(_convert_to_double(XA),
+                                                 _convert_to_double(XB), VV, dm)
+        # Need to test whether vectorized cosine works better.
+        # Find out: Is there a dot subtraction operator so I can
+        # subtract matrices in a similar way to multiplying them?
+        # Need to get rid of as much unnecessary C code as possible.
+        elif mstr in set(['cosine', 'cos']):
+            normsA = np.sqrt(np.sum(XA * XA, axis=1))
+            normsB = np.sqrt(np.sum(XB * XB, axis=1))
+            _distance_wrap.cdist_cosine_wrap(_convert_to_double(XA),
+                                             _convert_to_double(XB), dm,
+                                             normsA,
+                                             normsB)
+        elif mstr in set(['correlation', 'co']):
+            XA2 = XA - XA.mean(1)[:,np.newaxis]
+            XB2 = XB - XB.mean(1)[:,np.newaxis]
+            #X2 = X - np.matlib.repmat(np.mean(X, axis=1).reshape(m, 1), 1, n)
+            normsA = np.sqrt(np.sum(XA2 * XA2, axis=1))
+            normsB = np.sqrt(np.sum(XB2 * XB2, axis=1))
+            _distance_wrap.cdist_cosine_wrap(_convert_to_double(XA2),
+                                             _convert_to_double(XB2),
+                                             _convert_to_double(dm),
+                                             _convert_to_double(normsA),
+                                             _convert_to_double(normsB))
+        elif mstr in set(['mahalanobis', 'mahal', 'mah']):
+            if VI is not None:
+                VI = _convert_to_double(np.asarray(VI))
+                if type(VI) != np.ndarray:
+                    raise TypeError('VI must be a numpy array.')
+                if VI.dtype != np.double:
+                    raise TypeError('The array must contain 64-bit floats.')
+                [VI] = _copy_arrays_if_base_present([VI])
+            else:
+                X = np.vstack([XA, XB])
+                V = np.cov(X.T)
+                X = None
+                del X
+                VI = _convert_to_double(np.linalg.inv(V).T.copy())
+            # (u-v)V^(-1)(u-v)^T
+            _distance_wrap.cdist_mahalanobis_wrap(_convert_to_double(XA),
+                                                  _convert_to_double(XB), VI, dm)
+        elif mstr == 'canberra':
+            _distance_wrap.cdist_canberra_wrap(_convert_to_double(XA),
+                                               _convert_to_double(XB), dm)
+        elif mstr == 'braycurtis':
+            _distance_wrap.cdist_bray_curtis_wrap(_convert_to_double(XA),
+                                                  _convert_to_double(XB), dm)
+        elif mstr == 'yule':
+            _distance_wrap.cdist_yule_bool_wrap(_convert_to_bool(XA),
+                                                _convert_to_bool(XB), dm)
+        elif mstr == 'matching':
+            _distance_wrap.cdist_matching_bool_wrap(_convert_to_bool(XA),
+                                                    _convert_to_bool(XB), dm)
+        elif mstr == 'kulsinski':
+            _distance_wrap.cdist_kulsinski_bool_wrap(_convert_to_bool(XA),
+                                                     _convert_to_bool(XB), dm)
+        elif mstr == 'dice':
+            _distance_wrap.cdist_dice_bool_wrap(_convert_to_bool(XA),
+                                                _convert_to_bool(XB), dm)
+        elif mstr == 'rogerstanimoto':
+            _distance_wrap.cdist_rogerstanimoto_bool_wrap(_convert_to_bool(XA),
+                                                          _convert_to_bool(XB), dm)
+        elif mstr == 'russellrao':
+            _distance_wrap.cdist_russellrao_bool_wrap(_convert_to_bool(XA),
+                                                      _convert_to_bool(XB), dm)
+        elif mstr == 'sokalmichener':
+            _distance_wrap.cdist_sokalmichener_bool_wrap(_convert_to_bool(XA),
+                                                         _convert_to_bool(XB), dm)
+        elif mstr == 'sokalsneath':
+            _distance_wrap.cdist_sokalsneath_bool_wrap(_convert_to_bool(XA),
+                                                       _convert_to_bool(XB), dm)
+        elif metric == 'test_euclidean':
+            dm = cdist(XA, XB, euclidean)
+        elif metric == 'test_seuclidean':
+            if V is None:
+                V = np.var(np.vstack([XA, XB]), axis=0, ddof=1)
+            else:
+                V = np.asarray(V)
+            dm = cdist(XA, XB, lambda u, v: seuclidean(u, v, V))
+        elif metric == 'test_sqeuclidean':
+            dm = cdist(XA, XB, lambda u, v: sqeuclidean(u, v))
+        elif metric == 'test_braycurtis':
+            dm = cdist(XA, XB, braycurtis)
+        elif metric == 'test_mahalanobis':
+            if VI is None:
+                X = np.vstack([XA, XB])
+                V = np.cov(X.T)
+                VI = np.linalg.inv(V)
+                X = None
+                del X
+            else:
+                VI = np.asarray(VI)
+            [VI] = _copy_arrays_if_base_present([VI])
+            # (u-v)V^(-1)(u-v)^T
+            dm = cdist(XA, XB, (lambda u, v: mahalanobis(u, v, VI)))
+        elif metric == 'test_canberra':
+            dm = cdist(XA, XB, canberra)
+        elif metric == 'test_cityblock':
+            dm = cdist(XA, XB, cityblock)
+        elif metric == 'test_minkowski':
+            dm = cdist(XA, XB, minkowski, p)
+        elif metric == 'test_cosine':
+            dm = cdist(XA, XB, cosine)
+        elif metric == 'test_correlation':
+            dm = cdist(XA, XB, correlation)
+        elif metric == 'test_hamming':
+            dm = cdist(XA, XB, hamming)
+        elif metric == 'test_jaccard':
+            dm = cdist(XA, XB, jaccard)
+        elif metric == 'test_chebyshev' or metric == 'test_chebychev':
+            dm = cdist(XA, XB, chebyshev)
+        elif metric == 'test_yule':
+            dm = cdist(XA, XB, yule)
+        elif metric == 'test_matching':
+            dm = cdist(XA, XB, matching)
+        elif metric == 'test_dice':
+            dm = cdist(XA, XB, dice)
+        elif metric == 'test_kulsinski':
+            dm = cdist(XA, XB, kulsinski)
+        elif metric == 'test_rogerstanimoto':
+            dm = cdist(XA, XB, rogerstanimoto)
+        elif metric == 'test_russellrao':
+            dm = cdist(XA, XB, russellrao)
+        elif metric == 'test_sokalsneath':
+            dm = cdist(XA, XB, sokalsneath)
+        elif metric == 'test_sokalmichener':
+            dm = cdist(XA, XB, sokalmichener)
+        else:
+            raise ValueError('Unknown Distance Metric: %s' % mstr)
+    else:
+        raise TypeError('2nd argument metric must be a string identifier or a function.')
+    return dm

Modified: trunk/scipy/cluster/src/distance.c
===================================================================
--- trunk/scipy/cluster/src/distance.c	2008-09-07 07:46:29 UTC (rev 4693)
+++ trunk/scipy/cluster/src/distance.c	2008-09-07 19:28:06 UTC (rev 4694)
@@ -700,7 +700,7 @@
}

void cdist_hamming_bool(const char *XA,
-			const char *XB, const char *X, double *dm, int mA, int mB, int n) {
+			const char *XB, double *dm, int mA, int mB, int n) {
int i, j;
const char *u, *v;
double *it = dm;

Modified: trunk/scipy/cluster/src/distance.h
===================================================================
--- trunk/scipy/cluster/src/distance.h	2008-09-07 07:46:29 UTC (rev 4693)
+++ trunk/scipy/cluster/src/distance.h	2008-09-07 19:28:06 UTC (rev 4694)
@@ -74,7 +74,7 @@
void cdist_hamming(const double *XA,
const double *XB, double *dm, int mA, int mB, int n);
void cdist_hamming_bool(const char *XA,
-			const char *XB, const char *X, double *dm,
+			const char *XB, double *dm,
int mA, int mB, int n);
void cdist_jaccard(const double *XA,
const double *XB, double *dm, int mA, int mB, int n);

Modified: trunk/scipy/cluster/src/distance_wrap.c
===================================================================
--- trunk/scipy/cluster/src/distance_wrap.c	2008-09-07 07:46:29 UTC (rev 4693)
+++ trunk/scipy/cluster/src/distance_wrap.c	2008-09-07 19:28:06 UTC (rev 4694)
@@ -40,6 +40,506 @@
#include <numpy/arrayobject.h>
#include <stdio.h>

+extern PyObject *cdist_euclidean_wrap(PyObject *self, PyObject *args) {
+  PyArrayObject *XA_, *XB_, *dm_;
+  int mA, mB, n;
+  double *dm;
+  const double *XA, *XB;
+  if (!PyArg_ParseTuple(args, "O!O!O!",
+			&PyArray_Type, &XA_, &PyArray_Type, &XB_,
+			&PyArray_Type, &dm_)) {
+    return 0;
+  }
+  else {
+    XA = (const double*)XA_->data;
+    XB = (const double*)XB_->data;
+    dm = (double*)dm_->data;
+    mA = XA_->dimensions[0];
+    mB = XB_->dimensions[0];
+    n = XA_->dimensions[1];
+
+    cdist_euclidean(XA, XB, dm, mA, mB, n);
+  }
+  return Py_BuildValue("d", 0.0);
+}
+
+extern PyObject *cdist_canberra_wrap(PyObject *self, PyObject *args) {
+  PyArrayObject *XA_, *XB_, *dm_;
+  int mA, mB, n;
+  double *dm;
+  const double *XA, *XB;
+  if (!PyArg_ParseTuple(args, "O!O!O!",
+			&PyArray_Type, &XA_, &PyArray_Type, &XB_,
+			&PyArray_Type, &dm_)) {
+    return 0;
+  }
+  else {
+    XA = (const double*)XA_->data;
+    XB = (const double*)XB_->data;
+    dm = (double*)dm_->data;
+    mA = XA_->dimensions[0];
+    mB = XB_->dimensions[0];
+    n = XA_->dimensions[1];
+
+    cdist_canberra(XA, XB, dm, mA, mB, n);
+  }
+  return Py_BuildValue("d", 0.0);
+}
+
+extern PyObject *cdist_bray_curtis_wrap(PyObject *self, PyObject *args) {
+  PyArrayObject *XA_, *XB_, *dm_;
+  int mA, mB, n;
+  double *dm;
+  const double *XA, *XB;
+  if (!PyArg_ParseTuple(args, "O!O!O!",
+			&PyArray_Type, &XA_, &PyArray_Type, &XB_,
+			&PyArray_Type, &dm_)) {
+    return 0;
+  }
+  else {
+    XA = (const double*)XA_->data;
+    XB = (const double*)XB_->data;
+    dm = (double*)dm_->data;
+    mA = XA_->dimensions[0];
+    mB = XB_->dimensions[0];
+    n = XA_->dimensions[1];
+
+    cdist_bray_curtis(XA, XB, dm, mA, mB, n);
+  }
+  return Py_BuildValue("d", 0.0);
+}
+
+
+extern PyObject *cdist_mahalanobis_wrap(PyObject *self, PyObject *args) {
+  PyArrayObject *XA_, *XB_, *covinv_, *dm_;
+  int mA, mB, n;
+  double *dm;
+  const double *XA, *XB;
+  const double *covinv;
+  if (!PyArg_ParseTuple(args, "O!O!O!O!",
+			&PyArray_Type, &XA_, &PyArray_Type, &XB_,
+			&PyArray_Type, &covinv_,
+			&PyArray_Type, &dm_)) {
+    return 0;
+  }
+  else {
+    XA = (const double*)XA_->data;
+    XB = (const double*)XB_->data;
+    covinv = (const double*)covinv_->data;
+    dm = (double*)dm_->data;
+    mA = XA_->dimensions[0];
+    mB = XB_->dimensions[0];
+    n = XA_->dimensions[1];
+
+    cdist_mahalanobis(XA, XB, covinv, dm, mA, mB, n);
+  }
+  return Py_BuildValue("d", 0.0);
+}
+
+
+extern PyObject *cdist_chebyshev_wrap(PyObject *self, PyObject *args) {
+  PyArrayObject *XA_, *XB_, *dm_;
+  int mA, mB, n;
+  double *dm;
+  const double *XA, *XB;
+  if (!PyArg_ParseTuple(args, "O!O!O!",
+			&PyArray_Type, &XA_, &PyArray_Type, &XB_,
+			&PyArray_Type, &dm_)) {
+    return 0;
+  }
+  else {
+    XA = (const double*)XA_->data;
+    XB = (const double*)XB_->data;
+    dm = (double*)dm_->data;
+    mA = XA_->dimensions[0];
+    mB = XB_->dimensions[0];
+    n = XA_->dimensions[1];
+
+    cdist_chebyshev(XA, XB, dm, mA, mB, n);
+  }
+  return Py_BuildValue("d", 0.0);
+}
+
+
+extern PyObject *cdist_cosine_wrap(PyObject *self, PyObject *args) {
+  PyArrayObject *XA_, *XB_, *dm_, *normsA_, *normsB_;
+  int mA, mB, n;
+  double *dm;
+  const double *XA, *XB, *normsA, *normsB;
+  if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
+			&PyArray_Type, &XA_, &PyArray_Type, &XB_,
+			&PyArray_Type, &dm_,
+			&PyArray_Type, &normsA_,
+			&PyArray_Type, &normsB_)) {
+    return 0;
+  }
+  else {
+    XA = (const double*)XA_->data;
+    XB = (const double*)XB_->data;
+    dm = (double*)dm_->data;
+    normsA = (const double*)normsA_->data;
+    normsB = (const double*)normsB_->data;
+    mA = XA_->dimensions[0];
+    mB = XB_->dimensions[0];
+    n = XA_->dimensions[1];
+
+    cdist_cosine(XA, XB, dm, mA, mB, n, normsA, normsB);
+  }
+  return Py_BuildValue("d", 0.0);
+}
+
+extern PyObject *cdist_seuclidean_wrap(PyObject *self, PyObject *args) {
+  PyArrayObject *XA_, *XB_, *dm_, *var_;
+  int mA, mB, n;
+  double *dm;
+  const double *XA, *XB, *var;
+  if (!PyArg_ParseTuple(args, "O!O!O!O!",
+			&PyArray_Type, &XA_, &PyArray_Type, &XB_,
+			&PyArray_Type, &var_,
+			&PyArray_Type, &dm_)) {
+    return 0;
+  }
+  else {
+    XA = (const double*)XA_->data;
+    XB = (const double*)XB_->data;
+    dm = (double*)dm_->data;
+    var = (double*)var_->data;
+    mA = XA_->dimensions[0];
+    mB = XB_->dimensions[0];
+    n = XA_->dimensions[1];
+
+    cdist_seuclidean(XA, XB, var, dm, mA, mB, n);
+  }
+  return Py_BuildValue("d", 0.0);
+}
+
+extern PyObject *cdist_city_block_wrap(PyObject *self, PyObject *args) {
+  PyArrayObject *XA_, *XB_, *dm_;
+  int mA, mB, n;
+  double *dm;
+  const double *XA, *XB;
+  if (!PyArg_ParseTuple(args, "O!O!O!",
+			&PyArray_Type, &XA_, &PyArray_Type, &XB_,
+			&PyArray_Type, &dm_)) {
+    return 0;
+  }
+  else {
+    XA = (const double*)XA_->data;
+    XB = (const double*)XB_->data;
+    dm = (double*)dm_->data;
+    mA = XA_->dimensions[0];
+    mB = XB_->dimensions[0];
+    n = XA_->dimensions[1];
+
+    cdist_city_block(XA, XB, dm, mA, mB, n);
+  }
+  return Py_BuildValue("d", 0.0);
+}
+
+extern PyObject *cdist_hamming_wrap(PyObject *self, PyObject *args) {
+  PyArrayObject *XA_, *XB_, *dm_;
+  int mA, mB, n;
+  double *dm;
+  const double *XA, *XB;
+  if (!PyArg_ParseTuple(args, "O!O!O!",
+			&PyArray_Type, &XA_, &PyArray_Type, &XB_,
+			&PyArray_Type, &dm_)) {
+    return 0;
+  }
+  else {
+    XA = (const double*)XA_->data;
+    XB = (const double*)XB_->data;
+    dm = (double*)dm_->data;
+    mA = XA_->dimensions[0];
+    mB = XB_->dimensions[0];
+    n = XA_->dimensions[1];
+
+    cdist_hamming(XA, XB, dm, mA, mB, n);
+  }
+  return Py_BuildValue("d", 0.0);
+}
+
+extern PyObject *cdist_hamming_bool_wrap(PyObject *self, PyObject *args) {
+  PyArrayObject *XA_, *XB_, *dm_;
+  int mA, mB, n;
+  double *dm;
+  const char *XA, *XB;
+  if (!PyArg_ParseTuple(args, "O!O!O!",
+			&PyArray_Type, &XA_, &PyArray_Type, &XB_,
+			&PyArray_Type, &dm_)) {
+    return 0;
+  }
+  else {
+    XA = (const char*)XA_->data;
+    XB = (const char*)XB_->data;
+    dm = (double*)dm_->data;
+    mA = XA_->dimensions[0];
+    mB = XB_->dimensions[0];
+    n = XA_->dimensions[1];
+
+    cdist_hamming_bool(XA, XB, dm, mA, mB, n);
+  }
+  return Py_BuildValue("d", 0.0);
+}
+
+extern PyObject *cdist_jaccard_wrap(PyObject *self, PyObject *args) {
+  PyArrayObject *XA_, *XB_, *dm_;
+  int mA, mB, n;
+  double *dm;
+  const double *XA, *XB;
+  if (!PyArg_ParseTuple(args, "O!O!O!",
+			&PyArray_Type, &XA_, &PyArray_Type, &XB_,
+			&PyArray_Type, &dm_)) {
+    return 0;
+  }
+  else {
+    XA = (const double*)XA_->data;
+    XB = (const double*)XB_->data;
+    dm = (double*)dm_->data;
+    mA = XA_->dimensions[0];
+    mB = XB_->dimensions[0];
+    n = XA_->dimensions[1];
+
+    cdist_jaccard(XA, XB, dm, mA, mB, n);
+  }
+  return Py_BuildValue("d", 0.0);
+}
+
+extern PyObject *cdist_jaccard_bool_wrap(PyObject *self, PyObject *args) {
+  PyArrayObject *XA_, *XB_, *dm_;
+  int mA, mB, n;
+  double *dm;
+  const char *XA, *XB;
+  if (!PyArg_ParseTuple(args, "O!O!O!",
+			&PyArray_Type, &XA_, &PyArray_Type, &XB_,
+			&PyArray_Type, &dm_)) {
+    return 0;
+  }
+  else {
+    XA = (const char*)XA_->data;
+    XB = (const char*)XB_->data;
+    dm = (double*)dm_->data;
+    mA = XA_->dimensions[0];
+    mB = XB_->dimensions[0];
+    n = XA_->dimensions[1];
+
+    cdist_jaccard_bool(XA, XB, dm, mA, mB, n);
+  }
+  return Py_BuildValue("d", 0.0);
+}
+
+extern PyObject *cdist_minkowski_wrap(PyObject *self, PyObject *args) {
+  PyArrayObject *XA_, *XB_, *dm_;
+  int mA, mB, n;
+  double *dm;
+  const double *XA, *XB;
+  double p;
+  if (!PyArg_ParseTuple(args, "O!O!O!d",
+			&PyArray_Type, &XA_, &PyArray_Type, &XB_,
+			&PyArray_Type, &dm_,
+			&p)) {
+    return 0;
+  }
+  else {
+    XA = (const double*)XA_->data;
+    XB = (const double*)XB_->data;
+    dm = (double*)dm_->data;
+    mA = XA_->dimensions[0];
+    mB = XB_->dimensions[0];
+    n = XA_->dimensions[1];
+
+    cdist_minkowski(XA, XB, dm, mA, mB, n, p);
+  }
+  return Py_BuildValue("d", 0.0);
+}
+
+
+extern PyObject *cdist_yule_bool_wrap(PyObject *self, PyObject *args) {
+  PyArrayObject *XA_, *XB_, *dm_;
+  int mA, mB, n;
+  double *dm;
+  const char *XA, *XB;
+  if (!PyArg_ParseTuple(args, "O!O!O!",
+			&PyArray_Type, &XA_, &PyArray_Type, &XB_,
+			&PyArray_Type, &dm_)) {
+    return 0;
+  }
+  else {
+    XA = (const char*)XA_->data;
+    XB = (const char*)XB_->data;
+    dm = (double*)dm_->data;
+    mA = XA_->dimensions[0];
+    mB = XB_->dimensions[0];
+    n = XA_->dimensions[1];
+
+    cdist_yule_bool(XA, XB, dm, mA, mB, n);
+  }
+  return Py_BuildValue("");
+}
+
+extern PyObject *cdist_matching_bool_wrap(PyObject *self, PyObject *args) {
+  PyArrayObject *XA_, *XB_, *dm_;
+  int mA, mB, n;
+  double *dm;
+  const char *XA, *XB;
+  if (!PyArg_ParseTuple(args, "O!O!O!",
+			&PyArray_Type, &XA_, &PyArray_Type, &XB_,
+			&PyArray_Type, &dm_)) {
+    return 0;
+  }
+  else {
+    XA = (const char*)XA_->data;
+    XB = (const char*)XB_->data;
+    dm = (double*)dm_->data;
+    mA = XA_->dimensions[0];
+    mB = XB_->dimensions[0];
+    n = XA_->dimensions[1];
+
+    cdist_matching_bool(XA, XB, dm, mA, mB, n);
+  }
+  return Py_BuildValue("");
+}
+
+extern PyObject *cdist_dice_bool_wrap(PyObject *self, PyObject *args) {
+  PyArrayObject *XA_, *XB_, *dm_;
+  int mA, mB, n;
+  double *dm;
+  const char *XA, *XB;
+  if (!PyArg_ParseTuple(args, "O!O!O!",
+			&PyArray_Type, &XA_, &PyArray_Type, &XB_,
+			&PyArray_Type, &dm_)) {
+    return 0;
+  }
+  else {
+    XA = (const char*)XA_->data;
+    XB = (const char*)XB_->data;
+    dm = (double*)dm_->data;
+    mA = XA_->dimensions[0];
+    mB = XB_->dimensions[0];
+    n = XA_->dimensions[1];
+
+    cdist_dice_bool(XA, XB, dm, mA, mB, n);
+  }
+  return Py_BuildValue("");
+}
+
+extern PyObject *cdist_rogerstanimoto_bool_wrap(PyObject *self, PyObject *args) {
+  PyArrayObject *XA_, *XB_, *dm_;
+  int mA, mB, n;
+  double *dm;
+  const char *XA, *XB;
+  if (!PyArg_ParseTuple(args, "O!O!O!",
+			&PyArray_Type, &XA_, &PyArray_Type, &XB_,
+			&PyArray_Type, &dm_)) {
+    return 0;
+  }
+  else {
+    XA = (const char*)XA_->data;
+    XB = (const char*)XB_->data;
+    dm = (double*)dm_->data;
+    mA = XA_->dimensions[0];
+    mB = XB_->dimensions[0];
+    n = XA_->dimensions[1];
+
+    cdist_rogerstanimoto_bool(XA, XB, dm, mA, mB, n);
+  }
+  return Py_BuildValue("");
+}
+
+extern PyObject *cdist_russellrao_bool_wrap(PyObject *self, PyObject *args) {
+  PyArrayObject *XA_, *XB_, *dm_;
+  int mA, mB, n;
+  double *dm;
+  const char *XA, *XB;
+  if (!PyArg_ParseTuple(args, "O!O!O!",
+			&PyArray_Type, &XA_, &PyArray_Type, &XB_,
+			&PyArray_Type, &dm_)) {
+    return 0;
+  }
+  else {
+    XA = (const char*)XA_->data;
+    XB = (const char*)XB_->data;
+    dm = (double*)dm_->data;
+    mA = XA_->dimensions[0];
+    mB = XB_->dimensions[0];
+    n = XA_->dimensions[1];
+
+    cdist_russellrao_bool(XA, XB, dm, mA, mB, n);
+  }
+  return Py_BuildValue("");
+}
+
+extern PyObject *cdist_kulsinski_bool_wrap(PyObject *self, PyObject *args) {
+  PyArrayObject *XA_, *XB_, *dm_;
+  int mA, mB, n;
+  double *dm;
+  const char *XA, *XB;
+  if (!PyArg_ParseTuple(args, "O!O!O!",
+			&PyArray_Type, &XA_, &PyArray_Type, &XB_,
+			&PyArray_Type, &dm_)) {
+    return 0;
+  }
+  else {
+    XA = (const char*)XA_->data;
+    XB = (const char*)XB_->data;
+    dm = (double*)dm_->data;
+    mA = XA_->dimensions[0];
+    mB = XB_->dimensions[0];
+    n = XA_->dimensions[1];
+
+    cdist_kulsinski_bool(XA, XB, dm, mA, mB, n);
+  }
+  return Py_BuildValue("");
+}
+
+extern PyObject *cdist_sokalmichener_bool_wrap(PyObject *self, PyObject *args) {
+  PyArrayObject *XA_, *XB_, *dm_;
+  int mA, mB, n;
+  double *dm;
+  const char *XA, *XB;
+  if (!PyArg_ParseTuple(args, "O!O!O!",
+			&PyArray_Type, &XA_, &PyArray_Type, &XB_,
+			&PyArray_Type, &dm_)) {
+    return 0;
+  }
+  else {
+    XA = (const char*)XA_->data;
+    XB = (const char*)XB_->data;
+    dm = (double*)dm_->data;
+    mA = XA_->dimensions[0];
+    mB = XB_->dimensions[0];
+    n = XA_->dimensions[1];
+
+    cdist_sokalmichener_bool(XA, XB, dm, mA, mB, n);
+  }
+  return Py_BuildValue("");
+}
+
+extern PyObject *cdist_sokalsneath_bool_wrap(PyObject *self, PyObject *args) {
+  PyArrayObject *XA_, *XB_, *dm_;
+  int mA, mB, n;
+  double *dm;
+  const char *XA, *XB;
+  if (!PyArg_ParseTuple(args, "O!O!O!",
+			&PyArray_Type, &XA_, &PyArray_Type, &XB_,
+			&PyArray_Type, &dm_)) {
+    return 0;
+  }
+  else {
+    XA = (const char*)XA_->data;
+    XB = (const char*)XB_->data;
+    dm = (double*)dm_->data;
+    mA = XA_->dimensions[0];
+    mB = XB_->dimensions[0];
+    n = XA_->dimensions[1];
+
+    cdist_sokalsneath_bool(XA, XB, dm, mA, mB, n);
+  }
+  return Py_BuildValue("");
+}
+
+/***************************** pdist ***/
+
extern PyObject *pdist_euclidean_wrap(PyObject *self, PyObject *args) {
PyArrayObject *X_, *dm_;
int m, n;
@@ -533,6 +1033,27 @@

static PyMethodDef _distanceWrapMethods[] = {
+  {"cdist_bray_curtis_wrap", cdist_bray_curtis_wrap, METH_VARARGS},
+  {"cdist_canberra_wrap", cdist_canberra_wrap, METH_VARARGS},
+  {"cdist_chebyshev_wrap", cdist_chebyshev_wrap, METH_VARARGS},
+  {"cdist_city_block_wrap", cdist_city_block_wrap, METH_VARARGS},
+  {"cdist_cosine_wrap", cdist_cosine_wrap, METH_VARARGS},
+  {"cdist_dice_bool_wrap", cdist_dice_bool_wrap, METH_VARARGS},
+  {"cdist_euclidean_wrap", cdist_euclidean_wrap, METH_VARARGS},
+  {"cdist_hamming_wrap", cdist_hamming_wrap, METH_VARARGS},
+  {"cdist_hamming_bool_wrap", cdist_hamming_bool_wrap, METH_VARARGS},
+  {"cdist_jaccard_wrap", cdist_jaccard_wrap, METH_VARARGS},
+  {"cdist_jaccard_bool_wrap", cdist_jaccard_bool_wrap, METH_VARARGS},
+  {"cdist_kulsinski_bool_wrap", cdist_kulsinski_bool_wrap, METH_VARARGS},
+  {"cdist_mahalanobis_wrap", cdist_mahalanobis_wrap, METH_VARARGS},
+  {"cdist_matching_bool_wrap", cdist_matching_bool_wrap, METH_VARARGS},
+  {"cdist_minkowski_wrap", cdist_minkowski_wrap, METH_VARARGS},
+  {"cdist_rogerstanimoto_bool_wrap", cdist_rogerstanimoto_bool_wrap, METH_VARARGS},
+  {"cdist_russellrao_bool_wrap", cdist_russellrao_bool_wrap, METH_VARARGS},
+  {"cdist_seuclidean_wrap", cdist_seuclidean_wrap, METH_VARARGS},
+  {"cdist_sokalmichener_bool_wrap", cdist_sokalmichener_bool_wrap, METH_VARARGS},
+  {"cdist_sokalsneath_bool_wrap", cdist_sokalsneath_bool_wrap, METH_VARARGS},
+  {"cdist_yule_bool_wrap", cdist_yule_bool_wrap, METH_VARARGS},
{"pdist_bray_curtis_wrap", pdist_bray_curtis_wrap, METH_VARARGS},
{"pdist_canberra_wrap", pdist_canberra_wrap, METH_VARARGS},
{"pdist_chebyshev_wrap", pdist_chebyshev_wrap, METH_VARARGS},

===================================================================
--- trunk/scipy/cluster/tests/cdist-X1.txt	2008-09-07 07:46:29 UTC (rev 4693)
+++ trunk/scipy/cluster/tests/cdist-X1.txt	2008-09-07 19:28:06 UTC (rev 4694)
@@ -0,0 +1,10 @@
+1.147593763490969421e-01 8.926156143344999849e-01 1.437758624645746330e-02 1.803435962879929022e-02 5.533046214065578949e-01 5.554315640747428118e-01 4.497546637814608950e-02 4.438089247948049376e-01 7.984582810220538507e-01 2.752880789161644692e-01 1.344667112315823809e-01 9.230479561452992199e-01 6.040471462941819913e-01 3.797251652770228247e-01 4.316042735592399149e-01 5.312356915348823705e-01 4.348143005129563310e-01 3.111531488508799681e-01 9.531194313908697424e-04 8.212995023500069269e-02 6.689953269869852726e-01 9.914864535288493430e-01 8.037556036341153565e-01
+9.608925123801395074e-01 2.974451233678974127e-01 9.001110330654185088e-01 5.824163330415995654e-01 7.308574928293812834e-01 2.276154562412870952e-01 7.306791076039623745e-01 8.677244866905511333e-01 9.160806456176984192e-01 6.157216959991280714e-01 5.149053524695440531e-01 3.056427344890983999e-01 9.790557366933895223e-01 4.484995861076724877e-01 4.776550391081165747e-01 7.210436977670631187e-01 9.136399501661039979e-01 4.260275733550000776e-02 5.943900041968954717e-01 3.864571606342745991e-01 9.442027665110838131e-01 4.779949058608601309e-02 6.107551944250865228e-01
+3.297286578103622023e-01 5.980207401936733502e-01 3.673301293561567205e-01 2.585830520887681949e-01 4.660558746104259686e-01 6.083795956610364986e-01 4.535206368070313632e-01 6.873989778785424276e-01 5.130152688495458468e-01 7.665877846542720198e-01 3.444402973525138023e-01 3.583658123644906102e-02 7.924818220986856732e-01 8.746685720522412444e-01 3.010105569182431884e-01 6.012239357385538163e-01 6.233737362204671006e-01 4.830438698668915176e-01 2.317286885842551047e-02 7.585989958123050547e-01 7.108257632278830451e-01 1.551024884178199281e-01 2.665485998155288083e-01
+2.456278068903017253e-02 4.148739837711815648e-01 1.986372227934196655e-01 6.920408530298168825e-01 1.003067576685774398e-01 7.421560456480125190e-01 1.808453980608998313e-01 4.251297882537475870e-01 6.773002683522370004e-01 4.084108792570182445e-01 7.462888013191590897e-01 8.069930220529277776e-01 9.211110587681808903e-01 4.141491046181076108e-01 7.486318689260342829e-01 9.515405507589296263e-01 4.634288892577109742e-03 8.027593488166355762e-01 3.010346805217798405e-01 8.663248877242523127e-01 2.479968181181605447e-01 5.619851096054278017e-01 3.903886764590250857e-01
+7.122019976035700584e-01 6.188878051047785878e-01 7.290897087051201320e-01 6.334802157757637442e-01 5.523084734954342156e-01 5.614937129563645213e-01 2.496741051791574462e-01 5.972227939599233926e-01 1.786590597761109622e-01 2.609525984850900038e-01 7.210438943286010538e-01 2.211429064605652250e-01 9.140497572472672250e-02 1.430242193668443962e-01 7.856446942916397447e-01 4.635256358156553125e-01 5.278744289813760426e-01 3.702808015407184072e-01 5.527073830480792038e-01 6.370732917599846168e-01 9.953487928925482953e-01 3.021789770611936765e-01 3.354901923998221402e-02
+6.509638560895427695e-01 8.387598220902757751e-01 7.761375971745763103e-01 1.481627639227802717e-01 3.529474982902305324e-01 4.883093646287851586e-01 9.652923033658690199e-01 9.500680513565308294e-01 3.061885005078281985e-01 7.271902818906019750e-01 2.358962978196710303e-03 7.359889703223099211e-01 8.988893768074724955e-01 4.135279653937307121e-02 8.516441856688283796e-01 4.889597623270667270e-01 5.575909822114655245e-01 9.010853652261575641e-01 2.912844516556202246e-01 9.088759383368658629e-01 8.104351227460024898e-01 8.080695436776826890e-01 1.430530913253185155e-01
+8.048001196608134400e-01 3.066089444418462762e-02 9.021887554292090661e-01 6.154331491807940591e-02 1.378912575206647784e-02 5.775720193142440673e-01 1.219298963069791464e-01 1.883270243412101808e-01 5.569262398688379356e-02 8.964817777510125651e-02 7.977092785346929782e-01 4.878149375226197293e-01 4.511973131518809410e-02 1.858690046801604323e-01 6.947686471083162063e-01 5.884058794291086025e-01 8.638884676612634816e-01 3.855470871341656336e-01 3.495049047300468059e-01 2.767740932353948136e-01 4.731087031714035218e-01 6.679001673437914288e-01 7.502944200696660682e-01
+6.527328264244687261e-01 8.289483383553154505e-01 9.179741348282299818e-01 1.065639864466713105e-01 6.253616929058514184e-01 5.927750325266062381e-01 3.039157425463192563e-01 2.452766763359194302e-01 6.514027700704632107e-01 5.529218485487964463e-01 4.941158239308394151e-01 6.605306467722642516e-01 2.273688037050677346e-01 4.282616592244774534e-01 2.956128257930247250e-01 1.154803628237965896e-01 9.228220410235263849e-01 6.663525307676617659e-01 1.908852615936970087e-01 9.921383408926374159e-01 4.988716450388516188e-01 1.014900352736023414e-01 3.363930180244284474e-01
+2.914369076275757919e-01 5.196673601143533272e-01 7.420144907858341465e-01 1.768984185504740569e-01 5.296766993228564369e-01 5.922023566159900776e-01 5.965161262020234334e-01 3.810272333046110793e-01 8.368797246118340194e-01 7.896422363801189892e-01 9.655797561098209414e-01 4.430034032346981121e-01 2.780869795706976122e-01 3.047310845416009162e-01 8.051138863500326703e-01 6.731468634690835895e-01 4.743383036815584930e-01 9.530709614322225853e-01 7.753587619850917934e-01 2.801137109357491051e-01 6.182543660889736614e-01 5.005218857766725593e-01 9.071447804755052857e-01
+2.075071644012620453e-01 4.834950086973934802e-01 3.037011473860764532e-01 6.476084284887700937e-01 8.107195771564194020e-01 7.869075869075803364e-01 6.851234019375299633e-01 3.544187468104398331e-02 4.847673235908021017e-01 5.690262846164507726e-01 1.663354142616256803e-01 9.692796809752548537e-01 4.133441725866372485e-01 6.729167604487583665e-01 3.998813427407297283e-01 8.272617414104491695e-01 2.129248316324727774e-01 6.517004761357130249e-01 7.363013506605019520e-01 4.072375306356985636e-01 4.463336683526665238e-01 5.485059309728204102e-01 1.981745754527846071e-01

===================================================================
--- trunk/scipy/cluster/tests/cdist-X2.txt	2008-09-07 07:46:29 UTC (rev 4693)
+++ trunk/scipy/cluster/tests/cdist-X2.txt	2008-09-07 19:28:06 UTC (rev 4694)
@@ -0,0 +1,20 @@
+7.680465556300619667e-02 4.675022344069014180e-01 8.955498989131543963e-01 3.816236071436276411e-01 1.109030077070989329e-01 2.318928815459808668e-02 7.477394240984251983e-01 1.202289789304434864e-01 8.007290497575981769e-01 6.795195698871731027e-01 6.568225762396605605e-01 2.231475263228478445e-01 7.064624077661341151e-02 1.081656666815267176e-02 1.592069359090128033e-01 1.363392203645097389e-01 9.277020735447568667e-01 8.103136564528209407e-01 5.229467676276455812e-02 7.708020259874025504e-01 6.527954747473352359e-02 5.516397414886525796e-01 3.653371861367954443e-01
+8.144399106025798085e-01 7.731852525462976633e-01 6.909477620673205589e-01 9.696063817000286633e-01 4.297887511677249694e-01 6.989600553425188156e-01 7.310201335033380543e-01 3.135256147868910048e-01 5.715578037275241829e-01 3.935000744675094531e-01 2.057715781268398825e-01 5.892508589665171881e-01 8.512951599236765476e-01 9.569808799061578775e-01 6.164885878024699561e-01 4.714185430004367294e-01 6.128831737628155363e-01 6.641799309623502845e-01 6.001985185338730711e-01 4.231922889723856995e-01 7.605249308075449077e-01 1.064530958018087281e-01 6.306470691957204444e-01
+4.265470127256254518e-01 5.933766716280767239e-01 3.698589270536845053e-02 2.173799740537294412e-01 3.032679325475639009e-01 4.271831790058847611e-01 1.828944535901013690e-01 4.772333422710156592e-01 2.564773455194128138e-01 7.120329875362141347e-01 8.952243430110462530e-01 1.808777012183288013e-01 3.612151871458374464e-01 3.960999167923041631e-01 1.821669970670747318e-02 8.835474857189200559e-01 1.353104648821573663e-01 3.457291739160937016e-01 1.126467375304566199e-01 4.107293162402323450e-01 4.051719311053743056e-01 4.007382985250427243e-01 1.286905671428811848e-01
+2.910657003883979632e-01 9.616259180685315933e-03 2.033032441536681834e-01 1.096599110293863255e-01 4.191101704605176836e-01 5.462131536027151624e-01 8.393047907010142694e-01 9.046805198676335369e-01 7.009863472176891541e-01 2.508215985039629059e-01 6.754410796667598138e-01 6.740895474032024826e-01 1.358993708621679675e-01 8.219861775211464439e-01 6.322220445623235596e-01 2.766813559002430090e-01 6.575983861590951607e-01 9.515869708336625044e-01 8.654526462353933081e-01 3.450245117834797037e-01 5.649032890631299209e-01 4.717687914789682191e-01 3.296483580510030098e-01
+9.172477457635394016e-01 3.057396583041891436e-01 7.335332344225760082e-01 8.370236206345178509e-01 3.765464253115927695e-01 5.089680319287778199e-01 1.202325719268168003e-01 9.717771065272349240e-01 5.907820104019682050e-01 9.809211614977710880e-01 9.064285003671219698e-01 8.848841466121748489e-01 2.043407730734815297e-01 9.157600394927275511e-01 4.532260315147775831e-01 4.241077335005828397e-01 1.751730149568804240e-01 4.090412146081819911e-01 3.632197861847064058e-02 5.832539334970230360e-01 4.041848151536805434e-01 3.603643989086504629e-01 1.838411383882069261e-01
+2.508806403290032572e-01 4.381403985282813496e-01 4.694787405018008286e-02 6.353900562024634713e-01 1.200813444244532846e-01 6.072397042913001419e-01 9.937255904754030977e-01 4.916670237677555066e-01 3.473845913923001572e-01 3.526875922864345370e-01 5.448595548197197047e-01 2.245096010156972799e-01 9.003258279804994269e-01 3.534560469735994470e-01 2.989266066346342177e-01 4.621024982808636938e-01 9.626538866576676012e-01 9.791401720716153001e-01 7.138514287330390840e-01 9.832862333928654719e-01 3.233999591031431198e-01 5.406467224926423398e-01 9.581890295057201579e-01
+5.210583601680578436e-01 4.598159993059653949e-01 2.111497132057748027e-01 5.949977700916546652e-01 6.342618461422359077e-01 9.888228769705599275e-01 6.096770711536318998e-01 7.548431368960863974e-01 7.490858664860100546e-01 3.186213496546415058e-01 7.895687083231245351e-01 4.178326793268141159e-01 8.095818334534051752e-01 7.886271673523481684e-01 4.038905626506847923e-01 3.652649247094948981e-01 8.267205959224892542e-01 6.433617243328785262e-01 3.117681563249452559e-01 9.675995575054980868e-01 3.675673836358472890e-01 5.863757289184046151e-01 9.099029857959717305e-02
+4.024573981231733821e-01 3.578997554002771864e-01 3.519299868071553705e-01 7.417747693762357653e-01 2.963713903285800644e-01 9.602967989298948348e-01 3.811392331739601458e-01 5.493237898295448840e-01 6.835113342793640578e-01 2.304506220807415184e-01 3.727299857731285471e-01 5.450263991912108752e-01 6.951521210987908761e-01 6.474582745861203747e-01 6.316089475403589004e-01 5.672043967425510758e-02 9.034937506977609445e-01 2.332567550780038079e-01 1.096955741449157085e-02 8.870663813493575578e-01 4.384385452180562526e-01 7.100898998169548060e-01 3.245358176196319056e-01
+9.162009194452818139e-01 5.572224742426723498e-02 3.445910686865658601e-01 9.683564008127462097e-01 9.375063149031520604e-01 9.128188852869822956e-02 9.613605414326487075e-01 5.298598697556915482e-01 6.724799695520149445e-01 1.269103938571825019e-02 1.008406153387807480e-01 8.951105272379104028e-01 1.585460318853607609e-01 6.739986455059543413e-01 5.345419321702655768e-01 6.248843899572337213e-01 3.050288488994817859e-01 1.423645553465189284e-01 1.802121190541096096e-01 9.474646822694763326e-01 2.345716438587298613e-01 9.688281784764296578e-01 1.845165243240991515e-01
+2.548297646910531178e-01 2.580877375379494465e-01 1.355482532666937301e-01 6.478812986505504412e-01 9.971695982152032345e-01 2.606721082477282403e-01 5.483439686378906996e-01 4.409612606704470528e-01 4.396442074915688503e-01 7.414262832597111608e-01 7.308840725375539416e-01 8.072095530497225280e-02 6.829509968656330976e-01 5.700030854230387911e-01 3.801845336730320657e-01 2.481059916867158766e-01 3.977295094395927322e-03 5.749480512407895150e-01 4.112033136603401307e-01 8.676159710377848722e-01 9.062646588480167686e-01 3.326691167317923359e-01 8.498307982774666591e-01
+4.464338109330643345e-01 8.546516760817471914e-01 7.384800352329814466e-01 3.692485164984804502e-02 2.915662689505471583e-02 9.010049994217171898e-01 8.622900253010918892e-01 9.786230638032608065e-01 6.546824077297251909e-01 6.342297560006789903e-01 2.230339826582647955e-01 7.658846744185553446e-01 4.603043831539479491e-01 2.017100469861691225e-01 4.891590639893540482e-01 1.937140918314912419e-01 8.161582138652878626e-01 5.597293607114051106e-02 8.423261093326828153e-02 5.105392204475533990e-02 8.234193902673621057e-01 1.784268309975372002e-01 9.118997881986501408e-02
+8.588746913421980711e-01 1.479641118621310980e-02 1.375875301146138874e-01 7.533888774725254756e-01 5.782592791549248101e-01 9.128573037619659436e-01 1.831275762880391067e-01 3.471382864827737835e-01 4.859524740929310749e-02 8.955146541561730400e-01 4.787220791101074457e-01 4.222803577759057791e-01 8.469923964908064873e-01 6.300290047587608910e-02 1.020873237837905956e-01 3.585612487182909813e-02 6.320107119904569970e-01 5.891245970008752719e-01 1.104698053665007507e-01 4.233226558073774903e-01 4.432217054386708988e-01 2.864765416628194394e-01 2.489777211814803159e-02
+5.343810659756068615e-01 4.829076396403546578e-01 8.364480888953172988e-01 8.931374995414760321e-01 6.034161442354715188e-01 3.578336000768178593e-03 4.100579775972763574e-01 3.968667908067096128e-01 5.897163653686778861e-01 3.003241263928478899e-01 2.520935203143799264e-01 3.112129371563532310e-02 9.052865295974613646e-01 1.172285124002711010e-01 4.840001666149388315e-01 3.424620676348436588e-01 5.526057133826853818e-01 6.346139530261846184e-01 5.747945930485597321e-01 1.389915612177697879e-01 2.413801217666421417e-01 7.829900796662081497e-01 7.213528084845653998e-01
+9.384509283406079483e-01 6.303019601671526750e-01 1.787921522728125323e-01 1.556003868047917127e-02 5.662397078816850948e-01 3.437473614806091371e-01 8.615844972800188462e-01 7.624380237306396246e-01 1.096468347898514883e-01 1.276566836610887323e-01 8.479188493443535757e-01 3.634713454428405432e-01 7.478112314318967613e-01 9.856395696968375253e-01 6.250293654177319080e-02 1.919327272501809567e-01 1.415594476031050153e-01 7.224057351041784925e-01 8.452145259310355208e-01 5.434318833772002755e-01 5.177620959731277228e-02 3.358977598185840518e-01 2.542654881527960375e-01
+4.800909104006243489e-01 3.651345393613150137e-01 3.657093052788148446e-01 8.579662326651369408e-01 5.787694361240260932e-01 6.491966196891312268e-01 3.252508517294879775e-01 8.639694334693422961e-01 3.028097078756678551e-01 6.295814666338699350e-01 7.305627351548695803e-01 6.975931849120264872e-03 8.321205159004851915e-01 2.681809305821257761e-01 3.628869474597150591e-01 9.598981434716586936e-01 5.947913523332928332e-01 7.794864238003402779e-01 2.819511239444029149e-01 5.134200958476284882e-01 7.284684743064278045e-01 3.099571109539331903e-01 1.502222882866774967e-01
+2.463382654375219083e-01 4.465700737264240994e-01 7.180855317941433613e-01 5.056099420785193921e-01 6.182117344332578313e-01 2.370453793561340117e-01 9.831748018047525850e-01 6.397098184531551102e-01 8.260469782208745837e-02 7.474671691560941245e-01 9.963429983418570224e-02 5.450078811081275898e-01 5.370188678062637333e-02 2.774024442708808991e-01 2.082643088545442778e-01 2.704155352788065736e-01 7.225035580445194894e-01 4.866791976239246420e-01 1.357043111201584606e-01 7.911335827987711067e-01 7.278977102006007893e-01 6.880892094410231419e-01 1.029231496520791600e-01
+6.901796117735281566e-01 1.558248977395644275e-01 4.241818789360329855e-01 5.055658246392458199e-01 1.756288758075611467e-01 4.215083703818177652e-01 7.809231602323289945e-01 1.170053878686481141e-01 6.497026323614403243e-01 5.733120641440232479e-01 4.407703406152092551e-01 5.608677124532297498e-01 7.471045703286000039e-01 3.334604336022076732e-01 8.927208811415126011e-01 9.794565286182396191e-01 9.621542824973521313e-01 3.945825239405253981e-01 8.338963875792834157e-01 9.310552325082104286e-01 7.688283033784242271e-01 3.798823731047119567e-01 1.459993613028365278e-02
+7.848623555505630511e-01 2.681039365355797344e-03 7.833208051794043891e-01 8.184381915171493604e-01 4.682581645582317709e-01 2.391069309436419932e-01 1.765377537168698607e-01 9.863494676539893424e-01 4.378412300863872009e-01 7.494505491149090481e-01 1.942180356195394308e-01 9.981402467222395547e-01 7.992190944052800505e-01 1.350875702852057936e-01 4.950149186748543650e-01 7.243422481248201761e-01 3.544596746353472216e-01 8.320192561472177228e-01 9.776840296475269865e-01 7.733852731914863110e-01 2.305732998099923048e-01 9.746878189802981041e-01 7.747723331200035979e-01
+6.521099013127149568e-01 5.452399443648201505e-01 8.146707517183656710e-01 3.827256063695345656e-01 7.954832091744263867e-01 7.834427643148527132e-01 9.661317930643520402e-02 9.215673965718058636e-01 4.914305728788055383e-01 4.105628408027649501e-01 9.844647830893304974e-02 3.974831165301851987e-01 3.857608898053827007e-01 5.520210781401946321e-01 3.445787541654143915e-03 4.552922057017416702e-01 7.456544561760444223e-01 4.753985092154335845e-01 2.821385239833401615e-01 7.560136035104459973e-01 8.453142510471420845e-01 6.679627143276523071e-01 6.910882868284401459e-01
+8.526493480446283302e-01 1.183917973068240315e-01 6.163988861865119517e-01 5.751899460059114455e-01 1.638797964925038375e-01 8.214597298784013235e-01 5.424670654187370156e-01 1.806631819658732763e-01 9.268107278221827672e-01 4.127397378597359445e-01 7.529877485901653733e-01 1.714251090083847018e-01 2.601487784245806179e-01 2.028326156742237263e-01 5.299879450122358948e-01 7.587877062981395193e-01 4.070738595375062996e-01 3.546903049793261875e-01 8.695365138547607176e-01 1.447085661525142619e-01 3.193366245820845606e-01 8.797841086211429795e-01 2.666562188639977071e-01

Modified: trunk/scipy/cluster/tests/test_distance.py
===================================================================
--- trunk/scipy/cluster/tests/test_distance.py	2008-09-07 07:46:29 UTC (rev 4693)
+++ trunk/scipy/cluster/tests/test_distance.py	2008-09-07 19:28:06 UTC (rev 4694)
@@ -40,11 +40,13 @@
import numpy as np
from numpy.testing import *
-from scipy.cluster.distance import squareform, pdist, matching, jaccard, dice, sokalsneath, rogerstanimoto, russellrao, yule, numobs_dm, numobs_y
+from scipy.cluster.distance import squareform, pdist, cdist, matching, jaccard, dice, sokalsneath, rogerstanimoto, russellrao, yule, numobs_dm, numobs_y

#from scipy.cluster.hierarchy import pdist, euclidean

_filenames = ["iris.txt",
+              "cdist-X1.txt",
+              "cdist-X2.txt",
"pdist-hamming-ml.txt",
"pdist-boolean-inp.txt",
"pdist-jaccard-ml.txt",
@@ -97,6 +99,298 @@
#print np.abs(Y_test2 - Y_right).max()
#print np.abs(Y_test1 - Y_right).max()

+class TestCdist(TestCase):
+    """
+    Test suite for the pdist function.
+    """
+
+    def test_cdist_euclidean_random(self):
+        "Tests cdist(X, 'euclidean') on random data."
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1']
+        X2 = eo['cdist-X2']
+        Y1 = cdist(X1, X2, 'euclidean')
+        Y2 = cdist(X1, X2, 'test_euclidean')
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_sqeuclidean_random(self):
+        "Tests cdist(X, 'sqeuclidean') on random data."
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1']
+        X2 = eo['cdist-X2']
+        Y1 = cdist(X1, X2, 'sqeuclidean')
+        Y2 = cdist(X1, X2, 'test_sqeuclidean')
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_cityblock_random(self):
+        "Tests cdist(X, 'sqeuclidean') on random data."
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1']
+        X2 = eo['cdist-X2']
+        Y1 = cdist(X1, X2, 'cityblock')
+        Y2 = cdist(X1, X2, 'test_cityblock')
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_hamming_double_random(self):
+        "Tests cdist(X, 'hamming') on random data."
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1']
+        X2 = eo['cdist-X2']
+        Y1 = cdist(X1, X2, 'hamming')
+        Y2 = cdist(X1, X2, 'test_hamming')
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_hamming_bool_random(self):
+        "Tests cdist(X, 'hamming') on random boolean data."
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1'] < 0.5
+        X2 = eo['cdist-X2'] < 0.5
+        Y1 = cdist(X1, X2, 'hamming')
+        Y2 = cdist(X1, X2, 'test_hamming')
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_jaccard_double_random(self):
+        "Tests cdist(X, 'jaccard') on random data."
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1']
+        X2 = eo['cdist-X2']
+        Y1 = cdist(X1, X2, 'jaccard')
+        Y2 = cdist(X1, X2, 'test_jaccard')
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_jaccard_bool_random(self):
+        "Tests cdist(X, 'jaccard') on random boolean data."
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1'] < 0.5
+        X2 = eo['cdist-X2'] < 0.5
+        Y1 = cdist(X1, X2, 'jaccard')
+        Y2 = cdist(X1, X2, 'test_jaccard')
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_chebychev_random(self):
+        "Tests cdist(X, 'chebychev') on random data."
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1']
+        X2 = eo['cdist-X2']
+        Y1 = cdist(X1, X2, 'chebychev')
+        Y2 = cdist(X1, X2, 'test_chebychev')
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_minkowski_random_p3d8(self):
+        "Tests cdist(X, 'minkowski') on random data. (p=3.8)"
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1']
+        X2 = eo['cdist-X2']
+        Y1 = cdist(X1, X2, 'minkowski', p=3.8)
+        Y2 = cdist(X1, X2, 'test_minkowski', p=3.8)
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_minkowski_random_p4d6(self):
+        "Tests cdist(X, 'minkowski') on random data. (p=4.6)"
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1']
+        X2 = eo['cdist-X2']
+        Y1 = cdist(X1, X2, 'minkowski', p=4.6)
+        Y2 = cdist(X1, X2, 'test_minkowski', p=4.6)
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_minkowski_random_p1d23(self):
+        "Tests cdist(X, 'minkowski') on random data. (p=1.23)"
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1']
+        X2 = eo['cdist-X2']
+        Y1 = cdist(X1, X2, 'minkowski', p=1.23)
+        Y2 = cdist(X1, X2, 'test_minkowski', p=1.23)
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_seuclidean_random(self):
+        "Tests cdist(X, 'seuclidean') on random data."
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1']
+        X2 = eo['cdist-X2']
+        Y1 = cdist(X1, X2, 'seuclidean')
+        Y2 = cdist(X1, X2, 'test_seuclidean')
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_sqeuclidean_random(self):
+        "Tests cdist(X, 'sqeuclidean') on random data."
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1']
+        X2 = eo['cdist-X2']
+        Y1 = cdist(X1, X2, 'sqeuclidean')
+        Y2 = cdist(X1, X2, 'test_sqeuclidean')
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_cosine_random(self):
+        "Tests cdist(X, 'cosine') on random data."
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1']
+        X2 = eo['cdist-X2']
+        Y1 = cdist(X1, X2, 'cosine')
+        Y2 = cdist(X1, X2, 'test_cosine')
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_correlation_random(self):
+        "Tests cdist(X, 'correlation') on random data."
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1']
+        X2 = eo['cdist-X2']
+        Y1 = cdist(X1, X2, 'correlation')
+        Y2 = cdist(X1, X2, 'test_correlation')
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_mahalanobis_random(self):
+        "Tests cdist(X, 'mahalanobis') on random data."
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1']
+        X2 = eo['cdist-X2']
+        Y1 = cdist(X1, X2, 'mahalanobis')
+        Y2 = cdist(X1, X2, 'test_mahalanobis')
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_canberra_random(self):
+        "Tests cdist(X, 'canberra') on random data."
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1'] < 0.5
+        X2 = eo['cdist-X2'] < 0.5
+        Y1 = cdist(X1, X2, 'canberra')
+        Y2 = cdist(X1, X2, 'test_canberra')
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_braycurtis_random(self):
+        "Tests cdist(X, 'braycurtis') on random data."
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1'] < 0.5
+        X2 = eo['cdist-X2'] < 0.5
+        Y1 = cdist(X1, X2, 'braycurtis')
+        Y2 = cdist(X1, X2, 'test_braycurtis')
+        print Y1, Y2
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_yule_random(self):
+        "Tests cdist(X, 'yule') on random data."
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1'] < 0.5
+        X2 = eo['cdist-X2'] < 0.5
+        Y1 = cdist(X1, X2, 'yule')
+        Y2 = cdist(X1, X2, 'test_yule')
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_matching_random(self):
+        "Tests cdist(X, 'matching') on random data."
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1'] < 0.5
+        X2 = eo['cdist-X2'] < 0.5
+        Y1 = cdist(X1, X2, 'matching')
+        Y2 = cdist(X1, X2, 'test_matching')
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_kulsinski_random(self):
+        "Tests cdist(X, 'kulsinski') on random data."
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1'] < 0.5
+        X2 = eo['cdist-X2'] < 0.5
+        Y1 = cdist(X1, X2, 'kulsinski')
+        Y2 = cdist(X1, X2, 'test_kulsinski')
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_dice_random(self):
+        "Tests cdist(X, 'dice') on random data."
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1'] < 0.5
+        X2 = eo['cdist-X2'] < 0.5
+        Y1 = cdist(X1, X2, 'dice')
+        Y2 = cdist(X1, X2, 'test_dice')
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_rogerstanimoto_random(self):
+        "Tests cdist(X, 'rogerstanimoto') on random data."
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1'] < 0.5
+        X2 = eo['cdist-X2'] < 0.5
+        Y1 = cdist(X1, X2, 'rogerstanimoto')
+        Y2 = cdist(X1, X2, 'test_rogerstanimoto')
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_russellrao_random(self):
+        "Tests cdist(X, 'russellrao') on random data."
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1'] < 0.5
+        X2 = eo['cdist-X2'] < 0.5
+        Y1 = cdist(X1, X2, 'russellrao')
+        Y2 = cdist(X1, X2, 'test_russellrao')
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_sokalmichener_random(self):
+        "Tests cdist(X, 'sokalmichener') on random data."
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1'] < 0.5
+        X2 = eo['cdist-X2'] < 0.5
+        Y1 = cdist(X1, X2, 'sokalmichener')
+        Y2 = cdist(X1, X2, 'test_sokalmichener')
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
+    def test_cdist_sokalsneath_random(self):
+        "Tests cdist(X, 'sokalsneath') on random data."
+        eps = 1e-07
+        # Get the data: the input matrix and the right output.
+        X1 = eo['cdist-X1'] < 0.5
+        X2 = eo['cdist-X2'] < 0.5
+        Y1 = cdist(X1, X2, 'sokalsneath')
+        Y2 = cdist(X1, X2, 'test_sokalsneath')
+        print (Y1-Y2).max()
+        self.failUnless(within_tol(Y1, Y2, eps))
+
class TestPdist(TestCase):
"""
Test suite for the pdist function.

`