diff --git a/.mailmap b/.mailmap
index 076860f1ef7e79f4651aab2b294f4f9e80bf66d5..74d7126b494ca0ca18ba4af933b155c251a2a87e 100644
--- a/.mailmap
+++ b/.mailmap
@@ -18,6 +18,10 @@ Brian Cheung <bcheung5@gmail.com> <cow@rusty.(none)>
 Brian Holt <bh00038@cvplws63.eps.surrey.ac.uk> <bdholt1@gmail.com>
 Christian Osendorfer <osendorf@gmail.com>
 Clay Woolam <clay@woolam.org>
+Denis Engemann <d.engemann@fz-juelich.de>
+Denis Engemann <d.engemann@fz-juelich.de> <denis.engemann@gmail.com>
+Denis Engemann <d.engemann@fz-juelich.de> <dengemann@Deniss-MacBook-Pro.local>
+Denis Engemann <d.engemann@fz-juelich.de> <dengemann <denis.engemann@gmail.com>
 Diego Molla <dmollaaliod@gmail.com> <diego@diego-desktop.(none)>
 DraXus <draxus@gmail.com> draxus <draxus@hammer.ugr>
 Edouard DUCHESNAY <ed203246@is206877.intra.cea.fr> <duchesnay@is143433.(none)>
@@ -25,10 +29,14 @@ Edouard DUCHESNAY <ed203246@is206877.intra.cea.fr> <edouard.duchesnay@gmail.com>
 Edouard DUCHESNAY <ed203246@is206877.intra.cea.fr> <edouard@is2206219.(none)>
 Emmanuelle Gouillart <emmanuelle.gouillart@nsup.org>
 Emmanuelle Gouillart <emmanuelle.gouillart@nsup.org> <emma@aleph.(none)>
-Fabian Pedregosa <fabian@fseoane.net> <fabian.pedregosa@inria.fr>
+Fabian Pedregosa <fabian.pedregosa@inria.fr>
+Fabian Pedregosa <fabian.pedregosa@inria.fr> <fabian@fseoane.net>
+Fabian Pedregosa <fabian.pedregosa@inria.fr> <f@bianp.net>
 Federico Vaggi <vaggi.federico@gmail.com>
-Gael Varoquaux <gael.varoquaux@normalesup.org>
-Gael Varoquaux <gael.varoquaux@normalesup.org> <varoquau@normalesup.org>
+Federico Vaggi <vaggi.federico@gmail.com> <vaggi.federico@GMAIL.COM>
+Gael Varoquaux <gael.varoquaux@inria.fr>
+Gael Varoquaux <gael.varoquaux@inria.fr> <gael.varoquaux@normalesup.org>
+Gael Varoquaux <gael.varoquaux@inria.fr> <varoquau@normalesup.org>
 Gilles Louppe <g.louppe@gmail.com> <g.louppe@ulg.ac.be>
 Harikrishnan S <hihari777@gmail.com>
 Hrishikesh Huilgolkar <hrishikesh911@gmail.com> <hrishikesh@QE-IND-WKS007.(none)>
@@ -37,6 +45,7 @@ Jake VanderPlas <vanderplas@astro.washington.edu> <jakevdp@yahoo.com>
 Jake VanderPlas <vanderplas@astro.washington.edu> <jakevdp@gmail.com>
 Jake VanderPlas <vanderplas@astro.washington.edu> <vanderplas@astro.washington.edu>
 James Bergstra <james.bergstra@gmail.com>
+Jaques Grobler <jaques.grobler@inria.fr> <jaquesgrobler@gmail.com>
 Jan Schl�ter <scikit-learn@jan-schlueter.de>
 Jean Kossaifi <jean.kossaifi@gmail.com>
 Jean Kossaifi <jean.kossaifi@gmail.com> <jkossaifi@is208616.intra.cea.fr>
@@ -52,6 +61,7 @@ Nelle Varoquaux <nelle.varoquaux@gmail.com>
 Nelle Varoquaux <nelle.varoquaux@gmail.com> <nelle@phgroup.com> <nelle@varoquaux@gmail.com>
 Nicolas Pinto <pinto@alum.mit.edu> <pinto@mit.edu>
 Noel Dawe <Noel.Dawe@cern.ch> <noel.dawe@gmail.com>
+Noel Dawe <Noel.Dawe@cern.ch> <noel.dAwe@cern.ch>
 Olivier Grisel <olivier.grisel@ensta.org> <ogrisel@turingcarpet.(none)>
 Olivier Grisel <olivier.grisel@ensta.org> <olivier.grisel@ensta.org>
 Olivier Hervieu <olivier.hervieu@gmail.com> <olivier.hervieu@tinyclues.com>
@@ -78,3 +88,6 @@ Wei Li <kuantkid@gmail.com>
 Wei Li <kuantkid@gmail.com> <kuantkid+github@gmail.com>
 X006 <x006@x006-icsl.(none)> <x006@x006laptop.(none)>
 Xinfan Meng <mxf3306@gmail.com> <mxf@chomsky.localdomain>
+Yannick Schwartz <yannick.schwartz@inria.fr> <yannick.schwartz@cea.fr>
+Yannick Schwartz <yannick.schwartz@inria.fr> <ys218403@is220245.(none)>
+
diff --git a/README.rst b/README.rst
index e2d58b9837f1497355ec52f95fdaa9d9313d65b2..6888292b113f5f8e3d9c7c798ebe968101a10c9e 100644
--- a/README.rst
+++ b/README.rst
@@ -35,8 +35,7 @@ Dependencies
 ============
 
 scikit-learn is tested to work under Python 2.6+ and Python 3.3+
-(using the same codebase thanks to an embedded copy of [six](
-http://pythonhosted.org/six/)).
+(using the same codebase thanks to an embedded copy of `six <http://pythonhosted.org/six/>`_).
 
 The required dependencies to build the software Numpy >= 1.3, SciPy >= 0.7
 and a working C/C++ compiler.
diff --git a/doc/conf.py b/doc/conf.py
index c82fa8a0a14ecbcdd12b804a79353a230c0362e8..2f6f41b3d3160a96ea0de41e9086fa3c4efdd9d8 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -68,7 +68,7 @@ copyright = u('2010 - 2013, scikit-learn developers (BSD License)')
 # built documents.
 #
 # The short X.Y version.
-version = '0.14-git'
+version = '0.14'
 # The full version, including alpha/beta/rc tags.
 import sklearn
 release = sklearn.__version__
diff --git a/doc/datasets/covtype.rst b/doc/datasets/covtype.rst
index 999f4c4edf0b3c7227d92132c31e5fba13595c6a..c0ed4ea08af3d67b8dbce9bde8ce64ecdfabe47c 100644
--- a/doc/datasets/covtype.rst
+++ b/doc/datasets/covtype.rst
@@ -13,7 +13,7 @@ Each sample has 54 features, described on the
 Some of the features are boolean indicators,
 while others are discrete or continuous measurements.
 
-``sklearn.datasets.fetch_covtype`` will load the covertype dataset;
+:func:`sklearn.datasets.fetch_covtype` will load the covertype dataset;
 it returns a dictionary-like object
 with the feature matrix in the ``data`` member
 and the target values in ``target``.
diff --git a/doc/documentation.rst b/doc/documentation.rst
index 9c7f2edc540569c3a190b3aa4e72d7226b7688f8..ae18dc29a499c4f3f140a06f00713b20379bf5f1 100644
--- a/doc/documentation.rst
+++ b/doc/documentation.rst
@@ -2,7 +2,7 @@
 
   <div class="container-index">
 
-Documentation of scikit-learn 0.13
+Documentation of scikit-learn 0.14
 ==================================
 
 .. raw:: html
@@ -78,9 +78,10 @@ Documentation of scikit-learn 0.13
                 <div class="span4 box">
                     <h2>Other Versions</h2>
                     <ul>
-                        <li><a href="http://scikit-learn.org/0.13/user_guide.html">scikit-learn 0.13 (stable)</a></li>
-                        <li>scikit-learn 0.14 (development)</li>
+                        <li>scikit-learn 0.14 (stable)</li>
+                        <li><a href="http://scikit-learn.org/0.15/user_guide.html">scikit-learn 0.15 (development)</a></li>
 
+                        <li><a href="http://scikit-learn.org/0.13/user_guide.html">scikit-learn 0.13</a></li>
                         <li><a href="http://scikit-learn.org/0.12/user_guide.html">scikit-learn 0.12</a></li>
                         <li><a href="http://scikit-learn.org/0.11/user_guide.html">scikit-learn 0.11</a></li>
                         <li><a href="http://scikit-learn.org/0.10/user_guide.html">scikit-learn 0.10</a></li>
diff --git a/doc/index.rst b/doc/index.rst
index 9d1c0fc225aad3bab890c322268dfe71c0ddb1bc..2d2c95b84634d4c83649f113b321bdeb1fb3ea2a 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -246,69 +246,92 @@
     <div class="container index-lower">
         <div class="row-fluid">
             <!-- News -->
-            <div class="span6">
+            <div class="span4">
                 <h4>News</h4>
                 <ul>
                 <li><em>On-going development:</em>
                 <a href="whats_new.html"><em>What's new</em> (changelog)</a>
                 </li>
-                <li><em>July 22th - 28th, 2013: internal sprint</em>
+                <li><em>August 2013.</em> scikit-learn 0.14 is available for download (<a href="whats_new.html">Changelog</a>).
+                </li>
+                <li><em>July 22-28th, 2013: international sprint.</em>
                 During this week-long sprint, we gathered most of the core
                 developers in Paris.
-                <!--
-                Here are some of the biggest changes in the upcoming version:
-                <ul>
-                <li>Python 3 support</li>
-                <li>Ensembles of Randomized Trees speed improvements</li>
-                <li>Restricted Boltzman Machines</li>
-                <li>Missing data imputation</li>
-                <li>Bi-clustering</li>
-                </ul>
-                -->
-
                 We want to thank our sponsors, our
                 hosts <a href="http://www.telecom-paristech.fr/">Télécom ParisTech</a>
                 and <a href="http://www.tinyclues.com/">tinyclues</a>, and
                 donations that helped fund this event.
 
-                <li><em>February 2013.</em> scikit-learn 0.13.1 is available for download (<a href="whats_new.html">Changelog</a>).
-                </li>
                 </ul>
             </div>
 
             <!-- Community -->
-            <div class="span6">
+            <div class="span4">
                 <h4>Community</h4>
                 <ul>
-                <li><em>Questions?</em> See <a href="http://stackoverflow.com/questions/tagged/scikit-learn">stackoverflow</a> # scikit-learn for usage questions</li>
-                <li><em>Mailing list:</em> scikit-learn-general@lists.sourceforge.net</li>
+                <li><em>Questions?</em> See <a href="http://stackoverflow.com/questions/tagged/scikit-learn">stackoverflow</a> # scikit-learn</li>
+                <li><em>Mailing list:</em> <a href="https://lists.sourceforge.net/lists/listinfo/scikit-learn-general">scikit-learn-general@lists.sourceforge.net</a></li>
                 <li><em>IRC:</em> #scikit-learn @ <a href="http://webchat.freenode.net/">freenode</a></li>
-                <li><em>Help us:</em>
-                  <button class="btn btn-warning btn-big" onclick="document.getElementById('paypal-form').submit(); return false;"><b>Donate!</b></button> (<a href="about.html#funding">read more</a>)</li>
-                    <form target="_top" id="paypal-form" method="post" action="https://www.paypal.com/cgi-bin/webscr">
+                </ul>
+
+                <form target="_top" id="paypal-form" method="post" action="https://www.paypal.com/cgi-bin/webscr">
                     <input type="hidden" value="_s-xclick" name="cmd">
                     <input type="hidden" value="74EYUMF3FTSW8" name="hosted_button_id">
-                    </form>
-                </ul>
+                </form>
+
+                <a class="btn btn-warning btn-big" onclick="document.getElementById('paypal-form').submit(); return false;">Help us, <strong>donate!</strong></a>
+                <a class="btn btn-warning btn-big cite-us" href="./about.html#citing-scikit-learn"><strong>Cite us!</strong></a>
+
+                <small style="display: block; margin-top: 10px"><a href="about.html#funding">Read more about donations</a></small>
             </div>
 
             <!-- who using -->
-            <!--
             <div class="span4">
-                <h4>Who is using scikit-learn?</h4>
+                <h4>Who uses scikit-learn?</h4>
 
-                </h4>
-                <div id="myCarousel" class="carousel slide">
+                <div id="testimonials_carousel" class="carousel slide">
                     <div class="carousel-inner">
-                        <div class="active item"><img src="_images/inria.jpg" class="thumbnail" /><br /> <em>-- Great stuff!</em></div>
-                        <div class="item"><img src="_static/img/google.png" class="thumbnail" /><br /> <em>-- So good!</em></div>
+                        <div class="active item">
+                          <img src="_images/inria.jpg" class="thumbnail" />
+                          <p>
+                          <em>"We use scikit-learn to support leading-edge basic research [...]"</em>
+                          </p>
+                        </div>
+                        <div class="item">
+                          <img src="_images/evernote.png" class="thumbnail" />
+                          <p>
+                          <em>"For these tasks, we relied on the excellent scikit-learn package for Python."</em>
+                          </p>
+                        </div>
+                        <div class="item">
+                          <img src="_images/telecomparistech.jpg"
+                               class="thumbnail" />
+                          <p>
+                          <em>"The great benefit of scikit-learn is its fast learning curve [...]"</em>
+                          </p>
+                        </div>
+                        <div class="item">
+                          <img src="_images/aweber.png" class="thumbnail" />
+                          <p>
+                          <em>"It allows us to do AWesome stuff we would not otherwise accomplish"</em>
+                          </p>
+                        </div>
                     </div>
-                    <div style="margin-top: 5px"><a href="#">More testimonials</a></div>
                 </div>
-                <script>$('#myCarousel').carousel()</script>
+                <p align="right">
+                <small class="example-link">
+                <a href="testimonials/testimonials.html">More testimonials</a>
+                </small>
+                </p>
             </div>
-            -->
 
         </div>
     </div>
     </div>
+
+
+    <script>
+      $('#testimonials_carousel').carousel()
+    </script>
+
+
diff --git a/doc/modules/classes.rst b/doc/modules/classes.rst
index 987ccc548af7e1fe9191c8a2ac75b3c8c440daf9..a577f9fe66ee3ad048d691bfdda48856a2f5b317 100644
--- a/doc/modules/classes.rst
+++ b/doc/modules/classes.rst
@@ -715,7 +715,6 @@ details.
 
    metrics.accuracy_score
    metrics.auc
-   metrics.auc_score
    metrics.average_precision_score
    metrics.classification_report
    metrics.confusion_matrix
@@ -730,6 +729,7 @@ details.
    metrics.precision_recall_fscore_support
    metrics.precision_score
    metrics.recall_score
+   metrics.roc_auc_score
    metrics.roc_curve
    metrics.zero_one_loss
 
diff --git a/doc/modules/model_evaluation.rst b/doc/modules/model_evaluation.rst
index 869ff37083e56722f75dc181ff536ec0158c695b..ca3ad443d12240155ead53797d6bf9ae6bbb458c 100644
--- a/doc/modules/model_evaluation.rst
+++ b/doc/modules/model_evaluation.rst
@@ -56,7 +56,7 @@ Scoring                    Function
 'f1'                       :func:`sklearn.metrics.f1_score`
 'precision'                :func:`sklearn.metrics.precision_score`
 'recall'                   :func:`sklearn.metrics.recall_score`
-'roc_auc'                  :func:`sklearn.metrics.auc_score`
+'roc_auc'                  :func:`sklearn.metrics.roc_auc_score`
 
 **Clustering**
 'adjusted_rand_score'      :func:`sklearn.metrics.adjusted_rand_score`
@@ -182,11 +182,11 @@ Some of these are restricted to the binary classification case:
 .. autosummary::
    :template: function.rst
 
-   auc_score
    average_precision_score
    hinge_loss
    matthews_corrcoef
    precision_recall_curve
+   roc_auc_score
    roc_curve
 
 
@@ -268,27 +268,6 @@ and with a list of labels format:
     for an example of accuracy score usage using permutations of
     the dataset.
 
-Area under the curve (AUC)
-...........................
-
-The :func:`auc_score` function computes the 'area under the curve' (AUC) which
-is the area under the receiver operating characteristic (ROC) curve.
-
-This function requires  the true binary value and the target scores, which can
-either be probability estimates of the positive class, confidence values, or
-binary decisions.
-
-  >>> import numpy as np
-  >>> from sklearn.metrics import auc_score
-  >>> y_true = np.array([0, 0, 1, 1])
-  >>> y_scores = np.array([0.1, 0.4, 0.35, 0.8])
-  >>> auc_score(y_true, y_scores)
-  0.75
-
-For more information see the
-`Wikipedia article on AUC
-<http://en.wikipedia.org/wiki/Receiver_operating_characteristic#Area_under_curve>`_
-and the :ref:`roc_metrics` section.
 
 .. _average_precision_metrics:
 
@@ -713,7 +692,7 @@ with a svm classifier::
 
 
 Log loss
---------
+........
 The log loss, also called logistic regression loss or cross-entropy loss,
 is a loss function defined on probability estimates.
 It is commonly used in (multinomial) logistic regression and neural networks,
@@ -795,7 +774,7 @@ function:
 .. _roc_metrics:
 
 Receiver operating characteristic (ROC)
-........................................
+.......................................
 
 The function :func:`roc_curve` computes the `receiver operating characteristic
 curve, or ROC curve (quoting
@@ -809,16 +788,36 @@ Wikipedia) <http://en.wikipedia.org/wiki/Receiver_operating_characteristic>`_:
   positive rate), at various threshold settings. TPR is also known as
   sensitivity, and FPR is one minus the specificity or true negative rate."
 
+This function requires the true binary
+value and the target scores, which can either be probability estimates of the
+positive class, confidence values, or binary decisions.
 Here a small example of how to use the :func:`roc_curve` function::
 
     >>> import numpy as np
-    >>> from sklearn import metrics
+    >>> from sklearn.metrics import roc_curve
     >>> y = np.array([1, 1, 2, 2])
     >>> scores = np.array([0.1, 0.4, 0.35, 0.8])
-    >>> fpr, tpr, thresholds = metrics.roc_curve(y, scores, pos_label=2)
+    >>> fpr, tpr, thresholds = roc_curve(y, scores, pos_label=2)
     >>> fpr
     array([ 0. ,  0.5,  0.5,  1. ])
+    >>> tpr
+    array([ 0.5,  0.5,  1. ,  1. ])
+    >>> thresholds
+    array([ 0.8 ,  0.4 ,  0.35,  0.1 ])
+
+The :func:`roc_auc_score` function computes the area under the receiver
+operating characteristic (ROC) curve, which is also denoted by
+AUC or AUROC.  By computing the
+area under the roc curve, the curve information is summarized in one number.
+For more information see the `Wikipedia article on AUC
+<http://en.wikipedia.org/wiki/Receiver_operating_characteristic#Area_under_curve>`_.
 
+  >>> import numpy as np
+  >>> from sklearn.metrics import roc_auc_score
+  >>> y_true = np.array([0, 0, 1, 1])
+  >>> y_scores = np.array([0.1, 0.4, 0.35, 0.8])
+  >>> roc_auc_score(y_true, y_scores)
+  0.75
 
 The following figure shows an example of such ROC curve.
 
diff --git a/doc/testimonials/images/aweber.png b/doc/testimonials/images/aweber.png
new file mode 100644
index 0000000000000000000000000000000000000000..d35c4d7571e3029950dfdc662a442fa170472e49
Binary files /dev/null and b/doc/testimonials/images/aweber.png differ
diff --git a/doc/testimonials/images/evernote.png b/doc/testimonials/images/evernote.png
new file mode 100644
index 0000000000000000000000000000000000000000..6c1f989731c4bd917171a674107633027c069cc1
Binary files /dev/null and b/doc/testimonials/images/evernote.png differ
diff --git a/doc/testimonials/images/telecomparistech.jpg b/doc/testimonials/images/telecomparistech.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..ddf35ebdc3e4e3902191cdb23b189d5f09b062b3
Binary files /dev/null and b/doc/testimonials/images/telecomparistech.jpg differ
diff --git a/doc/testimonials/testimonials.rst b/doc/testimonials/testimonials.rst
index 886a375f9d06b0d9caad60e22916cc9f1c0157ee..454c02203dbba8df93f0e47ff174ccd45d2cab7b 100644
--- a/doc/testimonials/testimonials.rst
+++ b/doc/testimonials/testimonials.rst
@@ -12,52 +12,146 @@ Who is using scikit-learn?
 .. to add a testimonials, just XXX
 
 
-Inria
+`Inria <http://www.inria.fr>`_
 -------------------------------
 
+.. raw:: html
+
+  <div class="logo">
+
 .. image:: images/inria.jpg
+   :target: http://www.inria.fr
+
+.. raw:: html
+
+  </div>
+
+.. title Scikit-learn for efficient and easier machine learning research
+.. Author: Gaël Varoquaux
+
+
+At INRIA, we use scikit-learn to support leading-edge basic research in many
+teams: `Parietal <https://team.inria.fr/parietal/>`_ for neuroimaging, `Lear
+<http://lear.inrialpes.fr/>`_ for computer vision, `Visages
+<https://www.irisa.fr/visages/index>`_ for medical image analysis, `Privatics
+<https://team.inria.fr/privatics>`_ for security. The project is a fantastic
+tool to address difficult applications of machine learing in an academic
+environment as it is performant and versatile, but all easy-to-use and well
+documented, which makes it well suited to grad students.
 
-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus et ipsum ac
-ipsum auctor pulvinar. In fermentum justo libero, in aliquet dui tempus sit
-amet. Maecenas sed sem purus. Nulla mollis mi sit amet diam tristique, vitae
-accumsan tellus ullamcorper. Pellentesque ligula est, molestie non eros sed,
-sodales aliquam quam.
 
 .. raw:: html
 
-   <div class="testimonial-website">
+   <span class="testimonial-author">
 
-**website:** `www.inria.fr <http://www.inria.fr>`_
+Gaël Varoquaux, research at Parietal
 
 .. raw:: html
 
-    </div>
+   </span>
 
 
-Inria
--------------------------------
+`Evernote <http://evernote.com>`_
+----------------------------------
 
-.. image:: images/inria.jpg
+.. raw:: html
+
+  <div class="logo">
+
+.. image:: images/evernote.png
+   :target: https://evernote.com
+
+.. raw:: html
+
+  </div>
+
+
+Building a classifier is typically an iterative process of exploring
+the data, selecting the features (the attributes of the data believed
+to be predictive in some way), training the models, and finally
+evaluating them. For many of these tasks, we relied on the excellent
+scikit-learn package for Python.
+
+`Read more <http://blog.evernote.com/tech/2013/01/22/stay-classified/>`_
+
+.. raw:: html
+
+   <span class="testimonial-author">
+
+Mark Ayzenshtat, VP, Augmented Intelligence
+
+.. raw:: html
 
-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus et ipsum ac
-ipsum auctor pulvinar. In fermentum justo libero, in aliquet dui tempus sit
-amet. Maecenas sed sem purus. Nulla mollis mi sit amet diam tristique, vitae
-accumsan tellus ullamcorper. Pellentesque ligula est, molestie non eros sed,
-sodales aliquam quam.
+   </span>
+
+`Télécom ParisTech <http://www.telecom-paristech.fr>`_
+--------------------------------------------------------
+
+.. raw:: html
+
+  <div class="logo">
+
+.. image:: images/telecomparistech.jpg
+   :target: https://www.telecom-paristech.fr
+
+.. raw:: html
+
+  </div>
+
+
+At Telecom ParisTech, scikit-learn is used for hands-on sessions and home
+assignments in introductory and advanced machine learning courses. The classes
+are for undergrads and masters students. The great benefit of scikit-learn is
+its fast learning curve that allows students to quickly start working on
+interesting and motivating problems.
+
+.. raw:: html
+
+   <span class="testimonial-author">
+
+Alexandre Gramfort, Assistant Professor
 
 .. raw:: html
 
-   <div class="testimonial-website">
+   </span>
+
 
-**website:** `www.inria.fr <http://www.inria.fr>`_
+`AWeber <http://aweber.com/>`_
+------------------------------------------
 
 .. raw:: html
 
-    </div>
+  <div class="logo">
+
+.. image:: images/aweber.png
+   :target: http://aweber.com/
+
+.. raw:: html
+
+  </div>
+
 
+The scikit-learn toolkit is indispensable for the Data Analysis and Management
+team at AWeber.  It allows us to do AWesome stuff we would not otherwise have
+the time or resources to accomplish. The documentation is excellent, allowing
+new engineers to quickly evaluate and apply many different algorithms to our
+data. The text feature extraction utilities are useful when working with the
+large volume of email content we have at AWeber. The RandomizedPCA
+implementation, along with Pipelining and FeatureUnions, allows us to develop
+complex machine learning algorithms efficiently and reliably.
 
-.. END
+Anyone interested in learning more about how AWeber deploys scikit-learn in a
+production environment should check out talks from PyData Boston by AWeber's
+Michael Becker available at https://github.com/mdbecker/pydata_2013
 
 .. raw:: html
 
-    </div>
+   <span class="testimonial-author">
+
+Michael Becker, Software Engineer, Data Analysis and Management Ninjas
+
+.. raw:: html
+
+   </span>
+
+
diff --git a/doc/themes/scikit-learn/layout.html b/doc/themes/scikit-learn/layout.html
index fa1b0302ff37ab2854a72184803e91ac8f577dba..369760d422a6ab64b9cbc347a5d4f9f81371b7b0 100644
--- a/doc/themes/scikit-learn/layout.html
+++ b/doc/themes/scikit-learn/layout.html
@@ -108,27 +108,98 @@
 {%- if pagename == 'index' %}
 <!-- Banner -->
 <div class="container banner-container">
-    <div class="row-fluid banner-inner">
-        <div class="span6">
-            <div class="row-fluid">
-                <div class="offset2 span8"><div class="thumbnail">
-		  <a href="{{ pathto('auto_examples/plot_classifier_comparison') }}">
-		    <img src="{{ pathto('_static/banner_example.png', 1) }}"/>
-		  </a>
-		</div></div>
-            </div>
-        </div>
-        <div class="span6">
-            <h1>scikit-learn</h1>
-            <h2>Machine Learning in Python</h2>
-            <ul>
-                <li>Simple and efficient tools for data mining and data analysis</li>
-                <li>Accessible to everybody, and reusable in various contexts</li>
-                <li>Built on NumPy, SciPy, and matplotlib</li>
-                <li>Open source, commercially usable - BSD license</li>
-            </ul>
-        </div>
+  <div class="row-fluid banner-inner">
+    <div class="hidden-phone">
+      <div class="span6">
+	<div class="row-fluid">
+          <div class="offset2 span8"><div id="index_carousel_tn" class="thumbnail">
+	      <div id="examples_carousel" class="carousel slide" data-interval="false">
+		<ol id="scikit_learn_index_indicators" class="carousel-indicators">
+		  <li data-target="#examples_carousel" data-slide-to="0" class="active"></li>
+		  <li data-target="#examples_carousel" data-slide-to="1"></li>
+		  <li data-target="#examples_carousel" data-slide-to="2"></li>
+		  <li data-target="#examples_carousel" data-slide-to="3"></li>
+		  <li data-target="#examples_carousel" data-slide-to="4"></li>
+		  <li data-target="#examples_carousel" data-slide-to="5"></li>
+		  <li data-target="#examples_carousel" data-slide-to="6"></li>
+		  <li data-target="#examples_carousel" data-slide-to="7"></li>
+		  <li data-target="#examples_carousel" data-slide-to="8"></li>
+		  <li data-target="#examples_carousel" data-slide-to="9"></li>
+		  <li data-target="#examples_carousel" data-slide-to="10"></li>
+		  <li data-target="#examples_carousel" data-slide-to="11"></li>
+		</ol>
+		<!-- Carousel items -->
+		<div class="carousel-inner">
+		  <div class="active item">
+		    <a href="{{ pathto('auto_examples/plot_classifier_comparison') }}">
+		      <div class="crop-wrapper" style="width: 380px; height: 190px; overflow: hidden">
+			<img src="_images/plot_classifier_comparison_1.png"
+			     style="max-height: 200px; max-width: 629px; width: 629px; height: 186px;"></div></a>
+		  </div>
+		  <div class="item">
+		    <a href="auto_examples/covariance/plot_outlier_detection.html">
+		      <img src="_images/plot_outlier_detection_3.png"></a>
+		  </div>
+		  <div class="item">
+		    <a href="{{pathto('auto_examples/neighbors/plot_species_kde') }}">
+		      <img src="_images/plot_species_kde_1.png"></a>
+		  </div>
+		  <div class="item">
+		    <a href="{{pathto('auto_examples/linear_model/plot_lasso_lars') }}">
+		      <img src="_images/plot_lasso_lars_1.png"></a>
+		  </div>
+		  <div class="item">
+		    <a href="{{ pathto('auto_examples/decomposition/plot_faces_decomposition') }}">
+		      <img src="_images/plot_faces_decomposition_4.png"></a>
+		  </div>
+		  <div class="item">
+		    <a href="{{ pathto('auto_examples/cluster/plot_cluster_comparison') }}">
+		      <img src="_images/plot_cluster_comparison_1.png"></a>
+		  </div>
+		  <div class="item">
+		    <a href="{{ pathto('auto_examples/ensemble/plot_adaboost_twoclass') }}">
+		      <img src="_images/plot_adaboost_twoclass_1.png"></a>
+		  </div>
+		  <div class="item">
+		    <a href="{{ pathto('auto_examples/plot_lda_qda') }}">
+		      <img src="_images/plot_lda_qda_1.png"></a>
+		  </div>
+		  <div class="item">
+		    <a href="{{pathto('auto_examples/gaussian_process/plot_gp_regression') }}">
+		      <img src="_images/plot_gp_regression_2.png"></a>
+		  </div>
+		  <div class="item">
+		    <a href="{{ pathto('auto_examples/manifold/plot_compare_methods') }}">
+		      <img src="_images/plot_compare_methods_1.png"></a>
+		  </div>
+		  <div class="item">
+		    <a href="{{ pathto('auto_examples/mixture/plot_gmm_pdf') }}">
+		      <img src="_images/plot_gmm_pdf_1.png"></a>
+		  </div>
+		  <div class="item">
+		    <a href="{{ pathto('auto_examples/cluster/plot_lena_ward_segmentation') }}">
+		      <img src="_images/plot_lena_ward_segmentation_1.png"></a>
+		  </div>
+		</div>
+		<!-- Carousel nav -->
+		<a class="carousel-control left" href="#examples_carousel" data-slide="prev">&lsaquo;</a>
+		<a class="carousel-control right" href="#examples_carousel" data-slide="next">&rsaquo;</a>
+	      </div>
+	  </div></div>
+	</div>
+      </div>
+    </div>
+    <div id="intro_to_sklearn_p" class="span6">
+      <h1>scikit-learn</h1>
+      <h2>Machine Learning in Python</h2>
+      <ul>
+        <li>Simple and efficient tools for data mining and data analysis</li>
+        <li>Accessible to everybody, and reusable in various contexts</li>
+        <li>Built on NumPy, SciPy, and matplotlib</li>
+        <li>Open source, commercially usable - BSD license</li>
+      </ul>
     </div>
+  </div>
 </div>
 {%- endif %}
 
diff --git a/doc/themes/scikit-learn/static/banner_example.png b/doc/themes/scikit-learn/static/banner_example.png
deleted file mode 100755
index 00c0a42b2ff990d0d46e7c402a56a99aa1212bd0..0000000000000000000000000000000000000000
Binary files a/doc/themes/scikit-learn/static/banner_example.png and /dev/null differ
diff --git a/doc/themes/scikit-learn/static/nature.css_t b/doc/themes/scikit-learn/static/nature.css_t
index c83f6dc583f1164565d741e8652b26398ca93f82..41f5657df6fb8f5313d80ecddb7ce41977bf960a 100644
--- a/doc/themes/scikit-learn/static/nature.css_t
+++ b/doc/themes/scikit-learn/static/nature.css_t
@@ -800,7 +800,8 @@ div.container.index-lower ul {
 }
 
 div.container.index-lower ul li {
-    margin-bottom: 5px;
+    margin-bottom: 8px;
+    line-height: 1.3em;
 }
 
 div.container.index-lower ul li em {
@@ -808,6 +809,17 @@ div.container.index-lower ul li em {
     font-weight: bold;
 }
 
+#paypal-form {
+    margin: 30px 0;
+    padding: 0;
+}
+
+div.container.index-lower a.cite-us {
+    margin-left: 60px;
+    padding-right: 20px;
+    padding-left: 20px;
+}
+
 div.box h2 {
     height: 26px;
     background-color: transparent;
@@ -846,10 +858,77 @@ div.box-links p {
     display: inline;
 }
 
+div#examples_carousel {
+    margin-bottom: 0px;
+}
+
+div.carousel>.carousel-inner>.item {
+  width: 100%;
+  margin: auto;
+}
+
+
 div.carousel img {
-    max-height: 80px;
-    height: 80px;
+    max-height: 70px;
+    background-color: #fff;
+    margin: auto;
+}
+
+div#testimonials_carousel img {
+    max-width: 50%;
+}
+
+div#testimonials_carousel {
+    height: 120px;
+}
+
+
+div#examples_carousel img {
+    max-height: 201px;
+    height: 186px;
     background-color: #fff;
+    margin: 10px auto;
+}
+
+div#examples_carousel .carousel-indicators {
+    position: absolute;
+    top: 200px;
+    right: 26%; # Should be adjusted as the number of elements grows
+}
+
+div#examples_carousel .carousel-indicators .active {
+    background-color: #0F72F0;
+}
+
+div#examples_carousel .carousel-indicators li {
+    background-color: rgba(52, 147, 235, 0.25);
+}
+
+div#examples_carousel .carousel-control {
+    top: 203px;
+    left: 1px;
+    width: 25px;
+    height: 25px;
+    font-size: 37px;
+    line-height: 19px;
+    background: rgba(28, 140, 245, 0.38);
+}
+
+div#examples_carousel .carousel-control.right {
+    left: auto;
+    right: 2px;
+}
+
+div#intro_to_sklearn_p li {
+    line-height: 22px;
+}
+
+div#index_carousel_tn {
+    height: 216px;
+    width: 380px;
+    max-width: 130%;
+    background: white;
+    padding: 0px;
 }
 
 p.doc-version {
@@ -925,29 +1004,43 @@ div.testimonial h2 {
     text-align: center;
 }
 
-div.testimonial img {
+
+div.logo {
     float: left;
-    padding-right: 30px;
+    width: 200px;
+}
+
+div.logo img {
+  max-width: 150px;
+  max-height: 150px;
 }
 
 div.testimonial p {
     line-height: 1.5em;
-    padding-left: 30px;
     font-size: 1.1em;
+    color: #1c1c1c;
+    padding-left: 230px;
 }
 
-div.testimonial-website {
+div.testimonial span.testimonial-author {
     width: 100%;
     text-align: right;
+    margin-bottom: 30px;
+}
+
+div.testimonial span.testimonial-author p{
     font-size: 0.8em;
+    font-style: italic;
+    color: #808080;
 }
 
+
 .no-display {
   display: none;
 }
 
 .btn-group {
-  height: 100%	height: 100%;
+    height: 100%;
 }
 
 .btn-group .dropdown-menu {
@@ -970,7 +1063,7 @@ div.navbar ul.dropdown-menu li{
 }
 
 div.navbar ul.dropdown-menu li a {
-  font-size: 88%;
+  font-size: 100%;
   color: #2878A2;
   padding: 0;
   font-weight: normal;
@@ -1055,7 +1148,7 @@ div.navbar ul.dropdown-menu li a.btn {
 
 .navbar ul.dropdown-menu li {
   font-weight: bold;
-  font-size: 11px;
+  font-size: 12px;
   color: #000;
 }
 
@@ -1067,6 +1160,7 @@ div.container-index {
   margin-left: -210px;
 }
 
+
 @media all and (max-width: 780px) {
   .fork-me {
       display: none;
diff --git a/doc/whats_new.rst b/doc/whats_new.rst
index c103ec617f934304f88bed7ff6509413b212b019..2bead5d0be6f8c5a702247fcd7e45ca079e8f733 100644
--- a/doc/whats_new.rst
+++ b/doc/whats_new.rst
@@ -1,8 +1,8 @@
 .. currentmodule:: sklearn
 
-.. _changes_0_14_rc:
+.. _changes_0_14:
 
-0.14-rc
+0.14
 =======
 
 Changelog
@@ -212,6 +212,11 @@ Changelog
 API changes summary
 -------------------
 
+   - The :func:`auc_score` was renamed :func:`roc_auc_score`.
+
+   - Testing scikit-learn with `sklearn.test()` is deprecated. Use
+     `nosetest sklearn` from the command line.
+
    - Feature importances in :class:`tree.DecisionTreeClassifier`,
      :class:`tree.DecisionTreeRegressor` and all derived ensemble estimators
      are now computed on the fly when accessing  the ``feature_importances_``
@@ -279,6 +284,99 @@ API changes summary
 
    - Better input validation, warning on unexpected shapes for y.
 
+People
+------
+List of contributors for release 0.14 by number of commits.
+
+ * 277  Gilles Louppe
+ * 245  Lars Buitinck
+ * 187  Andreas Mueller
+ * 124  Arnaud Joly
+ * 112  Jaques Grobler
+ * 109  Gael Varoquaux
+ * 107  Olivier Grisel
+ * 102  Noel Dawe
+ *  99  Kemal Eren
+ *  79  Joel Nothman
+ *  75  Jake VanderPlas
+ *  73  Nelle Varoquaux
+ *  71  Vlad Niculae
+ *  65  Peter Prettenhofer
+ *  64  Alexandre Gramfort
+ *  54  Mathieu Blondel
+ *  38  Nicolas Trésegnie
+ *  35  eustache
+ *  27  Denis Engemann
+ *  25  Yann N. Dauphin
+ *  19  Justin Vincent
+ *  17  Robert Layton
+ *  15  Doug Coleman
+ *  14  Michael Eickenberg
+ *  13  Robert Marchman
+ *  11  Fabian Pedregosa
+ *  11  Philippe Gervais
+ *  10  Jim Holmström
+ *  10  Tadej Janež
+ *  10  syhw
+ *   9  Mikhail Korobov
+ *   9  Steven De Gryze
+ *   8  sergeyf
+ *   7  Ben Root
+ *   7  Hrishikesh Huilgolkar
+ *   6  Kyle Kastner
+ *   6  Martin Luessi
+ *   6  Rob Speer
+ *   5  Federico Vaggi
+ *   5  Raul Garreta
+ *   5  Rob Zinkov
+ *   4  Ken Geis
+ *   3  A. Flaxman
+ *   3  Denton Cockburn
+ *   3  Dougal Sutherland
+ *   3  Ian Ozsvald
+ *   3  Johannes Schönberger
+ *   3  Robert McGibbon
+ *   3  Roman Sinayev
+ *   3  Szabo Roland
+ *   2  Diego Molla
+ *   2  Imran Haque
+ *   2  Jochen Wersdörfer
+ *   2  Sergey Karayev
+ *   2  Yannick Schwartz
+ *   2  jamestwebber
+ *   1  Abhijeet Kolhe
+ *   1  Alexander Fabisch
+ *   1  Bastiaan van den Berg
+ *   1  Benjamin Peterson
+ *   1  Daniel Velkov
+ *   1  Fazlul Shahriar
+ *   1  Felix Brockherde
+ *   1  Félix-Antoine Fortin
+ *   1  Harikrishnan S
+ *   1  Jack Hale
+ *   1  JakeMick
+ *   1  James McDermott
+ *   1  John Benediktsson
+ *   1  John Zwinck
+ *   1  Joshua Vredevoogd
+ *   1  Justin Pati
+ *   1  Kevin Hughes
+ *   1  Kyle Kelley
+ *   1  Matthias Ekman
+ *   1  Miroslav Shubernetskiy
+ *   1  Naoki Orii
+ *   1  Norbert Crombach
+ *   1  Rafael Cunha de Almeida
+ *   1  Rolando Espinoza La fuente
+ *   1  Seamus Abshere
+ *   1  Sergey Feldman
+ *   1  Sergio Medina
+ *   1  Stefano Lattarini
+ *   1  Steve Koch
+ *   1  Sturla Molden
+ *   1  Thomas Jarosch
+ *   1  Yaroslav Halchenko
+
 .. _changes_0_13_1:
 
 0.13.1
diff --git a/examples/randomized_search.py b/examples/randomized_search.py
index 3c3c54cd41a412ff031fb795533af7534177d7ce..14a15139448d0769286d3c87e8aa3dad0c60ae45 100644
--- a/examples/randomized_search.py
+++ b/examples/randomized_search.py
@@ -79,6 +79,7 @@ param_grid = {"max_depth": [3, None],
 
 # run grid search
 grid_search = GridSearchCV(clf, param_grid=param_grid)
+start = time()
 grid_search.fit(X, y)
 
 print("GridSearchCV took %.2f seconds for %d candidate parameter settings."
diff --git a/setup.py b/setup.py
index d24711b184ea163924ecd220c0a64ec73e3e92bf..5031f3d31d8e06056aa0be95dd42b7f246a91e48 100755
--- a/setup.py
+++ b/setup.py
@@ -1,128 +1,156 @@
-#! /usr/bin/env python
-#
-# Copyright (C) 2007-2009 Cournapeau David <cournape@gmail.com>
-#               2010 Fabian Pedregosa <fabian.pedregosa@inria.fr>
-
-descr = """A set of python modules for machine learning and data mining"""
-
-import sys
-import os
-
-if sys.version_info[0] < 3:
-    import __builtin__ as builtins
-else:
-    import builtins
-
-# This is a bit (!) hackish: we are setting a global variable so that the main
-# sklearn __init__ can detect if it is being loaded by the setup routine, to
-# avoid attempting to load components that aren't built yet.
-builtins.__SKLEARN_SETUP__ = True
-
-DISTNAME = 'scikit-learn'
-DESCRIPTION = 'A set of python modules for machine learning and data mining'
-LONG_DESCRIPTION = open('README.rst').read()
-MAINTAINER = 'Andreas Mueller'
-MAINTAINER_EMAIL = 'amueller@ais.uni-bonn.de'
-URL = 'http://scikit-learn.org'
-LICENSE = 'new BSD'
-DOWNLOAD_URL = 'http://sourceforge.net/projects/scikit-learn/files/'
-
-# We can actually import a restricted version of sklearn that
-# does not need the compiled code
-import sklearn
-
-VERSION = sklearn.__version__
-
-###############################################################################
-# Optional setuptools features
-# We need to import setuptools early, if we want setuptools features,
-# as it monkey-patches the 'setup' function
-
-# For some commands, use setuptools
-if len(set(('develop', 'release', 'bdist_egg', 'bdist_rpm',
-           'bdist_wininst', 'install_egg_info', 'build_sphinx',
-           'egg_info', 'easy_install', 'upload',
-           '--single-version-externally-managed',
-            )).intersection(sys.argv)) > 0:
-    import setuptools
-    extra_setuptools_args = dict(
-        zip_safe=False,  # the package can run out of an .egg file
-        include_package_data=True,
-    )
-else:
-    extra_setuptools_args = dict()
-
-
-def configuration(parent_package='', top_path=None):
-    if os.path.exists('MANIFEST'):
-        os.remove('MANIFEST')
-
-    from numpy.distutils.misc_util import Configuration
-    config = Configuration(None, parent_package, top_path)
-
-    # Avoid non-useful msg:
-    # "Ignoring attempt to set 'name' (from ... "
-    config.set_options(ignore_setup_xxx_py=True,
-                       assume_default_configuration=True,
-                       delegate_options_to_subpackages=True,
-                       quiet=True)
-
-    config.add_subpackage('sklearn')
-
-    return config
-
-
-def setup_package():
-    metadata = dict(name=DISTNAME,
-                    maintainer=MAINTAINER,
-                    maintainer_email=MAINTAINER_EMAIL,
-                    description=DESCRIPTION,
-                    license=LICENSE,
-                    url=URL,
-                    version=VERSION,
-                    download_url=DOWNLOAD_URL,
-                    long_description=LONG_DESCRIPTION,
-                    classifiers=['Intended Audience :: Science/Research',
-                                 'Intended Audience :: Developers',
-                                 'License :: OSI Approved',
-                                 'Programming Language :: C',
-                                 'Programming Language :: Python',
-                                 'Topic :: Software Development',
-                                 'Topic :: Scientific/Engineering',
-                                 'Operating System :: Microsoft :: Windows',
-                                 'Operating System :: POSIX',
-                                 'Operating System :: Unix',
-                                 'Operating System :: MacOS',
-                                 'Programming Language :: Python :: 2',
-                                 'Programming Language :: Python :: 2.6',
-                                 'Programming Language :: Python :: 2.7',
-                                 'Programming Language :: Python :: 3',
-                                 'Programming Language :: Python :: 3.3',
-                                 ],
-                    **extra_setuptools_args)
-
-    if (len(sys.argv) >= 2
-            and ('--help' in sys.argv[1:] or sys.argv[1]
-                 in ('--help-commands', 'egg_info', '--version', 'clean'))):
-
-        # For these actions, NumPy is not required.
-        #
-        # They are required to succeed without Numpy for example when
-        # pip is used to install Scikit when Numpy is not yet present in
-        # the system.
-        try:
-            from setuptools import setup
-        except ImportError:
-            from distutils.core import setup
-
-        metadata['version'] = VERSION
-    else:
-        from numpy.distutils.core import setup
-
-        metadata['configuration'] = configuration
-
-    setup(**metadata)
-
-
-if __name__ == "__main__":
-    setup_package()
+#! /usr/bin/env python
+#
+# Copyright (C) 2007-2009 Cournapeau David <cournape@gmail.com>
+#               2010 Fabian Pedregosa <fabian.pedregosa@inria.fr>
+
+descr = """A set of python modules for machine learning and data mining"""
+
+import sys
+import os
+import shutil
+from distutils.core import Command
+
+if sys.version_info[0] < 3:
+    import __builtin__ as builtins
+else:
+    import builtins
+
+# This is a bit (!) hackish: we are setting a global variable so that the main
+# sklearn __init__ can detect if it is being loaded by the setup routine, to
+# avoid attempting to load components that aren't built yet.
+builtins.__SKLEARN_SETUP__ = True
+
+DISTNAME = 'scikit-learn'
+DESCRIPTION = 'A set of python modules for machine learning and data mining'
+LONG_DESCRIPTION = open('README.rst').read()
+MAINTAINER = 'Andreas Mueller'
+MAINTAINER_EMAIL = 'amueller@ais.uni-bonn.de'
+URL = 'http://scikit-learn.org'
+LICENSE = 'new BSD'
+DOWNLOAD_URL = 'http://sourceforge.net/projects/scikit-learn/files/'
+
+# We can actually import a restricted version of sklearn that
+# does not need the compiled code
+import sklearn
+
+VERSION = sklearn.__version__
+
+###############################################################################
+# Optional setuptools features
+# We need to import setuptools early, if we want setuptools features,
+# as it monkey-patches the 'setup' function
+
+# For some commands, use setuptools
+if len(set(('develop', 'release', 'bdist_egg', 'bdist_rpm',
+           'bdist_wininst', 'install_egg_info', 'build_sphinx',
+           'egg_info', 'easy_install', 'upload',
+           '--single-version-externally-managed',
+            )).intersection(sys.argv)) > 0:
+    import setuptools
+    extra_setuptools_args = dict(
+        zip_safe=False,  # the package can run out of an .egg file
+        include_package_data=True,
+    )
+else:
+    extra_setuptools_args = dict()
+
+###############################################################################
+
+class CleanCommand(Command):
+    description = "Remove build directories, and compiled file in the source tree"
+    user_options = []
+
+    def initialize_options(self):
+        self.cwd = None
+
+    def finalize_options(self):
+        self.cwd = os.getcwd()
+
+    def run(self):
+        assert os.getcwd() == self.cwd, 'Must be in package root: %s' % self.cwd
+        if os.path.exists('build'):
+            shutil.rmtree('build')
+        for dirpath, dirnames, filenames in os.walk('sklearn'):
+            for filename in filenames:
+                if (filename.endswith('.so') or filename.endswith('.pyd')
+                             or filename.endswith('.dll')
+                             or filename.endswith('.pyc')):
+                    os.unlink(os.path.join(dirpath, filename))
+
+
+
+###############################################################################
+def configuration(parent_package='', top_path=None):
+    if os.path.exists('MANIFEST'):
+        os.remove('MANIFEST')
+
+    from numpy.distutils.misc_util import Configuration
+    config = Configuration(None, parent_package, top_path)
+
+    # Avoid non-useful msg:
+    # "Ignoring attempt to set 'name' (from ... "
+    config.set_options(ignore_setup_xxx_py=True,
+                       assume_default_configuration=True,
+                       delegate_options_to_subpackages=True,
+                       quiet=True)
+
+    config.add_subpackage('sklearn')
+
+    return config
+
+
+def setup_package():
+    metadata = dict(name=DISTNAME,
+                    maintainer=MAINTAINER,
+                    maintainer_email=MAINTAINER_EMAIL,
+                    description=DESCRIPTION,
+                    license=LICENSE,
+                    url=URL,
+                    version=VERSION,
+                    download_url=DOWNLOAD_URL,
+                    long_description=LONG_DESCRIPTION,
+                    classifiers=['Intended Audience :: Science/Research',
+                                 'Intended Audience :: Developers',
+                                 'License :: OSI Approved',
+                                 'Programming Language :: C',
+                                 'Programming Language :: Python',
+                                 'Topic :: Software Development',
+                                 'Topic :: Scientific/Engineering',
+                                 'Operating System :: Microsoft :: Windows',
+                                 'Operating System :: POSIX',
+                                 'Operating System :: Unix',
+                                 'Operating System :: MacOS',
+                                 'Programming Language :: Python :: 2',
+                                 'Programming Language :: Python :: 2.6',
+                                 'Programming Language :: Python :: 2.7',
+                                 'Programming Language :: Python :: 3',
+                                 'Programming Language :: Python :: 3.3',
+                                 ],
+                    cmdclass={'clean': CleanCommand},
+                    **extra_setuptools_args)
+
+    if (len(sys.argv) >= 2
+            and ('--help' in sys.argv[1:] or sys.argv[1]
+                 in ('--help-commands', 'egg_info', '--version', 'clean'))):
+
+        # For these actions, NumPy is not required.
+        #
+        # They are required to succeed without Numpy for example when
+        # pip is used to install Scikit when Numpy is not yet present in
+        # the system.
+        try:
+            from setuptools import setup
+        except ImportError:
+            from distutils.core import setup
+
+        metadata['version'] = VERSION
+    else:
+        from numpy.distutils.core import setup
+
+        metadata['configuration'] = configuration
+
+    setup(**metadata)
+
+
+if __name__ == "__main__":
+    setup_package()
diff --git a/sklearn/__init__.py b/sklearn/__init__.py
index 8c2a74926f3ed2e2f291b16535f8963ee33d7670..36821dbf6a314b3b67f983ffa0980c6b77270f11 100644
--- a/sklearn/__init__.py
+++ b/sklearn/__init__.py
@@ -13,7 +13,7 @@ machine-learning as a versatile tool for science and engineering.
 See http://scikit-learn.org for complete documentation.
 """
 import sys
-__version__ = '0.14a1'
+__version__ = '0.14'
 
 try:
     # This variable is injected in the __builtins__ by the build
@@ -31,45 +31,35 @@ else:
     from . import __check_build
     from .base import clone
 
-    try:
-        from numpy.testing import nosetester
-
-        class _NoseTester(nosetester.NoseTester):
-            """ Subclass numpy's NoseTester to add doctests by default
-            """
-
-            def test(self, label='fast', verbose=1, extra_argv=['--exe'],
-                     doctests=True, coverage=False):
-                """Run the full test suite
-
-                Examples
-                --------
-                This will run the test suite and stop at the first failing
-                example
-                >>> from sklearn import test
-                >>> test(extra_argv=['--exe', '-sx']) #doctest: +SKIP
-                """
-                return super(_NoseTester, self).test(label=label,
-                                                     verbose=verbose,
-                                                     extra_argv=extra_argv,
-                                                     doctests=doctests,
-                                                     coverage=coverage)
-
-        try:
-            test = _NoseTester(raise_warnings="release").test
-        except TypeError:
-            # Older versions of numpy do not have a raise_warnings argument
-            test = _NoseTester().test
-        del nosetester
-    except:
-        pass
+    def test(*args, **kwargs):
+        import warnings
+        # Not using a DeprecationWarning, as they are turned off by
+        # default
+        warnings.warn("""sklearn.test() is no longer supported to run the
+scikit-learn test suite.
+
+After installation, you can launch the test suite from outside the
+source directory (you will need to have nosetests installed)::
+
+   $ nosetests --exe sklearn
+
+See the web page http://scikit-learn.org/stable/install.html#testing
+for more information.
+
+This function, `sklearn.test()` does not do anything. It does not run
+the tests and will be removed in release 0.16.
+""", stacklevel=2)
+
+    # The following line is useful so that nosetests doesn't consider
+    # "test" as a test function
+    test.__test__ = False
 
     __all__ = ['cross_validation', 'cluster', 'covariance',
                'datasets', 'decomposition', 'feature_extraction',
                'feature_selection', 'semi_supervised',
                'gaussian_process', 'grid_search', 'hmm', 'lda', 'linear_model',
                'metrics', 'mixture', 'naive_bayes', 'neighbors', 'pipeline',
-               'preprocessing', 'qda', 'svm', 'test', 'clone',
+               'preprocessing', 'qda', 'svm', 'clone',
                'cross_decomposition',
                'isotonic', 'pls']
 
diff --git a/sklearn/cluster/_hierarchical.c b/sklearn/cluster/_hierarchical.c
index f62b8ad1c1100cc8d327e084a689e0b51ead9939..ecf30f0ab2fc08c08d843db311e51d1642f57628 100644
--- a/sklearn/cluster/_hierarchical.c
+++ b/sklearn/cluster/_hierarchical.c
@@ -1,6 +1,18 @@
-/* Generated by Cython 0.17.4 on Thu Jan 10 17:59:48 2013 */
+/* Generated by Cython 0.19.1 on Wed Aug  7 14:16:15 2013 */
 
 #define PY_SSIZE_T_CLEAN
+#ifndef CYTHON_USE_PYLONG_INTERNALS
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#else
+#include "pyconfig.h"
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 1
+#else
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#endif
+#endif
+#endif
 #include "Python.h"
 #ifndef Py_PYTHON_H
     #error Python headers needed to compile C extensions, please install development version of Python.
@@ -116,6 +128,9 @@
 #if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
   #define Py_TPFLAGS_HAVE_NEWBUFFER 0
 #endif
+#if PY_VERSION_HEX < 0x02060000
+  #define Py_TPFLAGS_HAVE_VERSION_TAG 0
+#endif
 #if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
   #define CYTHON_PEP393_ENABLED 1
   #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
@@ -155,6 +170,14 @@
   #define PyBytes_Concat               PyString_Concat
   #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
 #endif
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)
+  #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj)
+#else
+  #define __Pyx_PyBaseString_Check(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj) || \
+                                         PyString_Check(obj) || PyUnicode_Check(obj))
+  #define __Pyx_PyBaseString_CheckExact(obj) (Py_TYPE(obj) == &PyBaseString_Type)
+#endif
 #if PY_VERSION_HEX < 0x02060000
   #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
   #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
@@ -227,6 +250,40 @@
   #define __Pyx_NAMESTR(n) (n)
   #define __Pyx_DOCSTR(n)  (n)
 #endif
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+#ifndef CYTHON_RESTRICT
+  #if defined(__GNUC__)
+    #define CYTHON_RESTRICT __restrict__
+  #elif defined(_MSC_VER)
+    #define CYTHON_RESTRICT __restrict
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_RESTRICT restrict
+  #else
+    #define CYTHON_RESTRICT
+  #endif
+#endif
+#ifdef NAN
+#define __PYX_NAN() ((float) NAN)
+#else
+static CYTHON_INLINE float __PYX_NAN() {
+  /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and
+   a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is
+   a quiet NaN. */
+  float value;
+  memset(&value, 0xFF, sizeof(value));
+  return value;
+}
+#endif
 
 
 #if PY_MAJOR_VERSION >= 3
@@ -251,6 +308,7 @@
 #include <math.h>
 #define __PYX_HAVE__sklearn__cluster___hierarchical
 #define __PYX_HAVE_API__sklearn__cluster___hierarchical
+#include "string.h"
 #include "stdio.h"
 #include "stdlib.h"
 #include "numpy/arrayobject.h"
@@ -263,21 +321,6 @@
 #define CYTHON_WITHOUT_ASSERTIONS
 #endif
 
-
-/* inline attribute */
-#ifndef CYTHON_INLINE
-  #if defined(__GNUC__)
-    #define CYTHON_INLINE __inline__
-  #elif defined(_MSC_VER)
-    #define CYTHON_INLINE __inline
-  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-    #define CYTHON_INLINE inline
-  #else
-    #define CYTHON_INLINE
-  #endif
-#endif
-
-/* unused attribute */
 #ifndef CYTHON_UNUSED
 # if defined(__GNUC__)
 #   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
@@ -291,30 +334,130 @@
 #   define CYTHON_UNUSED
 # endif
 #endif
-
-typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
-
-
-/* Type Conversion Predeclarations */
-
-#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
-#define __Pyx_PyBytes_AsUString(s)   ((unsigned char*) PyBytes_AsString(s))
-
+typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding;
+                const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
+
+#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0
+#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0
+#define __PYX_DEFAULT_STRING_ENCODING ""
+#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString
+#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*);
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length);
+#define __Pyx_PyBytes_FromString        PyBytes_FromString
+#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(char*);
+#if PY_MAJOR_VERSION < 3
+    #define __Pyx_PyStr_FromString        __Pyx_PyBytes_FromString
+    #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#else
+    #define __Pyx_PyStr_FromString        __Pyx_PyUnicode_FromString
+    #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize
+#endif
+#define __Pyx_PyObject_AsUString(s)    ((unsigned char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_FromUString(s)  __Pyx_PyObject_FromString((char*)s)
+#define __Pyx_PyBytes_FromUString(s)   __Pyx_PyBytes_FromString((char*)s)
+#define __Pyx_PyStr_FromUString(s)     __Pyx_PyStr_FromString((char*)s)
+#define __Pyx_PyUnicode_FromUString(s) __Pyx_PyUnicode_FromString((char*)s)
+#if PY_MAJOR_VERSION < 3
+static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)
+{
+    const Py_UNICODE *u_end = u;
+    while (*u_end++) ;
+    return u_end - u - 1;
+}
+#else
+#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen
+#endif
+#define __Pyx_PyUnicode_FromUnicode(u)       PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))
+#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode
+#define __Pyx_PyUnicode_AsUnicode            PyUnicode_AsUnicode
 #define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
 #define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
 static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
 static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
-
 static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
 static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
 static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
-
 #if CYTHON_COMPILING_IN_CPYTHON
 #define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
 #else
 #define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
 #endif
 #define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+static int __Pyx_sys_getdefaultencoding_not_ascii;
+static int __Pyx_init_sys_getdefaultencoding_params() {
+    PyObject* sys = NULL;
+    PyObject* default_encoding = NULL;
+    PyObject* ascii_chars_u = NULL;
+    PyObject* ascii_chars_b = NULL;
+    sys = PyImport_ImportModule("sys");
+    if (sys == NULL) goto bad;
+    default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+    if (default_encoding == NULL) goto bad;
+    if (strcmp(PyBytes_AsString(default_encoding), "ascii") == 0) {
+        __Pyx_sys_getdefaultencoding_not_ascii = 0;
+    } else {
+        const char* default_encoding_c = PyBytes_AS_STRING(default_encoding);
+        char ascii_chars[128];
+        int c;
+        for (c = 0; c < 128; c++) {
+            ascii_chars[c] = c;
+        }
+        __Pyx_sys_getdefaultencoding_not_ascii = 1;
+        ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL);
+        if (ascii_chars_u == NULL) goto bad;
+        ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL);
+        if (ascii_chars_b == NULL || strncmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) {
+            PyErr_Format(
+                PyExc_ValueError,
+                "This module compiled with c_string_encoding=ascii, but default encoding '%s' is not a superset of ascii.",
+                default_encoding_c);
+            goto bad;
+        }
+    }
+    Py_XDECREF(sys);
+    Py_XDECREF(default_encoding);
+    Py_XDECREF(ascii_chars_u);
+    Py_XDECREF(ascii_chars_b);
+    return 0;
+bad:
+    Py_XDECREF(sys);
+    Py_XDECREF(default_encoding);
+    Py_XDECREF(ascii_chars_u);
+    Py_XDECREF(ascii_chars_b);
+    return -1;
+}
+#endif
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL)
+#else
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL)
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+static char* __PYX_DEFAULT_STRING_ENCODING;
+static int __Pyx_init_sys_getdefaultencoding_params() {
+    PyObject* sys = NULL;
+    PyObject* default_encoding = NULL;
+    char* default_encoding_c;
+    sys = PyImport_ImportModule("sys");
+    if (sys == NULL) goto bad;
+    default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+    if (default_encoding == NULL) goto bad;
+    default_encoding_c = PyBytes_AS_STRING(default_encoding);
+    __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c));
+    strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c);
+    Py_DECREF(sys);
+    Py_DECREF(default_encoding);
+    return 0;
+bad:
+    Py_XDECREF(sys);
+    Py_XDECREF(default_encoding);
+    return -1;
+}
+#endif
+#endif
+
 
 #ifdef __GNUC__
   /* Test for GCC > 2.95 */
@@ -329,8 +472,9 @@ static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
   #define likely(x)   (x)
   #define unlikely(x) (x)
 #endif /* __GNUC__ */
-    
+
 static PyObject *__pyx_m;
+static PyObject *__pyx_d;
 static PyObject *__pyx_b;
 static PyObject *__pyx_empty_tuple;
 static PyObject *__pyx_empty_bytes;
@@ -591,27 +735,27 @@ typedef npy_double __pyx_t_5numpy_double_t;
  */
 typedef npy_longdouble __pyx_t_5numpy_longdouble_t;
 
-/* "sklearn/cluster/_hierarchical.pyx":4
- * cimport numpy as np
+/* "sklearn/cluster/_hierarchical.pyx":7
  * cimport cython
+ * 
  * ctypedef np.float64_t DOUBLE             # <<<<<<<<<<<<<<
- * ctypedef np.int_t INT
+ * ctypedef np.npy_intp INTP
  * ctypedef np.int8_t INT8
  */
 typedef __pyx_t_5numpy_float64_t __pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE;
 
-/* "sklearn/cluster/_hierarchical.pyx":5
- * cimport cython
+/* "sklearn/cluster/_hierarchical.pyx":8
+ * 
  * ctypedef np.float64_t DOUBLE
- * ctypedef np.int_t INT             # <<<<<<<<<<<<<<
+ * ctypedef np.npy_intp INTP             # <<<<<<<<<<<<<<
  * ctypedef np.int8_t INT8
  * 
  */
-typedef __pyx_t_5numpy_int_t __pyx_t_7sklearn_7cluster_13_hierarchical_INT;
+typedef npy_intp __pyx_t_7sklearn_7cluster_13_hierarchical_INTP;
 
-/* "sklearn/cluster/_hierarchical.pyx":6
+/* "sklearn/cluster/_hierarchical.pyx":9
  * ctypedef np.float64_t DOUBLE
- * ctypedef np.int_t INT
+ * ctypedef np.npy_intp INTP
  * ctypedef np.int8_t INT8             # <<<<<<<<<<<<<<
  * 
  * np.import_array()
@@ -729,7 +873,22 @@ typedef npy_cdouble __pyx_t_5numpy_complex_t;
 #define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
 #define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
 
-static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) {
+    PyTypeObject* tp = Py_TYPE(obj);
+    if (likely(tp->tp_getattro))
+        return tp->tp_getattro(obj, attr_name);
+#if PY_MAJOR_VERSION < 3
+    if (likely(tp->tp_getattr))
+        return tp->tp_getattr(obj, PyString_AS_STRING(attr_name));
+#endif
+    return PyObject_GetAttr(obj, attr_name);
+}
+#else
+#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n)
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name); /*proto*/
 
 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
     Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
@@ -747,131 +906,77 @@ static CYTHON_INLINE int  __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* o
     __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack);
 static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);
 
-#define __Pyx_BufPtrStrided1d(type, buf, i0, s0) (type)((char*)buf + i0 * s0)
-#define __Pyx_BufPtrStrided2d(type, buf, i0, s0, i1, s1) (type)((char*)buf + i0 * s0 + i1 * s1)
+#define __Pyx_BufPtrCContig1d(type, buf, i0, s0) ((type)buf + i0)
+#define __Pyx_BufPtrCContig2d(type, buf, i0, s0, i1, s1) ((type)((char*)buf + i0 * s0) + i1)
 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
 
-static CYTHON_INLINE PyObject* __Pyx_PyObject_Pop(PyObject* L) {
-#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x02040000
-    if (likely(PyList_CheckExact(L))
-        && likely(PyList_GET_SIZE(L) > (((PyListObject*)L)->allocated >> 1))) {
-        Py_SIZE(L) -= 1;
-        return PyList_GET_ITEM(L, PyList_GET_SIZE(L));
-    }
-#if PY_VERSION_HEX >= 0x02050000
-    else if (Py_TYPE(L) == (&PySet_Type)) {
-        return PySet_Pop(L);
-    }
-#endif
-#endif
-    return PyObject_CallMethod(L, (char*)"pop", NULL);
+static PyObject* __Pyx_PyObject_CallMethodTuple(PyObject* obj, PyObject* method_name, PyObject* args) {
+    PyObject *method, *result = NULL;
+    if (unlikely(!args)) return NULL;
+    method = __Pyx_PyObject_GetAttrStr(obj, method_name);
+    if (unlikely(!method)) goto bad;
+    result = PyObject_Call(method, args, NULL);
+    Py_DECREF(method);
+bad:
+    Py_DECREF(args);
+    return result;
 }
+#define __Pyx_PyObject_CallMethod3(obj, name, arg1, arg2, arg3) \
+    __Pyx_PyObject_CallMethodTuple(obj, name, PyTuple_Pack(3, arg1, arg2, arg3))
+#define __Pyx_PyObject_CallMethod2(obj, name, arg1, arg2) \
+    __Pyx_PyObject_CallMethodTuple(obj, name, PyTuple_Pack(2, arg1, arg2))
+#define __Pyx_PyObject_CallMethod1(obj, name, arg1) \
+    __Pyx_PyObject_CallMethodTuple(obj, name, PyTuple_Pack(1, arg1))
+#define __Pyx_PyObject_CallMethod0(obj, name) \
+    __Pyx_PyObject_CallMethodTuple(obj, name, (Py_INCREF(__pyx_empty_tuple), __pyx_empty_tuple))
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Pop(PyObject* L); /*proto*/
 
-static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
-    PyObject *r;
-    if (!j) return NULL;
-    r = PyObject_GetItem(o, j);
-    Py_DECREF(j);
-    return r;
-}
-#define __Pyx_GetItemInt_List(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
-                                                    __Pyx_GetItemInt_List_Fast(o, i) : \
-                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
-static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i) {
-#if CYTHON_COMPILING_IN_CPYTHON
-    if (likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
-        PyObject *r = PyList_GET_ITEM(o, i);
-        Py_INCREF(r);
-        return r;
-    }
-    else if ((-PyList_GET_SIZE(o) <= i) & (i < 0)) {
-        PyObject *r = PyList_GET_ITEM(o, PyList_GET_SIZE(o) + i);
-        Py_INCREF(r);
-        return r;
-    }
-    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
-#else
-    return PySequence_GetItem(o, i);
-#endif
-}
-#define __Pyx_GetItemInt_Tuple(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
-                                                    __Pyx_GetItemInt_Tuple_Fast(o, i) : \
-                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
-static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i) {
 #if CYTHON_COMPILING_IN_CPYTHON
-    if (likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
-        PyObject *r = PyTuple_GET_ITEM(o, i);
-        Py_INCREF(r);
-        return r;
-    }
-    else if ((-PyTuple_GET_SIZE(o) <= i) & (i < 0)) {
-        PyObject *r = PyTuple_GET_ITEM(o, PyTuple_GET_SIZE(o) + i);
-        Py_INCREF(r);
-        return r;
+static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
+    PyListObject* L = (PyListObject*) list;
+    Py_ssize_t len = Py_SIZE(list);
+    if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) {
+        Py_INCREF(x);
+        PyList_SET_ITEM(list, len, x);
+        Py_SIZE(list) = len+1;
+        return 0;
     }
-    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
-#else
-    return PySequence_GetItem(o, i);
-#endif
+    return PyList_Append(list, x);
 }
-#define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
-                                                    __Pyx_GetItemInt_Fast(o, i) : \
-                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
-static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) {
-#if CYTHON_COMPILING_IN_CPYTHON
-    if (PyList_CheckExact(o)) {
-        Py_ssize_t n = (likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
-        if (likely((n >= 0) & (n < PyList_GET_SIZE(o)))) {
-            PyObject *r = PyList_GET_ITEM(o, n);
-            Py_INCREF(r);
-            return r;
-        }
-    }
-    else if (PyTuple_CheckExact(o)) {
-        Py_ssize_t n = (likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
-        if (likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
-            PyObject *r = PyTuple_GET_ITEM(o, n);
-            Py_INCREF(r);
-            return r;
-        }
-    } else {  /* inlined PySequence_GetItem() */
-        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
-        if (likely(m && m->sq_item)) {
-            if (unlikely(i < 0) && likely(m->sq_length)) {
-                Py_ssize_t l = m->sq_length(o);
-                if (unlikely(l < 0)) return NULL;
-                i += l;
-            }
-            return m->sq_item(o, i);
-        }
-    }
 #else
-    if (PySequence_Check(o)) {
-        return PySequence_GetItem(o, i);
-    }
+#define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
 #endif
-    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
-}
+
+#define __Pyx_GetItemInt(o, i, size, to_py_func, is_list, wraparound, boundscheck) \
+    (((size) <= sizeof(Py_ssize_t)) ? \
+    __Pyx_GetItemInt_Fast(o, i, is_list, wraparound, boundscheck) : \
+    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+#define __Pyx_GetItemInt_List(o, i, size, to_py_func, is_list, wraparound, boundscheck) \
+    (((size) <= sizeof(Py_ssize_t)) ? \
+    __Pyx_GetItemInt_List_Fast(o, i, wraparound, boundscheck) : \
+    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+                                                              int wraparound, int boundscheck);
+#define __Pyx_GetItemInt_Tuple(o, i, size, to_py_func, is_list, wraparound, boundscheck) \
+    (((size) <= sizeof(Py_ssize_t)) ? \
+    __Pyx_GetItemInt_Tuple_Fast(o, i, wraparound, boundscheck) : \
+    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+                                                              int wraparound, int boundscheck);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+                                                     int is_list, int wraparound, int boundscheck);
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name); /*proto*/
 
 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
 
 static void __Pyx_RaiseBufferFallbackError(void); /*proto*/
 
-static CYTHON_INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
-    if (likely(PyList_CheckExact(L))) {
-        if (unlikely(PyList_Append(L, x) < 0)) return NULL;
-        Py_INCREF(Py_None);
-        return Py_None; /* this is just to have an accurate signature */
-    } else {
-        PyObject *r, *m;
-        m = __Pyx_GetAttrString(L, "append");
-        if (!m) return NULL;
-        r = PyObject_CallFunctionObjArgs(m, x, NULL);
-        Py_DECREF(m);
-        return r;
-    }
-}
+#define __Pyx_BufPtrStrided1d(type, buf, i0, s0) (type)((char*)buf + i0 * s0)
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x); /*proto*/
 
 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); /*proto*/
 
@@ -910,7 +1015,11 @@ typedef struct {
 static Py_ssize_t __Pyx_zeros[] = {0, 0, 0, 0, 0, 0, 0, 0};
 static Py_ssize_t __Pyx_minusones[] = {-1, -1, -1, -1, -1, -1, -1, -1};
 
-static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, long level); /*proto*/
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); /*proto*/
+
+static CYTHON_INLINE Py_intptr_t __Pyx_PyInt_from_py_Py_intptr_t(PyObject *);
+
+static CYTHON_INLINE PyObject *__Pyx_PyInt_to_py_Py_intptr_t(Py_intptr_t);
 
 #if CYTHON_CCOMPLEX
   #ifdef __cplusplus
@@ -1080,6 +1189,8 @@ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
 
 /* Module declarations from 'cpython.ref' */
 
+/* Module declarations from 'libc.string' */
+
 /* Module declarations from 'libc.stdio' */
 
 /* Module declarations from 'cpython.object' */
@@ -1105,7 +1216,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, cha
 
 /* Module declarations from 'sklearn.cluster._hierarchical' */
 static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE = { "DOUBLE", NULL, sizeof(__pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE), { 0 }, 0, 'R', 0, 0 };
-static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_INT = { "INT", NULL, sizeof(__pyx_t_7sklearn_7cluster_13_hierarchical_INT), { 0 }, 0, IS_UNSIGNED(__pyx_t_7sklearn_7cluster_13_hierarchical_INT) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_7sklearn_7cluster_13_hierarchical_INT), 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_INTP = { "INTP", NULL, sizeof(__pyx_t_7sklearn_7cluster_13_hierarchical_INTP), { 0 }, 0, IS_UNSIGNED(__pyx_t_7sklearn_7cluster_13_hierarchical_INTP) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_7sklearn_7cluster_13_hierarchical_INTP), 0 };
 static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_INT8 = { "INT8", NULL, sizeof(__pyx_t_7sklearn_7cluster_13_hierarchical_INT8), { 0 }, 0, IS_UNSIGNED(__pyx_t_7sklearn_7cluster_13_hierarchical_INT8) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_7sklearn_7cluster_13_hierarchical_INT8), 0 };
 #define __Pyx_MODULE_NAME "sklearn.cluster._hierarchical"
 int __pyx_module_is_main_sklearn__cluster___hierarchical = 0;
@@ -1115,7 +1226,7 @@ static PyObject *__pyx_builtin_range;
 static PyObject *__pyx_builtin_ValueError;
 static PyObject *__pyx_builtin_RuntimeError;
 static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_compute_ward_dist(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_m_1, PyArrayObject *__pyx_v_m_2, PyArrayObject *__pyx_v_coord_row, PyArrayObject *__pyx_v_coord_col, PyArrayObject *__pyx_v_res); /* proto */
-static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_2_hc_get_descendent(CYTHON_UNUSED PyObject *__pyx_self, int __pyx_v_node, PyObject *__pyx_v_children, int __pyx_v_n_leaves); /* proto */
+static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_2_hc_get_descendent(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_v_node, PyObject *__pyx_v_children, __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_v_n_leaves); /* proto */
 static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_4hc_get_heads(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_parents, PyObject *__pyx_v_copy); /* proto */
 static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_6_get_parents(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_nodes, PyObject *__pyx_v_heads, PyArrayObject *__pyx_v_parents, PyArrayObject *__pyx_v_not_visited); /* proto */
 static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
@@ -1126,7 +1237,7 @@ static char __pyx_k_6[] = "Non-native byte order not supported";
 static char __pyx_k_8[] = "unknown dtype code in numpy.pxd (%d)";
 static char __pyx_k_9[] = "Format string allocated too short, see comment in numpy.pxd";
 static char __pyx_k_12[] = "Format string allocated too short.";
-static char __pyx_k_16[] = "/scratch/apps/src/scikit-learn/sklearn/cluster/_hierarchical.pyx";
+static char __pyx_k_16[] = "/home/lars/src/scikit-learn/sklearn/cluster/_hierarchical.pyx";
 static char __pyx_k_17[] = "sklearn.cluster._hierarchical";
 static char __pyx_k__B[] = "B";
 static char __pyx_k__H[] = "H";
@@ -1153,6 +1264,7 @@ static char __pyx_k__col[] = "col";
 static char __pyx_k__ind[] = "ind";
 static char __pyx_k__m_1[] = "m_1";
 static char __pyx_k__m_2[] = "m_2";
+static char __pyx_k__pop[] = "pop";
 static char __pyx_k__res[] = "res";
 static char __pyx_k__row[] = "row";
 static char __pyx_k__copy[] = "copy";
@@ -1163,6 +1275,7 @@ static char __pyx_k__node0[] = "node0";
 static char __pyx_k__nodes[] = "nodes";
 static char __pyx_k__numpy[] = "numpy";
 static char __pyx_k__range[] = "range";
+static char __pyx_k__append[] = "append";
 static char __pyx_k__extend[] = "extend";
 static char __pyx_k__parent[] = "parent";
 static char __pyx_k__parents[] = "parents";
@@ -1175,14 +1288,17 @@ static char __pyx_k__coord_col[] = "coord_col";
 static char __pyx_k__coord_row[] = "coord_row";
 static char __pyx_k__n_indices[] = "n_indices";
 static char __pyx_k__ValueError[] = "ValueError";
+static char __pyx_k____import__[] = "__import__";
 static char __pyx_k__descendent[] = "descendent";
 static char __pyx_k__n_features[] = "n_features";
 static char __pyx_k__not_visited[] = "not_visited";
 static char __pyx_k__RuntimeError[] = "RuntimeError";
 static char __pyx_k___get_parents[] = "_get_parents";
 static char __pyx_k__hc_get_heads[] = "hc_get_heads";
+static char __pyx_k____pyx_getbuffer[] = "__pyx_getbuffer";
 static char __pyx_k__compute_ward_dist[] = "compute_ward_dist";
 static char __pyx_k___hc_get_descendent[] = "_hc_get_descendent";
+static char __pyx_k____pyx_releasebuffer[] = "__pyx_releasebuffer";
 static PyObject *__pyx_kp_u_12;
 static PyObject *__pyx_kp_s_16;
 static PyObject *__pyx_n_s_17;
@@ -1193,10 +1309,14 @@ static PyObject *__pyx_kp_u_8;
 static PyObject *__pyx_kp_u_9;
 static PyObject *__pyx_n_s__RuntimeError;
 static PyObject *__pyx_n_s__ValueError;
+static PyObject *__pyx_n_s____import__;
 static PyObject *__pyx_n_s____main__;
+static PyObject *__pyx_n_s____pyx_getbuffer;
+static PyObject *__pyx_n_s____pyx_releasebuffer;
 static PyObject *__pyx_n_s____test__;
 static PyObject *__pyx_n_s___get_parents;
 static PyObject *__pyx_n_s___hc_get_descendent;
+static PyObject *__pyx_n_s__append;
 static PyObject *__pyx_n_s__children;
 static PyObject *__pyx_n_s__col;
 static PyObject *__pyx_n_s__compute_ward_dist;
@@ -1225,6 +1345,7 @@ static PyObject *__pyx_n_s__numpy;
 static PyObject *__pyx_n_s__pa;
 static PyObject *__pyx_n_s__parent;
 static PyObject *__pyx_n_s__parents;
+static PyObject *__pyx_n_s__pop;
 static PyObject *__pyx_n_s__range;
 static PyObject *__pyx_n_s__res;
 static PyObject *__pyx_n_s__row;
@@ -1256,6 +1377,9 @@ static PyObject *__pyx_pw_7sklearn_7cluster_13_hierarchical_1compute_ward_dist(P
   PyArrayObject *__pyx_v_coord_row = 0;
   PyArrayObject *__pyx_v_coord_col = 0;
   PyArrayObject *__pyx_v_res = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("compute_ward_dist (wrapper)", 0);
@@ -1282,26 +1406,26 @@ static PyObject *__pyx_pw_7sklearn_7cluster_13_hierarchical_1compute_ward_dist(P
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__m_2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("compute_ward_dist", 1, 5, 5, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("compute_ward_dist", 1, 5, 5, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__coord_row)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("compute_ward_dist", 1, 5, 5, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("compute_ward_dist", 1, 5, 5, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  3:
         if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__coord_col)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("compute_ward_dist", 1, 5, 5, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("compute_ward_dist", 1, 5, 5, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  4:
         if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__res)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("compute_ward_dist", 1, 5, 5, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("compute_ward_dist", 1, 5, 5, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "compute_ward_dist") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "compute_ward_dist") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 5) {
       goto __pyx_L5_argtuple_error;
@@ -1320,17 +1444,17 @@ static PyObject *__pyx_pw_7sklearn_7cluster_13_hierarchical_1compute_ward_dist(P
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("compute_ward_dist", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("compute_ward_dist", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("sklearn.cluster._hierarchical.compute_ward_dist", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_m_1), __pyx_ptype_5numpy_ndarray, 1, "m_1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_m_2), __pyx_ptype_5numpy_ndarray, 1, "m_2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_coord_row), __pyx_ptype_5numpy_ndarray, 1, "coord_row", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_coord_col), __pyx_ptype_5numpy_ndarray, 1, "coord_col", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_res), __pyx_ptype_5numpy_ndarray, 1, "res", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_m_1), __pyx_ptype_5numpy_ndarray, 1, "m_1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_m_2), __pyx_ptype_5numpy_ndarray, 1, "m_2", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_coord_row), __pyx_ptype_5numpy_ndarray, 1, "coord_row", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_coord_col), __pyx_ptype_5numpy_ndarray, 1, "coord_col", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_res), __pyx_ptype_5numpy_ndarray, 1, "res", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_r = __pyx_pf_7sklearn_7cluster_13_hierarchical_compute_ward_dist(__pyx_self, __pyx_v_m_1, __pyx_v_m_2, __pyx_v_coord_row, __pyx_v_coord_col, __pyx_v_res);
   goto __pyx_L0;
   __pyx_L1_error:;
@@ -1340,21 +1464,21 @@ static PyObject *__pyx_pw_7sklearn_7cluster_13_hierarchical_1compute_ward_dist(P
   return __pyx_r;
 }
 
-/* "sklearn/cluster/_hierarchical.pyx":14
+/* "sklearn/cluster/_hierarchical.pyx":17
  * @cython.wraparound(False)
  * @cython.cdivision(True)
- * def compute_ward_dist(np.ndarray[DOUBLE, ndim=1] m_1,\             # <<<<<<<<<<<<<<
- *                     np.ndarray[DOUBLE, ndim=2] m_2,\
- *                     np.ndarray[INT, ndim=1] coord_row,
+ * def compute_ward_dist(np.ndarray[DOUBLE, ndim=1, mode='c'] m_1,             # <<<<<<<<<<<<<<
+ *                       np.ndarray[DOUBLE, ndim=2, mode='c'] m_2,
+ *                       np.ndarray[INTP, ndim=1, mode='c'] coord_row,
  */
 
 static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_compute_ward_dist(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_m_1, PyArrayObject *__pyx_v_m_2, PyArrayObject *__pyx_v_coord_row, PyArrayObject *__pyx_v_coord_col, PyArrayObject *__pyx_v_res) {
-  int __pyx_v_size_max;
-  int __pyx_v_n_features;
-  int __pyx_v_i;
-  int __pyx_v_j;
-  int __pyx_v_row;
-  int __pyx_v_col;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_v_size_max;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_v_n_features;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_v_i;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_v_j;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_v_row;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_v_col;
   __pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE __pyx_v_pa;
   __pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE __pyx_v_n;
   __Pyx_LocalBuf_ND __pyx_pybuffernd_coord_col;
@@ -1369,22 +1493,22 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_compute_ward_dist(CY
   __Pyx_Buffer __pyx_pybuffer_res;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  int __pyx_t_2;
-  int __pyx_t_3;
-  int __pyx_t_4;
-  int __pyx_t_5;
-  int __pyx_t_6;
-  int __pyx_t_7;
-  int __pyx_t_8;
-  int __pyx_t_9;
-  int __pyx_t_10;
-  int __pyx_t_11;
-  int __pyx_t_12;
-  int __pyx_t_13;
-  int __pyx_t_14;
-  int __pyx_t_15;
-  int __pyx_t_16;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_1;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_2;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_3;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_4;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_5;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_6;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_7;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_8;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_9;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_10;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_11;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_12;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_13;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_14;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_15;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_16;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
@@ -1411,51 +1535,51 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_compute_ward_dist(CY
   __pyx_pybuffernd_res.rcbuffer = &__pyx_pybuffer_res;
   {
     __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_m_1.rcbuffer->pybuffer, (PyObject*)__pyx_v_m_1, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_m_1.rcbuffer->pybuffer, (PyObject*)__pyx_v_m_1, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __pyx_pybuffernd_m_1.diminfo[0].strides = __pyx_pybuffernd_m_1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_m_1.diminfo[0].shape = __pyx_pybuffernd_m_1.rcbuffer->pybuffer.shape[0];
   {
     __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_m_2.rcbuffer->pybuffer, (PyObject*)__pyx_v_m_2, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_m_2.rcbuffer->pybuffer, (PyObject*)__pyx_v_m_2, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __pyx_pybuffernd_m_2.diminfo[0].strides = __pyx_pybuffernd_m_2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_m_2.diminfo[0].shape = __pyx_pybuffernd_m_2.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_m_2.diminfo[1].strides = __pyx_pybuffernd_m_2.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_m_2.diminfo[1].shape = __pyx_pybuffernd_m_2.rcbuffer->pybuffer.shape[1];
   {
     __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_coord_row.rcbuffer->pybuffer, (PyObject*)__pyx_v_coord_row, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_INT, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_coord_row.rcbuffer->pybuffer, (PyObject*)__pyx_v_coord_row, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_INTP, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __pyx_pybuffernd_coord_row.diminfo[0].strides = __pyx_pybuffernd_coord_row.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_coord_row.diminfo[0].shape = __pyx_pybuffernd_coord_row.rcbuffer->pybuffer.shape[0];
   {
     __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_coord_col.rcbuffer->pybuffer, (PyObject*)__pyx_v_coord_col, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_INT, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_coord_col.rcbuffer->pybuffer, (PyObject*)__pyx_v_coord_col, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_INTP, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __pyx_pybuffernd_coord_col.diminfo[0].strides = __pyx_pybuffernd_coord_col.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_coord_col.diminfo[0].shape = __pyx_pybuffernd_coord_col.rcbuffer->pybuffer.shape[0];
   {
     __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_res.rcbuffer->pybuffer, (PyObject*)__pyx_v_res, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_res.rcbuffer->pybuffer, (PyObject*)__pyx_v_res, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __pyx_pybuffernd_res.diminfo[0].strides = __pyx_pybuffernd_res.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_res.diminfo[0].shape = __pyx_pybuffernd_res.rcbuffer->pybuffer.shape[0];
 
-  /* "sklearn/cluster/_hierarchical.pyx":19
- *                     np.ndarray[INT, ndim=1] coord_col,\
- *                     np.ndarray[DOUBLE, ndim=1] res):
- *     cdef int size_max = coord_row.shape[0]             # <<<<<<<<<<<<<<
- *     cdef int n_features = m_2.shape[1]
- *     cdef int i, j, row, col
+  /* "sklearn/cluster/_hierarchical.pyx":22
+ *                       np.ndarray[INTP, ndim=1, mode='c'] coord_col,
+ *                       np.ndarray[DOUBLE, ndim=1, mode='c'] res):
+ *     cdef INTP size_max = coord_row.shape[0]             # <<<<<<<<<<<<<<
+ *     cdef INTP n_features = m_2.shape[1]
+ *     cdef INTP i, j, row, col
  */
   __pyx_v_size_max = (__pyx_v_coord_row->dimensions[0]);
 
-  /* "sklearn/cluster/_hierarchical.pyx":20
- *                     np.ndarray[DOUBLE, ndim=1] res):
- *     cdef int size_max = coord_row.shape[0]
- *     cdef int n_features = m_2.shape[1]             # <<<<<<<<<<<<<<
- *     cdef int i, j, row, col
+  /* "sklearn/cluster/_hierarchical.pyx":23
+ *                       np.ndarray[DOUBLE, ndim=1, mode='c'] res):
+ *     cdef INTP size_max = coord_row.shape[0]
+ *     cdef INTP n_features = m_2.shape[1]             # <<<<<<<<<<<<<<
+ *     cdef INTP i, j, row, col
  *     cdef DOUBLE pa, n
  */
   __pyx_v_n_features = (__pyx_v_m_2->dimensions[1]);
 
-  /* "sklearn/cluster/_hierarchical.pyx":23
- *     cdef int i, j, row, col
+  /* "sklearn/cluster/_hierarchical.pyx":27
  *     cdef DOUBLE pa, n
+ * 
  *     for i in range(size_max):             # <<<<<<<<<<<<<<
  *         row = coord_row[i]
  *         col = coord_col[i]
@@ -1464,17 +1588,17 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_compute_ward_dist(CY
   for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
     __pyx_v_i = __pyx_t_2;
 
-    /* "sklearn/cluster/_hierarchical.pyx":24
- *     cdef DOUBLE pa, n
+    /* "sklearn/cluster/_hierarchical.pyx":28
+ * 
  *     for i in range(size_max):
  *         row = coord_row[i]             # <<<<<<<<<<<<<<
  *         col = coord_col[i]
  *         n = (m_1[row] * m_1[col]) / (m_1[row] + m_1[col])
  */
     __pyx_t_3 = __pyx_v_i;
-    __pyx_v_row = (*__Pyx_BufPtrStrided1d(__pyx_t_7sklearn_7cluster_13_hierarchical_INT *, __pyx_pybuffernd_coord_row.rcbuffer->pybuffer.buf, __pyx_t_3, __pyx_pybuffernd_coord_row.diminfo[0].strides));
+    __pyx_v_row = (*__Pyx_BufPtrCContig1d(__pyx_t_7sklearn_7cluster_13_hierarchical_INTP *, __pyx_pybuffernd_coord_row.rcbuffer->pybuffer.buf, __pyx_t_3, __pyx_pybuffernd_coord_row.diminfo[0].strides));
 
-    /* "sklearn/cluster/_hierarchical.pyx":25
+    /* "sklearn/cluster/_hierarchical.pyx":29
  *     for i in range(size_max):
  *         row = coord_row[i]
  *         col = coord_col[i]             # <<<<<<<<<<<<<<
@@ -1482,9 +1606,9 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_compute_ward_dist(CY
  *         pa = 0.
  */
     __pyx_t_4 = __pyx_v_i;
-    __pyx_v_col = (*__Pyx_BufPtrStrided1d(__pyx_t_7sklearn_7cluster_13_hierarchical_INT *, __pyx_pybuffernd_coord_col.rcbuffer->pybuffer.buf, __pyx_t_4, __pyx_pybuffernd_coord_col.diminfo[0].strides));
+    __pyx_v_col = (*__Pyx_BufPtrCContig1d(__pyx_t_7sklearn_7cluster_13_hierarchical_INTP *, __pyx_pybuffernd_coord_col.rcbuffer->pybuffer.buf, __pyx_t_4, __pyx_pybuffernd_coord_col.diminfo[0].strides));
 
-    /* "sklearn/cluster/_hierarchical.pyx":26
+    /* "sklearn/cluster/_hierarchical.pyx":30
  *         row = coord_row[i]
  *         col = coord_col[i]
  *         n = (m_1[row] * m_1[col]) / (m_1[row] + m_1[col])             # <<<<<<<<<<<<<<
@@ -1495,32 +1619,32 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_compute_ward_dist(CY
     __pyx_t_6 = __pyx_v_col;
     __pyx_t_7 = __pyx_v_row;
     __pyx_t_8 = __pyx_v_col;
-    __pyx_v_n = (((*__Pyx_BufPtrStrided1d(__pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE *, __pyx_pybuffernd_m_1.rcbuffer->pybuffer.buf, __pyx_t_5, __pyx_pybuffernd_m_1.diminfo[0].strides)) * (*__Pyx_BufPtrStrided1d(__pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE *, __pyx_pybuffernd_m_1.rcbuffer->pybuffer.buf, __pyx_t_6, __pyx_pybuffernd_m_1.diminfo[0].strides))) / ((*__Pyx_BufPtrStrided1d(__pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE *, __pyx_pybuffernd_m_1.rcbuffer->pybuffer.buf, __pyx_t_7, __pyx_pybuffernd_m_1.diminfo[0].strides)) + (*__Pyx_BufPtrStrided1d(__pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE *, __pyx_pybuffernd_m_1.rcbuffer->pybuffer.buf, __pyx_t_8, __pyx_pybuffernd_m_1.diminfo[0].strides))));
+    __pyx_v_n = (((*__Pyx_BufPtrCContig1d(__pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE *, __pyx_pybuffernd_m_1.rcbuffer->pybuffer.buf, __pyx_t_5, __pyx_pybuffernd_m_1.diminfo[0].strides)) * (*__Pyx_BufPtrCContig1d(__pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE *, __pyx_pybuffernd_m_1.rcbuffer->pybuffer.buf, __pyx_t_6, __pyx_pybuffernd_m_1.diminfo[0].strides))) / ((*__Pyx_BufPtrCContig1d(__pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE *, __pyx_pybuffernd_m_1.rcbuffer->pybuffer.buf, __pyx_t_7, __pyx_pybuffernd_m_1.diminfo[0].strides)) + (*__Pyx_BufPtrCContig1d(__pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE *, __pyx_pybuffernd_m_1.rcbuffer->pybuffer.buf, __pyx_t_8, __pyx_pybuffernd_m_1.diminfo[0].strides))));
 
-    /* "sklearn/cluster/_hierarchical.pyx":27
+    /* "sklearn/cluster/_hierarchical.pyx":31
  *         col = coord_col[i]
  *         n = (m_1[row] * m_1[col]) / (m_1[row] + m_1[col])
  *         pa = 0.             # <<<<<<<<<<<<<<
  *         for j in range(n_features):
- *             pa += (m_2[row, j] / m_1[row] - m_2[col, j] / m_1[col])**2
+ *             pa += (m_2[row, j] / m_1[row] - m_2[col, j] / m_1[col]) ** 2
  */
     __pyx_v_pa = 0.;
 
-    /* "sklearn/cluster/_hierarchical.pyx":28
+    /* "sklearn/cluster/_hierarchical.pyx":32
  *         n = (m_1[row] * m_1[col]) / (m_1[row] + m_1[col])
  *         pa = 0.
  *         for j in range(n_features):             # <<<<<<<<<<<<<<
- *             pa += (m_2[row, j] / m_1[row] - m_2[col, j] / m_1[col])**2
+ *             pa += (m_2[row, j] / m_1[row] - m_2[col, j] / m_1[col]) ** 2
  *         res[i] = pa * n
  */
     __pyx_t_9 = __pyx_v_n_features;
     for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
       __pyx_v_j = __pyx_t_10;
 
-      /* "sklearn/cluster/_hierarchical.pyx":29
+      /* "sklearn/cluster/_hierarchical.pyx":33
  *         pa = 0.
  *         for j in range(n_features):
- *             pa += (m_2[row, j] / m_1[row] - m_2[col, j] / m_1[col])**2             # <<<<<<<<<<<<<<
+ *             pa += (m_2[row, j] / m_1[row] - m_2[col, j] / m_1[col]) ** 2             # <<<<<<<<<<<<<<
  *         res[i] = pa * n
  *     return res
  */
@@ -1530,22 +1654,22 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_compute_ward_dist(CY
       __pyx_t_14 = __pyx_v_col;
       __pyx_t_15 = __pyx_v_j;
       __pyx_t_16 = __pyx_v_col;
-      __pyx_v_pa = (__pyx_v_pa + pow((((*__Pyx_BufPtrStrided2d(__pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE *, __pyx_pybuffernd_m_2.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_m_2.diminfo[0].strides, __pyx_t_12, __pyx_pybuffernd_m_2.diminfo[1].strides)) / (*__Pyx_BufPtrStrided1d(__pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE *, __pyx_pybuffernd_m_1.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_m_1.diminfo[0].strides))) - ((*__Pyx_BufPtrStrided2d(__pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE *, __pyx_pybuffernd_m_2.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_m_2.diminfo[0].strides, __pyx_t_15, __pyx_pybuffernd_m_2.diminfo[1].strides)) / (*__Pyx_BufPtrStrided1d(__pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE *, __pyx_pybuffernd_m_1.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_m_1.diminfo[0].strides)))), 2.0));
+      __pyx_v_pa = (__pyx_v_pa + pow((((*__Pyx_BufPtrCContig2d(__pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE *, __pyx_pybuffernd_m_2.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_m_2.diminfo[0].strides, __pyx_t_12, __pyx_pybuffernd_m_2.diminfo[1].strides)) / (*__Pyx_BufPtrCContig1d(__pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE *, __pyx_pybuffernd_m_1.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_m_1.diminfo[0].strides))) - ((*__Pyx_BufPtrCContig2d(__pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE *, __pyx_pybuffernd_m_2.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_m_2.diminfo[0].strides, __pyx_t_15, __pyx_pybuffernd_m_2.diminfo[1].strides)) / (*__Pyx_BufPtrCContig1d(__pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE *, __pyx_pybuffernd_m_1.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_m_1.diminfo[0].strides)))), 2.0));
     }
 
-    /* "sklearn/cluster/_hierarchical.pyx":30
+    /* "sklearn/cluster/_hierarchical.pyx":34
  *         for j in range(n_features):
- *             pa += (m_2[row, j] / m_1[row] - m_2[col, j] / m_1[col])**2
+ *             pa += (m_2[row, j] / m_1[row] - m_2[col, j] / m_1[col]) ** 2
  *         res[i] = pa * n             # <<<<<<<<<<<<<<
  *     return res
  * 
  */
     __pyx_t_9 = __pyx_v_i;
-    *__Pyx_BufPtrStrided1d(__pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE *, __pyx_pybuffernd_res.rcbuffer->pybuffer.buf, __pyx_t_9, __pyx_pybuffernd_res.diminfo[0].strides) = (__pyx_v_pa * __pyx_v_n);
+    *__Pyx_BufPtrCContig1d(__pyx_t_7sklearn_7cluster_13_hierarchical_DOUBLE *, __pyx_pybuffernd_res.rcbuffer->pybuffer.buf, __pyx_t_9, __pyx_pybuffernd_res.diminfo[0].strides) = (__pyx_v_pa * __pyx_v_n);
   }
 
-  /* "sklearn/cluster/_hierarchical.pyx":31
- *             pa += (m_2[row, j] / m_1[row] - m_2[col, j] / m_1[col])**2
+  /* "sklearn/cluster/_hierarchical.pyx":35
+ *             pa += (m_2[row, j] / m_1[row] - m_2[col, j] / m_1[col]) ** 2
  *         res[i] = pa * n
  *     return res             # <<<<<<<<<<<<<<
  * 
@@ -1584,12 +1708,15 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_compute_ward_dist(CY
 
 /* Python wrapper */
 static PyObject *__pyx_pw_7sklearn_7cluster_13_hierarchical_3_hc_get_descendent(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7sklearn_7cluster_13_hierarchical_2_hc_get_descendent[] = "\n    Function returning all the descendent leaves of a set of nodes in the tree.\n\n    Parameters\n    ----------\n    node : int\n        The node for which we want the descendents.\n\n    children : list of pairs. Length of n_nodes\n        List of the children of each nodes.\n        This is not defined for leaves.\n\n    n_leaves : int\n        Number of leaves.\n\n    Return\n    ------\n    descendent : list of int\n    ";
+static char __pyx_doc_7sklearn_7cluster_13_hierarchical_2_hc_get_descendent[] = "\n    Function returning all the descendent leaves of a set of nodes in the tree.\n\n    Parameters\n    ----------\n    node : integer\n        The node for which we want the descendents.\n\n    children : list of pairs, length n_nodes\n        The children of each non-leaf node. Values less than `n_samples` refer\n        to leaves of the tree. A greater value `i` indicates a node with\n        children `children[i - n_samples]`.\n\n    n_leaves : integer\n        Number of leaves.\n\n    Returns\n    -------\n    descendent : list of int\n    ";
 static PyMethodDef __pyx_mdef_7sklearn_7cluster_13_hierarchical_3_hc_get_descendent = {__Pyx_NAMESTR("_hc_get_descendent"), (PyCFunction)__pyx_pw_7sklearn_7cluster_13_hierarchical_3_hc_get_descendent, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_7sklearn_7cluster_13_hierarchical_2_hc_get_descendent)};
 static PyObject *__pyx_pw_7sklearn_7cluster_13_hierarchical_3_hc_get_descendent(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  int __pyx_v_node;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_v_node;
   PyObject *__pyx_v_children = 0;
-  int __pyx_v_n_leaves;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_v_n_leaves;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_hc_get_descendent (wrapper)", 0);
@@ -1614,16 +1741,16 @@ static PyObject *__pyx_pw_7sklearn_7cluster_13_hierarchical_3_hc_get_descendent(
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__children)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("_hc_get_descendent", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("_hc_get_descendent", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__n_leaves)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("_hc_get_descendent", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("_hc_get_descendent", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_hc_get_descendent") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_hc_get_descendent") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
       goto __pyx_L5_argtuple_error;
@@ -1632,13 +1759,13 @@ static PyObject *__pyx_pw_7sklearn_7cluster_13_hierarchical_3_hc_get_descendent(
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
       values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
     }
-    __pyx_v_node = __Pyx_PyInt_AsInt(values[0]); if (unlikely((__pyx_v_node == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_node = __Pyx_PyInt_from_py_Py_intptr_t(values[0]); if (unlikely((__pyx_v_node == (npy_intp)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     __pyx_v_children = values[1];
-    __pyx_v_n_leaves = __Pyx_PyInt_AsInt(values[2]); if (unlikely((__pyx_v_n_leaves == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_n_leaves = __Pyx_PyInt_from_py_Py_intptr_t(values[2]); if (unlikely((__pyx_v_n_leaves == (npy_intp)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("_hc_get_descendent", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("_hc_get_descendent", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("sklearn.cluster._hierarchical._hc_get_descendent", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -1649,65 +1776,66 @@ static PyObject *__pyx_pw_7sklearn_7cluster_13_hierarchical_3_hc_get_descendent(
   return __pyx_r;
 }
 
-/* "sklearn/cluster/_hierarchical.pyx":34
+/* "sklearn/cluster/_hierarchical.pyx":38
  * 
  * 
- * def _hc_get_descendent(int node, children, int n_leaves):             # <<<<<<<<<<<<<<
+ * def _hc_get_descendent(INTP node, children, INTP n_leaves):             # <<<<<<<<<<<<<<
  *     """
  *     Function returning all the descendent leaves of a set of nodes in the tree.
  */
 
-static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_2_hc_get_descendent(CYTHON_UNUSED PyObject *__pyx_self, int __pyx_v_node, PyObject *__pyx_v_children, int __pyx_v_n_leaves) {
+static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_2_hc_get_descendent(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_v_node, PyObject *__pyx_v_children, __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_v_n_leaves) {
   PyObject *__pyx_v_ind = NULL;
   PyObject *__pyx_v_descendent = NULL;
-  int __pyx_v_n_indices;
-  int __pyx_v_i;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_v_i;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_v_n_indices;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   int __pyx_t_3;
-  int __pyx_t_4;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_4;
   int __pyx_t_5;
-  PyObject *__pyx_t_6 = NULL;
+  int __pyx_t_6;
+  PyObject *__pyx_t_7 = NULL;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_hc_get_descendent", 0);
 
-  /* "sklearn/cluster/_hierarchical.pyx":54
+  /* "sklearn/cluster/_hierarchical.pyx":59
  *     descendent : list of int
  *     """
  *     ind = [node]             # <<<<<<<<<<<<<<
  *     if node < n_leaves:
  *         return ind
  */
-  __pyx_t_1 = PyInt_FromLong(__pyx_v_node); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_PyInt_to_py_Py_intptr_t(__pyx_v_node); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   PyList_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_1);
   __pyx_t_1 = 0;
-  __pyx_v_ind = __pyx_t_2;
+  __pyx_v_ind = ((PyObject*)__pyx_t_2);
   __pyx_t_2 = 0;
 
-  /* "sklearn/cluster/_hierarchical.pyx":55
+  /* "sklearn/cluster/_hierarchical.pyx":60
  *     """
  *     ind = [node]
  *     if node < n_leaves:             # <<<<<<<<<<<<<<
  *         return ind
  *     descendent = []
  */
-  __pyx_t_3 = (__pyx_v_node < __pyx_v_n_leaves);
+  __pyx_t_3 = ((__pyx_v_node < __pyx_v_n_leaves) != 0);
   if (__pyx_t_3) {
 
-    /* "sklearn/cluster/_hierarchical.pyx":56
+    /* "sklearn/cluster/_hierarchical.pyx":61
  *     ind = [node]
  *     if node < n_leaves:
  *         return ind             # <<<<<<<<<<<<<<
  *     descendent = []
- *     # It is actually faster to do the accounting of the number of
+ * 
  */
     __Pyx_XDECREF(__pyx_r);
     __Pyx_INCREF(((PyObject *)__pyx_v_ind));
@@ -1717,73 +1845,74 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_2_hc_get_descendent(
   }
   __pyx_L3:;
 
-  /* "sklearn/cluster/_hierarchical.pyx":57
+  /* "sklearn/cluster/_hierarchical.pyx":62
  *     if node < n_leaves:
  *         return ind
  *     descendent = []             # <<<<<<<<<<<<<<
+ * 
  *     # It is actually faster to do the accounting of the number of
- *     # elements is the list ourselves: len is a lengthy operation on a
  */
-  __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_v_descendent = __pyx_t_2;
+  __pyx_v_descendent = ((PyObject*)__pyx_t_2);
   __pyx_t_2 = 0;
 
-  /* "sklearn/cluster/_hierarchical.pyx":61
+  /* "sklearn/cluster/_hierarchical.pyx":67
  *     # elements is the list ourselves: len is a lengthy operation on a
  *     # chained list
- *     cdef int n_indices = 1             # <<<<<<<<<<<<<<
- *     cdef int i
+ *     cdef INTP i, n_indices = 1             # <<<<<<<<<<<<<<
+ * 
  *     while n_indices:
  */
   __pyx_v_n_indices = 1;
 
-  /* "sklearn/cluster/_hierarchical.pyx":63
- *     cdef int n_indices = 1
- *     cdef int i
+  /* "sklearn/cluster/_hierarchical.pyx":69
+ *     cdef INTP i, n_indices = 1
+ * 
  *     while n_indices:             # <<<<<<<<<<<<<<
  *         i = ind.pop()
  *         if i < n_leaves:
  */
   while (1) {
-    if (!__pyx_v_n_indices) break;
+    __pyx_t_3 = (__pyx_v_n_indices != 0);
+    if (!__pyx_t_3) break;
 
-    /* "sklearn/cluster/_hierarchical.pyx":64
- *     cdef int i
+    /* "sklearn/cluster/_hierarchical.pyx":70
+ * 
  *     while n_indices:
  *         i = ind.pop()             # <<<<<<<<<<<<<<
  *         if i < n_leaves:
  *             descendent.append(i)
  */
-    __pyx_t_2 = __Pyx_PyObject_Pop(((PyObject *)__pyx_v_ind)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_PyObject_Pop(((PyObject *)__pyx_v_ind)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_4 = __Pyx_PyInt_AsInt(__pyx_t_2); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PyInt_from_py_Py_intptr_t(__pyx_t_2); if (unlikely((__pyx_t_4 == (npy_intp)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __pyx_v_i = __pyx_t_4;
 
-    /* "sklearn/cluster/_hierarchical.pyx":65
+    /* "sklearn/cluster/_hierarchical.pyx":71
  *     while n_indices:
  *         i = ind.pop()
  *         if i < n_leaves:             # <<<<<<<<<<<<<<
  *             descendent.append(i)
  *             n_indices -= 1
  */
-    __pyx_t_3 = (__pyx_v_i < __pyx_v_n_leaves);
+    __pyx_t_3 = ((__pyx_v_i < __pyx_v_n_leaves) != 0);
     if (__pyx_t_3) {
 
-      /* "sklearn/cluster/_hierarchical.pyx":66
+      /* "sklearn/cluster/_hierarchical.pyx":72
  *         i = ind.pop()
  *         if i < n_leaves:
  *             descendent.append(i)             # <<<<<<<<<<<<<<
  *             n_indices -= 1
  *         else:
  */
-      __pyx_t_2 = PyInt_FromLong(__pyx_v_i); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_PyInt_to_py_Py_intptr_t(__pyx_v_i); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_5 = PyList_Append(__pyx_v_descendent, __pyx_t_2); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = __Pyx_PyList_Append(__pyx_v_descendent, __pyx_t_2); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "sklearn/cluster/_hierarchical.pyx":67
+      /* "sklearn/cluster/_hierarchical.pyx":73
  *         if i < n_leaves:
  *             descendent.append(i)
  *             n_indices -= 1             # <<<<<<<<<<<<<<
@@ -1795,30 +1924,30 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_2_hc_get_descendent(
     }
     /*else*/ {
 
-      /* "sklearn/cluster/_hierarchical.pyx":69
+      /* "sklearn/cluster/_hierarchical.pyx":75
  *             n_indices -= 1
  *         else:
  *             ind.extend(children[i - n_leaves])             # <<<<<<<<<<<<<<
  *             n_indices += 1
  *     return descendent
  */
-      __pyx_t_2 = PyObject_GetAttr(((PyObject *)__pyx_v_ind), __pyx_n_s__extend); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_ind), __pyx_n_s__extend); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = (__pyx_v_i - __pyx_v_n_leaves);
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_children, __pyx_t_4, sizeof(int), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_6 = (__pyx_v_i - __pyx_v_n_leaves);
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_children, __pyx_t_6, sizeof(int), PyInt_FromLong, 0, 1, 1); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_6);
-      PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1);
+      __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_7);
+      PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_1);
       __Pyx_GIVEREF(__pyx_t_1);
       __pyx_t_1 = 0;
-      __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_7), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
+      __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-      /* "sklearn/cluster/_hierarchical.pyx":70
+      /* "sklearn/cluster/_hierarchical.pyx":76
  *         else:
  *             ind.extend(children[i - n_leaves])
  *             n_indices += 1             # <<<<<<<<<<<<<<
@@ -1830,7 +1959,7 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_2_hc_get_descendent(
     __pyx_L6:;
   }
 
-  /* "sklearn/cluster/_hierarchical.pyx":71
+  /* "sklearn/cluster/_hierarchical.pyx":77
  *             ind.extend(children[i - n_leaves])
  *             n_indices += 1
  *     return descendent             # <<<<<<<<<<<<<<
@@ -1847,7 +1976,7 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_2_hc_get_descendent(
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
   __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
   __Pyx_AddTraceback("sklearn.cluster._hierarchical._hc_get_descendent", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -1860,11 +1989,14 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_2_hc_get_descendent(
 
 /* Python wrapper */
 static PyObject *__pyx_pw_7sklearn_7cluster_13_hierarchical_5hc_get_heads(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7sklearn_7cluster_13_hierarchical_4hc_get_heads[] = " Return the heads of the forest, as defined by parents\n    \n    Parameters\n    ===========\n    parents: array of integers\n        The parent structure defining the forest (ensemble of trees)\n    copy: boolean\n        If copy is False, the input 'parents' array is modified inplace\n\n    Returns\n    =======\n    heads: array of integers of same shape as parents\n        The indices in the 'parents' of the tree heads\n\n    ";
+static char __pyx_doc_7sklearn_7cluster_13_hierarchical_4hc_get_heads[] = "Returns the heads of the forest, as defined by parents.\n\n    Parameters\n    ----------\n    parents : array of integers\n        The parent structure defining the forest (ensemble of trees)\n    copy : boolean\n        If copy is False, the input 'parents' array is modified inplace\n\n    Returns\n    -------\n    heads : array of integers of same shape as parents\n        The indices in the 'parents' of the tree heads\n\n    ";
 static PyMethodDef __pyx_mdef_7sklearn_7cluster_13_hierarchical_5hc_get_heads = {__Pyx_NAMESTR("hc_get_heads"), (PyCFunction)__pyx_pw_7sklearn_7cluster_13_hierarchical_5hc_get_heads, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_7sklearn_7cluster_13_hierarchical_4hc_get_heads)};
 static PyObject *__pyx_pw_7sklearn_7cluster_13_hierarchical_5hc_get_heads(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyArrayObject *__pyx_v_parents = 0;
   PyObject *__pyx_v_copy = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("hc_get_heads (wrapper)", 0);
@@ -1893,7 +2025,7 @@ static PyObject *__pyx_pw_7sklearn_7cluster_13_hierarchical_5hc_get_heads(PyObje
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "hc_get_heads") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "hc_get_heads") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -1908,13 +2040,13 @@ static PyObject *__pyx_pw_7sklearn_7cluster_13_hierarchical_5hc_get_heads(PyObje
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("hc_get_heads", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("hc_get_heads", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("sklearn.cluster._hierarchical.hc_get_heads", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_parents), __pyx_ptype_5numpy_ndarray, 1, "parents", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_parents), __pyx_ptype_5numpy_ndarray, 1, "parents", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_r = __pyx_pf_7sklearn_7cluster_13_hierarchical_4hc_get_heads(__pyx_self, __pyx_v_parents, __pyx_v_copy);
   goto __pyx_L0;
   __pyx_L1_error:;
@@ -1924,19 +2056,19 @@ static PyObject *__pyx_pw_7sklearn_7cluster_13_hierarchical_5hc_get_heads(PyObje
   return __pyx_r;
 }
 
-/* "sklearn/cluster/_hierarchical.pyx":76
+/* "sklearn/cluster/_hierarchical.pyx":82
  * @cython.boundscheck(False)
  * @cython.wraparound(False)
- * def hc_get_heads(np.ndarray[INT, ndim=1] parents, copy=True):             # <<<<<<<<<<<<<<
- *     """ Return the heads of the forest, as defined by parents
+ * def hc_get_heads(np.ndarray[INTP, ndim=1] parents, copy=True):             # <<<<<<<<<<<<<<
+ *     """Returns the heads of the forest, as defined by parents.
  * 
  */
 
 static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_4hc_get_heads(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_parents, PyObject *__pyx_v_copy) {
-  unsigned int __pyx_v_parent;
-  unsigned int __pyx_v_node0;
-  unsigned int __pyx_v_node;
-  unsigned int __pyx_v_size;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_v_parent;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_v_node0;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_v_node;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_v_size;
   __Pyx_LocalBuf_ND __pyx_pybuffernd_parents;
   __Pyx_Buffer __pyx_pybuffer_parents;
   PyObject *__pyx_r = NULL;
@@ -1950,11 +2082,10 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_4hc_get_heads(CYTHON
   PyObject *__pyx_t_7 = NULL;
   PyObject *__pyx_t_8 = NULL;
   PyObject *__pyx_t_9 = NULL;
-  unsigned int __pyx_t_10;
-  unsigned int __pyx_t_11;
-  unsigned int __pyx_t_12;
-  unsigned int __pyx_t_13;
-  unsigned int __pyx_t_14;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_10;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_11;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_12;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_13;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
@@ -1966,50 +2097,50 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_4hc_get_heads(CYTHON
   __pyx_pybuffernd_parents.rcbuffer = &__pyx_pybuffer_parents;
   {
     __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_parents.rcbuffer->pybuffer, (PyObject*)__pyx_v_parents, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_INT, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_parents.rcbuffer->pybuffer, (PyObject*)__pyx_v_parents, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_INTP, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __pyx_pybuffernd_parents.diminfo[0].strides = __pyx_pybuffernd_parents.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_parents.diminfo[0].shape = __pyx_pybuffernd_parents.rcbuffer->pybuffer.shape[0];
 
-  /* "sklearn/cluster/_hierarchical.pyx":93
+  /* "sklearn/cluster/_hierarchical.pyx":99
  *     """
- *     cdef unsigned int parent, node0, node, size
+ *     cdef INTP parent, node0, node, size
  *     if copy:             # <<<<<<<<<<<<<<
  *         parents = np.copy(parents)
  *     size = parents.size
  */
-  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_copy); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_copy); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   if (__pyx_t_1) {
 
-    /* "sklearn/cluster/_hierarchical.pyx":94
- *     cdef unsigned int parent, node0, node, size
+    /* "sklearn/cluster/_hierarchical.pyx":100
+ *     cdef INTP parent, node0, node, size
  *     if copy:
  *         parents = np.copy(parents)             # <<<<<<<<<<<<<<
  *     size = parents.size
- *     for node0 in range(size):
+ * 
  */
-    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s__np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__copy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s__copy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_INCREF(((PyObject *)__pyx_v_parents));
     PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_v_parents));
     __Pyx_GIVEREF(((PyObject *)__pyx_v_parents));
-    __pyx_t_4 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-    if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __pyx_t_5 = ((PyArrayObject *)__pyx_t_4);
     {
       __Pyx_BufFmt_StackElem __pyx_stack[1];
       __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_parents.rcbuffer->pybuffer);
-      __pyx_t_6 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_parents.rcbuffer->pybuffer, (PyObject*)__pyx_t_5, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_INT, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack);
+      __pyx_t_6 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_parents.rcbuffer->pybuffer, (PyObject*)__pyx_t_5, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_INTP, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack);
       if (unlikely(__pyx_t_6 < 0)) {
         PyErr_Fetch(&__pyx_t_7, &__pyx_t_8, &__pyx_t_9);
-        if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_parents.rcbuffer->pybuffer, (PyObject*)__pyx_v_parents, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_INT, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {
+        if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_parents.rcbuffer->pybuffer, (PyObject*)__pyx_v_parents, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_INTP, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {
           Py_XDECREF(__pyx_t_7); Py_XDECREF(__pyx_t_8); Py_XDECREF(__pyx_t_9);
           __Pyx_RaiseBufferFallbackError();
         } else {
@@ -2017,7 +2148,7 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_4hc_get_heads(CYTHON
         }
       }
       __pyx_pybuffernd_parents.diminfo[0].strides = __pyx_pybuffernd_parents.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_parents.diminfo[0].shape = __pyx_pybuffernd_parents.rcbuffer->pybuffer.shape[0];
-      if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
     __pyx_t_5 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_v_parents));
@@ -2027,59 +2158,49 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_4hc_get_heads(CYTHON
   }
   __pyx_L3:;
 
-  /* "sklearn/cluster/_hierarchical.pyx":95
+  /* "sklearn/cluster/_hierarchical.pyx":101
  *     if copy:
  *         parents = np.copy(parents)
  *     size = parents.size             # <<<<<<<<<<<<<<
- *     for node0 in range(size):
- *         # Start from the top of the tree and go down
+ * 
+ *     # Start from the top of the tree and go down
  */
-  __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_v_parents), __pyx_n_s__size); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_parents), __pyx_n_s__size); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_10 = __Pyx_PyInt_AsUnsignedInt(__pyx_t_4); if (unlikely((__pyx_t_10 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_10 = __Pyx_PyInt_from_py_Py_intptr_t(__pyx_t_4); if (unlikely((__pyx_t_10 == (npy_intp)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_v_size = __pyx_t_10;
 
-  /* "sklearn/cluster/_hierarchical.pyx":96
- *         parents = np.copy(parents)
- *     size = parents.size
- *     for node0 in range(size):             # <<<<<<<<<<<<<<
- *         # Start from the top of the tree and go down
- *         node0 = size - node0 - 1
- */
-  __pyx_t_10 = __pyx_v_size;
-  for (__pyx_t_11 = 0; __pyx_t_11 < __pyx_t_10; __pyx_t_11+=1) {
-    __pyx_v_node0 = __pyx_t_11;
-
-    /* "sklearn/cluster/_hierarchical.pyx":98
- *     for node0 in range(size):
- *         # Start from the top of the tree and go down
- *         node0 = size - node0 - 1             # <<<<<<<<<<<<<<
+  /* "sklearn/cluster/_hierarchical.pyx":104
+ * 
+ *     # Start from the top of the tree and go down
+ *     for node0 in range(size - 1, -1, -1):             # <<<<<<<<<<<<<<
  *         node = node0
  *         parent = parents[node]
  */
-    __pyx_v_node0 = ((__pyx_v_size - __pyx_v_node0) - 1);
+  for (__pyx_t_10 = (__pyx_v_size - 1); __pyx_t_10 > -1; __pyx_t_10-=1) {
+    __pyx_v_node0 = __pyx_t_10;
 
-    /* "sklearn/cluster/_hierarchical.pyx":99
- *         # Start from the top of the tree and go down
- *         node0 = size - node0 - 1
+    /* "sklearn/cluster/_hierarchical.pyx":105
+ *     # Start from the top of the tree and go down
+ *     for node0 in range(size - 1, -1, -1):
  *         node = node0             # <<<<<<<<<<<<<<
  *         parent = parents[node]
  *         while parent != node:
  */
     __pyx_v_node = __pyx_v_node0;
 
-    /* "sklearn/cluster/_hierarchical.pyx":100
- *         node0 = size - node0 - 1
+    /* "sklearn/cluster/_hierarchical.pyx":106
+ *     for node0 in range(size - 1, -1, -1):
  *         node = node0
  *         parent = parents[node]             # <<<<<<<<<<<<<<
  *         while parent != node:
  *             parents[node0] = parent
  */
-    __pyx_t_12 = __pyx_v_node;
-    __pyx_v_parent = (*__Pyx_BufPtrStrided1d(__pyx_t_7sklearn_7cluster_13_hierarchical_INT *, __pyx_pybuffernd_parents.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_parents.diminfo[0].strides));
+    __pyx_t_11 = __pyx_v_node;
+    __pyx_v_parent = (*__Pyx_BufPtrStrided1d(__pyx_t_7sklearn_7cluster_13_hierarchical_INTP *, __pyx_pybuffernd_parents.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_parents.diminfo[0].strides));
 
-    /* "sklearn/cluster/_hierarchical.pyx":101
+    /* "sklearn/cluster/_hierarchical.pyx":107
  *         node = node0
  *         parent = parents[node]
  *         while parent != node:             # <<<<<<<<<<<<<<
@@ -2087,20 +2208,20 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_4hc_get_heads(CYTHON
  *             node = parent
  */
     while (1) {
-      __pyx_t_1 = (__pyx_v_parent != __pyx_v_node);
+      __pyx_t_1 = ((__pyx_v_parent != __pyx_v_node) != 0);
       if (!__pyx_t_1) break;
 
-      /* "sklearn/cluster/_hierarchical.pyx":102
+      /* "sklearn/cluster/_hierarchical.pyx":108
  *         parent = parents[node]
  *         while parent != node:
  *             parents[node0] = parent             # <<<<<<<<<<<<<<
  *             node = parent
  *             parent = parents[node]
  */
-      __pyx_t_13 = __pyx_v_node0;
-      *__Pyx_BufPtrStrided1d(__pyx_t_7sklearn_7cluster_13_hierarchical_INT *, __pyx_pybuffernd_parents.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_parents.diminfo[0].strides) = __pyx_v_parent;
+      __pyx_t_12 = __pyx_v_node0;
+      *__Pyx_BufPtrStrided1d(__pyx_t_7sklearn_7cluster_13_hierarchical_INTP *, __pyx_pybuffernd_parents.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_parents.diminfo[0].strides) = __pyx_v_parent;
 
-      /* "sklearn/cluster/_hierarchical.pyx":103
+      /* "sklearn/cluster/_hierarchical.pyx":109
  *         while parent != node:
  *             parents[node0] = parent
  *             node = parent             # <<<<<<<<<<<<<<
@@ -2109,19 +2230,19 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_4hc_get_heads(CYTHON
  */
       __pyx_v_node = __pyx_v_parent;
 
-      /* "sklearn/cluster/_hierarchical.pyx":104
+      /* "sklearn/cluster/_hierarchical.pyx":110
  *             parents[node0] = parent
  *             node = parent
  *             parent = parents[node]             # <<<<<<<<<<<<<<
  *     return parents
  * 
  */
-      __pyx_t_14 = __pyx_v_node;
-      __pyx_v_parent = (*__Pyx_BufPtrStrided1d(__pyx_t_7sklearn_7cluster_13_hierarchical_INT *, __pyx_pybuffernd_parents.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_parents.diminfo[0].strides));
+      __pyx_t_13 = __pyx_v_node;
+      __pyx_v_parent = (*__Pyx_BufPtrStrided1d(__pyx_t_7sklearn_7cluster_13_hierarchical_INTP *, __pyx_pybuffernd_parents.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_parents.diminfo[0].strides));
     }
   }
 
-  /* "sklearn/cluster/_hierarchical.pyx":105
+  /* "sklearn/cluster/_hierarchical.pyx":111
  *             node = parent
  *             parent = parents[node]
  *     return parents             # <<<<<<<<<<<<<<
@@ -2157,13 +2278,16 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_4hc_get_heads(CYTHON
 
 /* Python wrapper */
 static PyObject *__pyx_pw_7sklearn_7cluster_13_hierarchical_7_get_parents(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_7sklearn_7cluster_13_hierarchical_6_get_parents[] = " Return the heads of the given nodes, as defined by parents\n    \n    Modifies in-place 'heads' and 'not_visited'\n\n    Parameters\n    ===========\n    nodes: list of integers\n        The nodes to start from\n    heads: list of integers\n        A list to hold the results (modified inplace)\n    parents: array of integers\n        The parent structure defining the tree\n    not_visited:\n        The tree nodes to consider (modified inplace)\n\n    ";
+static char __pyx_doc_7sklearn_7cluster_13_hierarchical_6_get_parents[] = "Returns the heads of the given nodes, as defined by parents.\n\n    Modifies 'heads' and 'not_visited' in-place.\n\n    Parameters\n    ----------\n    nodes : list of integers\n        The nodes to start from\n    heads : list of integers\n        A list to hold the results (modified inplace)\n    parents : array of integers\n        The parent structure defining the tree\n    not_visited\n        The tree nodes to consider (modified inplace)\n\n    ";
 static PyMethodDef __pyx_mdef_7sklearn_7cluster_13_hierarchical_7_get_parents = {__Pyx_NAMESTR("_get_parents"), (PyCFunction)__pyx_pw_7sklearn_7cluster_13_hierarchical_7_get_parents, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_7sklearn_7cluster_13_hierarchical_6_get_parents)};
 static PyObject *__pyx_pw_7sklearn_7cluster_13_hierarchical_7_get_parents(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_nodes = 0;
   PyObject *__pyx_v_heads = 0;
   PyArrayObject *__pyx_v_parents = 0;
   PyArrayObject *__pyx_v_not_visited = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_get_parents (wrapper)", 0);
@@ -2189,21 +2313,21 @@ static PyObject *__pyx_pw_7sklearn_7cluster_13_hierarchical_7_get_parents(PyObje
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__heads)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("_get_parents", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("_get_parents", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__parents)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("_get_parents", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("_get_parents", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  3:
         if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__not_visited)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("_get_parents", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("_get_parents", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_get_parents") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_get_parents") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
       goto __pyx_L5_argtuple_error;
@@ -2220,14 +2344,14 @@ static PyObject *__pyx_pw_7sklearn_7cluster_13_hierarchical_7_get_parents(PyObje
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("_get_parents", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("_get_parents", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("sklearn.cluster._hierarchical._get_parents", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_parents), __pyx_ptype_5numpy_ndarray, 1, "parents", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_not_visited), __pyx_ptype_5numpy_ndarray, 1, "not_visited", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_parents), __pyx_ptype_5numpy_ndarray, 1, "parents", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_not_visited), __pyx_ptype_5numpy_ndarray, 1, "not_visited", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_r = __pyx_pf_7sklearn_7cluster_13_hierarchical_6_get_parents(__pyx_self, __pyx_v_nodes, __pyx_v_heads, __pyx_v_parents, __pyx_v_not_visited);
   goto __pyx_L0;
   __pyx_L1_error:;
@@ -2237,17 +2361,17 @@ static PyObject *__pyx_pw_7sklearn_7cluster_13_hierarchical_7_get_parents(PyObje
   return __pyx_r;
 }
 
-/* "sklearn/cluster/_hierarchical.pyx":110
+/* "sklearn/cluster/_hierarchical.pyx":116
  * @cython.boundscheck(False)
  * @cython.wraparound(False)
- * def _get_parents(nodes, heads, np.ndarray[INT, ndim=1] parents,             # <<<<<<<<<<<<<<
- *                  np.ndarray[INT8, ndim=1] not_visited):
- *     """ Return the heads of the given nodes, as defined by parents
+ * def _get_parents(nodes, heads, np.ndarray[INTP, ndim=1] parents,             # <<<<<<<<<<<<<<
+ *                  np.ndarray[INT8, ndim=1, mode='c'] not_visited):
+ *     """Returns the heads of the given nodes, as defined by parents.
  */
 
 static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_6_get_parents(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_nodes, PyObject *__pyx_v_heads, PyArrayObject *__pyx_v_parents, PyArrayObject *__pyx_v_not_visited) {
-  unsigned int __pyx_v_parent;
-  unsigned int __pyx_v_node;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_v_parent;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_v_node;
   __Pyx_LocalBuf_ND __pyx_pybuffernd_not_visited;
   __Pyx_Buffer __pyx_pybuffer_not_visited;
   __Pyx_LocalBuf_ND __pyx_pybuffernd_parents;
@@ -2258,13 +2382,12 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_6_get_parents(CYTHON
   Py_ssize_t __pyx_t_2;
   PyObject *(*__pyx_t_3)(PyObject *);
   PyObject *__pyx_t_4 = NULL;
-  unsigned int __pyx_t_5;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_5;
   int __pyx_t_6;
-  unsigned int __pyx_t_7;
-  unsigned int __pyx_t_8;
-  __pyx_t_7sklearn_7cluster_13_hierarchical_INT8 __pyx_t_9;
-  unsigned int __pyx_t_10;
-  PyObject *__pyx_t_11 = NULL;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_7;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_8;
+  __pyx_t_7sklearn_7cluster_13_hierarchical_INTP __pyx_t_9;
+  PyObject *__pyx_t_10 = NULL;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
@@ -2279,18 +2402,18 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_6_get_parents(CYTHON
   __pyx_pybuffernd_not_visited.rcbuffer = &__pyx_pybuffer_not_visited;
   {
     __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_parents.rcbuffer->pybuffer, (PyObject*)__pyx_v_parents, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_INT, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_parents.rcbuffer->pybuffer, (PyObject*)__pyx_v_parents, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_INTP, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __pyx_pybuffernd_parents.diminfo[0].strides = __pyx_pybuffernd_parents.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_parents.diminfo[0].shape = __pyx_pybuffernd_parents.rcbuffer->pybuffer.shape[0];
   {
     __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_not_visited.rcbuffer->pybuffer, (PyObject*)__pyx_v_not_visited, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_INT8, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_not_visited.rcbuffer->pybuffer, (PyObject*)__pyx_v_not_visited, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_7cluster_13_hierarchical_INT8, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __pyx_pybuffernd_not_visited.diminfo[0].strides = __pyx_pybuffernd_not_visited.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_not_visited.diminfo[0].shape = __pyx_pybuffernd_not_visited.rcbuffer->pybuffer.shape[0];
 
-  /* "sklearn/cluster/_hierarchical.pyx":129
- *     """
- *     cdef unsigned int parent, node
+  /* "sklearn/cluster/_hierarchical.pyx":136
+ *     cdef INTP parent, node
+ * 
  *     for node in nodes:             # <<<<<<<<<<<<<<
  *         parent = parents[node]
  *         while parent != node:
@@ -2299,7 +2422,7 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_6_get_parents(CYTHON
     __pyx_t_1 = __pyx_v_nodes; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_3 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_nodes); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_nodes); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext;
   }
@@ -2307,43 +2430,43 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_6_get_parents(CYTHON
     if (!__pyx_t_3 && PyList_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else if (!__pyx_t_3 && PyTuple_CheckExact(__pyx_t_1)) {
       if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
       #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       #endif
     } else {
       __pyx_t_4 = __pyx_t_3(__pyx_t_1);
       if (unlikely(!__pyx_t_4)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
       __Pyx_GOTREF(__pyx_t_4);
     }
-    __pyx_t_5 = __Pyx_PyInt_AsUnsignedInt(__pyx_t_4); if (unlikely((__pyx_t_5 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = __Pyx_PyInt_from_py_Py_intptr_t(__pyx_t_4); if (unlikely((__pyx_t_5 == (npy_intp)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __pyx_v_node = __pyx_t_5;
 
-    /* "sklearn/cluster/_hierarchical.pyx":130
- *     cdef unsigned int parent, node
+    /* "sklearn/cluster/_hierarchical.pyx":137
+ * 
  *     for node in nodes:
  *         parent = parents[node]             # <<<<<<<<<<<<<<
  *         while parent != node:
  *             node = parent
  */
     __pyx_t_5 = __pyx_v_node;
-    __pyx_v_parent = (*__Pyx_BufPtrStrided1d(__pyx_t_7sklearn_7cluster_13_hierarchical_INT *, __pyx_pybuffernd_parents.rcbuffer->pybuffer.buf, __pyx_t_5, __pyx_pybuffernd_parents.diminfo[0].strides));
+    __pyx_v_parent = (*__Pyx_BufPtrStrided1d(__pyx_t_7sklearn_7cluster_13_hierarchical_INTP *, __pyx_pybuffernd_parents.rcbuffer->pybuffer.buf, __pyx_t_5, __pyx_pybuffernd_parents.diminfo[0].strides));
 
-    /* "sklearn/cluster/_hierarchical.pyx":131
+    /* "sklearn/cluster/_hierarchical.pyx":138
  *     for node in nodes:
  *         parent = parents[node]
  *         while parent != node:             # <<<<<<<<<<<<<<
@@ -2351,10 +2474,10 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_6_get_parents(CYTHON
  *             parent = parents[node]
  */
     while (1) {
-      __pyx_t_6 = (__pyx_v_parent != __pyx_v_node);
+      __pyx_t_6 = ((__pyx_v_parent != __pyx_v_node) != 0);
       if (!__pyx_t_6) break;
 
-      /* "sklearn/cluster/_hierarchical.pyx":132
+      /* "sklearn/cluster/_hierarchical.pyx":139
  *         parent = parents[node]
  *         while parent != node:
  *             node = parent             # <<<<<<<<<<<<<<
@@ -2363,7 +2486,7 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_6_get_parents(CYTHON
  */
       __pyx_v_node = __pyx_v_parent;
 
-      /* "sklearn/cluster/_hierarchical.pyx":133
+      /* "sklearn/cluster/_hierarchical.pyx":140
  *         while parent != node:
  *             node = parent
  *             parent = parents[node]             # <<<<<<<<<<<<<<
@@ -2371,10 +2494,10 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_6_get_parents(CYTHON
  *             not_visited[node] = 0
  */
       __pyx_t_7 = __pyx_v_node;
-      __pyx_v_parent = (*__Pyx_BufPtrStrided1d(__pyx_t_7sklearn_7cluster_13_hierarchical_INT *, __pyx_pybuffernd_parents.rcbuffer->pybuffer.buf, __pyx_t_7, __pyx_pybuffernd_parents.diminfo[0].strides));
+      __pyx_v_parent = (*__Pyx_BufPtrStrided1d(__pyx_t_7sklearn_7cluster_13_hierarchical_INTP *, __pyx_pybuffernd_parents.rcbuffer->pybuffer.buf, __pyx_t_7, __pyx_pybuffernd_parents.diminfo[0].strides));
     }
 
-    /* "sklearn/cluster/_hierarchical.pyx":134
+    /* "sklearn/cluster/_hierarchical.pyx":141
  *             node = parent
  *             parent = parents[node]
  *         if not_visited[node]:             # <<<<<<<<<<<<<<
@@ -2382,38 +2505,38 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_6_get_parents(CYTHON
  *             heads.append(node)
  */
     __pyx_t_8 = __pyx_v_node;
-    __pyx_t_9 = (*__Pyx_BufPtrStrided1d(__pyx_t_7sklearn_7cluster_13_hierarchical_INT8 *, __pyx_pybuffernd_not_visited.rcbuffer->pybuffer.buf, __pyx_t_8, __pyx_pybuffernd_not_visited.diminfo[0].strides));
-    if (__pyx_t_9) {
+    __pyx_t_6 = ((*__Pyx_BufPtrCContig1d(__pyx_t_7sklearn_7cluster_13_hierarchical_INT8 *, __pyx_pybuffernd_not_visited.rcbuffer->pybuffer.buf, __pyx_t_8, __pyx_pybuffernd_not_visited.diminfo[0].strides)) != 0);
+    if (__pyx_t_6) {
 
-      /* "sklearn/cluster/_hierarchical.pyx":135
+      /* "sklearn/cluster/_hierarchical.pyx":142
  *             parent = parents[node]
  *         if not_visited[node]:
  *             not_visited[node] = 0             # <<<<<<<<<<<<<<
  *             heads.append(node)
  *     return heads
  */
-      __pyx_t_10 = __pyx_v_node;
-      *__Pyx_BufPtrStrided1d(__pyx_t_7sklearn_7cluster_13_hierarchical_INT8 *, __pyx_pybuffernd_not_visited.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_not_visited.diminfo[0].strides) = 0;
+      __pyx_t_9 = __pyx_v_node;
+      *__Pyx_BufPtrCContig1d(__pyx_t_7sklearn_7cluster_13_hierarchical_INT8 *, __pyx_pybuffernd_not_visited.rcbuffer->pybuffer.buf, __pyx_t_9, __pyx_pybuffernd_not_visited.diminfo[0].strides) = 0;
 
-      /* "sklearn/cluster/_hierarchical.pyx":136
+      /* "sklearn/cluster/_hierarchical.pyx":143
  *         if not_visited[node]:
  *             not_visited[node] = 0
  *             heads.append(node)             # <<<<<<<<<<<<<<
  *     return heads
  */
-      __pyx_t_4 = PyLong_FromUnsignedLong(__pyx_v_node); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_4 = __Pyx_PyInt_to_py_Py_intptr_t(__pyx_v_node); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_11 = __Pyx_PyObject_Append(__pyx_v_heads, __pyx_t_4); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_11);
+      __pyx_t_10 = __Pyx_PyObject_Append(__pyx_v_heads, __pyx_t_4); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
       goto __pyx_L7;
     }
     __pyx_L7:;
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "sklearn/cluster/_hierarchical.pyx":137
+  /* "sklearn/cluster/_hierarchical.pyx":144
  *             not_visited[node] = 0
  *             heads.append(node)
  *     return heads             # <<<<<<<<<<<<<<
@@ -2428,7 +2551,7 @@ static PyObject *__pyx_pf_7sklearn_7cluster_13_hierarchical_6_get_parents(CYTHON
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_11);
+  __Pyx_XDECREF(__pyx_t_10);
   { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
     __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
     __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_not_visited.rcbuffer->pybuffer);
@@ -2462,7 +2585,7 @@ static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx
  *         # -- the details of this may change.
  *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
  *             # This implementation of getbuffer is geared towards Cython
- *             # requirements, and does not yet fulfill the PEP.
+ *             # requirements, and does not yet fullfill the PEP.
  */
 
 static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
@@ -2503,7 +2626,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  * 
  *             cdef int copy_shape, i, ndim
  */
-  __pyx_t_1 = (__pyx_v_info == NULL);
+  __pyx_t_1 = ((__pyx_v_info == NULL) != 0);
   if (__pyx_t_1) {
     __pyx_r = 0;
     goto __pyx_L0;
@@ -2545,7 +2668,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  *                 copy_shape = 1
  *             else:
  */
-  __pyx_t_1 = ((sizeof(npy_intp)) != (sizeof(Py_ssize_t)));
+  __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
   if (__pyx_t_1) {
 
     /* "numpy.pxd":209
@@ -2578,7 +2701,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
  *                 raise ValueError(u"ndarray is not C contiguous")
  */
-  __pyx_t_1 = ((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS);
+  __pyx_t_1 = (((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) != 0);
   if (__pyx_t_1) {
 
     /* "numpy.pxd":214
@@ -2588,7 +2711,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  *                 raise ValueError(u"ndarray is not C contiguous")
  * 
  */
-    __pyx_t_2 = (!PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS));
+    __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS) != 0)) != 0);
     __pyx_t_3 = __pyx_t_2;
   } else {
     __pyx_t_3 = __pyx_t_1;
@@ -2618,7 +2741,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
  *                 raise ValueError(u"ndarray is not Fortran contiguous")
  */
-  __pyx_t_3 = ((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS);
+  __pyx_t_3 = (((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) != 0);
   if (__pyx_t_3) {
 
     /* "numpy.pxd":218
@@ -2628,7 +2751,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  *                 raise ValueError(u"ndarray is not Fortran contiguous")
  * 
  */
-    __pyx_t_1 = (!PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS));
+    __pyx_t_1 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS) != 0)) != 0);
     __pyx_t_2 = __pyx_t_1;
   } else {
     __pyx_t_2 = __pyx_t_3;
@@ -2676,7 +2799,8 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  *                 # Allocate new buffer for strides and shape info.
  *                 # This is allocated as one block, strides first.
  */
-  if (__pyx_v_copy_shape) {
+  __pyx_t_2 = (__pyx_v_copy_shape != 0);
+  if (__pyx_t_2) {
 
     /* "numpy.pxd":226
  *                 # Allocate new buffer for strides and shape info.
@@ -2774,7 +2898,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  * 
  *             cdef int t
  */
-  __pyx_v_info->readonly = (!PyArray_ISWRITEABLE(__pyx_v_self));
+  __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0));
 
   /* "numpy.pxd":239
  * 
@@ -2813,9 +2937,9 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  *                 # do not call releasebuffer
  *                 info.obj = None
  */
-  __pyx_t_2 = (!__pyx_v_hasfields);
+  __pyx_t_2 = ((!(__pyx_v_hasfields != 0)) != 0);
   if (__pyx_t_2) {
-    __pyx_t_3 = (!__pyx_v_copy_shape);
+    __pyx_t_3 = ((!(__pyx_v_copy_shape != 0)) != 0);
     __pyx_t_1 = __pyx_t_3;
   } else {
     __pyx_t_1 = __pyx_t_2;
@@ -2860,7 +2984,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  *                 t = descr.type_num
  *                 if ((descr.byteorder == c'>' and little_endian) or
  */
-  __pyx_t_1 = (!__pyx_v_hasfields);
+  __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0);
   if (__pyx_t_1) {
 
     /* "numpy.pxd":254
@@ -2880,9 +3004,9 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  *                     (descr.byteorder == c'<' and not little_endian)):
  *                     raise ValueError(u"Non-native byte order not supported")
  */
-    __pyx_t_1 = (__pyx_v_descr->byteorder == '>');
+    __pyx_t_1 = ((__pyx_v_descr->byteorder == '>') != 0);
     if (__pyx_t_1) {
-      __pyx_t_2 = __pyx_v_little_endian;
+      __pyx_t_2 = (__pyx_v_little_endian != 0);
     } else {
       __pyx_t_2 = __pyx_t_1;
     }
@@ -2895,9 +3019,9 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
  *                     raise ValueError(u"Non-native byte order not supported")
  *                 if   t == NPY_BYTE:        f = "b"
  */
-      __pyx_t_1 = (__pyx_v_descr->byteorder == '<');
+      __pyx_t_1 = ((__pyx_v_descr->byteorder == '<') != 0);
       if (__pyx_t_1) {
-        __pyx_t_3 = (!__pyx_v_little_endian);
+        __pyx_t_3 = ((!(__pyx_v_little_endian != 0)) != 0);
         __pyx_t_7 = __pyx_t_3;
       } else {
         __pyx_t_7 = __pyx_t_1;
@@ -2924,227 +3048,202 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
     }
     __pyx_L12:;
 
-    /* "numpy.pxd":258
+    /* "numpy.pxd":274
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+    switch (__pyx_v_t) {
+
+      /* "numpy.pxd":258
  *                     (descr.byteorder == c'<' and not little_endian)):
  *                     raise ValueError(u"Non-native byte order not supported")
  *                 if   t == NPY_BYTE:        f = "b"             # <<<<<<<<<<<<<<
  *                 elif t == NPY_UBYTE:       f = "B"
  *                 elif t == NPY_SHORT:       f = "h"
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_BYTE);
-    if (__pyx_t_1) {
+      case NPY_BYTE:
       __pyx_v_f = __pyx_k__b;
-      goto __pyx_L13;
-    }
+      break;
 
-    /* "numpy.pxd":259
+      /* "numpy.pxd":259
  *                     raise ValueError(u"Non-native byte order not supported")
  *                 if   t == NPY_BYTE:        f = "b"
  *                 elif t == NPY_UBYTE:       f = "B"             # <<<<<<<<<<<<<<
  *                 elif t == NPY_SHORT:       f = "h"
  *                 elif t == NPY_USHORT:      f = "H"
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_UBYTE);
-    if (__pyx_t_1) {
+      case NPY_UBYTE:
       __pyx_v_f = __pyx_k__B;
-      goto __pyx_L13;
-    }
+      break;
 
-    /* "numpy.pxd":260
+      /* "numpy.pxd":260
  *                 if   t == NPY_BYTE:        f = "b"
  *                 elif t == NPY_UBYTE:       f = "B"
  *                 elif t == NPY_SHORT:       f = "h"             # <<<<<<<<<<<<<<
  *                 elif t == NPY_USHORT:      f = "H"
  *                 elif t == NPY_INT:         f = "i"
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_SHORT);
-    if (__pyx_t_1) {
+      case NPY_SHORT:
       __pyx_v_f = __pyx_k__h;
-      goto __pyx_L13;
-    }
+      break;
 
-    /* "numpy.pxd":261
+      /* "numpy.pxd":261
  *                 elif t == NPY_UBYTE:       f = "B"
  *                 elif t == NPY_SHORT:       f = "h"
  *                 elif t == NPY_USHORT:      f = "H"             # <<<<<<<<<<<<<<
  *                 elif t == NPY_INT:         f = "i"
  *                 elif t == NPY_UINT:        f = "I"
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_USHORT);
-    if (__pyx_t_1) {
+      case NPY_USHORT:
       __pyx_v_f = __pyx_k__H;
-      goto __pyx_L13;
-    }
+      break;
 
-    /* "numpy.pxd":262
+      /* "numpy.pxd":262
  *                 elif t == NPY_SHORT:       f = "h"
  *                 elif t == NPY_USHORT:      f = "H"
  *                 elif t == NPY_INT:         f = "i"             # <<<<<<<<<<<<<<
  *                 elif t == NPY_UINT:        f = "I"
  *                 elif t == NPY_LONG:        f = "l"
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_INT);
-    if (__pyx_t_1) {
+      case NPY_INT:
       __pyx_v_f = __pyx_k__i;
-      goto __pyx_L13;
-    }
+      break;
 
-    /* "numpy.pxd":263
+      /* "numpy.pxd":263
  *                 elif t == NPY_USHORT:      f = "H"
  *                 elif t == NPY_INT:         f = "i"
  *                 elif t == NPY_UINT:        f = "I"             # <<<<<<<<<<<<<<
  *                 elif t == NPY_LONG:        f = "l"
  *                 elif t == NPY_ULONG:       f = "L"
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_UINT);
-    if (__pyx_t_1) {
+      case NPY_UINT:
       __pyx_v_f = __pyx_k__I;
-      goto __pyx_L13;
-    }
+      break;
 
-    /* "numpy.pxd":264
+      /* "numpy.pxd":264
  *                 elif t == NPY_INT:         f = "i"
  *                 elif t == NPY_UINT:        f = "I"
  *                 elif t == NPY_LONG:        f = "l"             # <<<<<<<<<<<<<<
  *                 elif t == NPY_ULONG:       f = "L"
  *                 elif t == NPY_LONGLONG:    f = "q"
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_LONG);
-    if (__pyx_t_1) {
+      case NPY_LONG:
       __pyx_v_f = __pyx_k__l;
-      goto __pyx_L13;
-    }
+      break;
 
-    /* "numpy.pxd":265
+      /* "numpy.pxd":265
  *                 elif t == NPY_UINT:        f = "I"
  *                 elif t == NPY_LONG:        f = "l"
  *                 elif t == NPY_ULONG:       f = "L"             # <<<<<<<<<<<<<<
  *                 elif t == NPY_LONGLONG:    f = "q"
  *                 elif t == NPY_ULONGLONG:   f = "Q"
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_ULONG);
-    if (__pyx_t_1) {
+      case NPY_ULONG:
       __pyx_v_f = __pyx_k__L;
-      goto __pyx_L13;
-    }
+      break;
 
-    /* "numpy.pxd":266
+      /* "numpy.pxd":266
  *                 elif t == NPY_LONG:        f = "l"
  *                 elif t == NPY_ULONG:       f = "L"
  *                 elif t == NPY_LONGLONG:    f = "q"             # <<<<<<<<<<<<<<
  *                 elif t == NPY_ULONGLONG:   f = "Q"
  *                 elif t == NPY_FLOAT:       f = "f"
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_LONGLONG);
-    if (__pyx_t_1) {
+      case NPY_LONGLONG:
       __pyx_v_f = __pyx_k__q;
-      goto __pyx_L13;
-    }
+      break;
 
-    /* "numpy.pxd":267
+      /* "numpy.pxd":267
  *                 elif t == NPY_ULONG:       f = "L"
  *                 elif t == NPY_LONGLONG:    f = "q"
  *                 elif t == NPY_ULONGLONG:   f = "Q"             # <<<<<<<<<<<<<<
  *                 elif t == NPY_FLOAT:       f = "f"
  *                 elif t == NPY_DOUBLE:      f = "d"
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_ULONGLONG);
-    if (__pyx_t_1) {
+      case NPY_ULONGLONG:
       __pyx_v_f = __pyx_k__Q;
-      goto __pyx_L13;
-    }
+      break;
 
-    /* "numpy.pxd":268
+      /* "numpy.pxd":268
  *                 elif t == NPY_LONGLONG:    f = "q"
  *                 elif t == NPY_ULONGLONG:   f = "Q"
  *                 elif t == NPY_FLOAT:       f = "f"             # <<<<<<<<<<<<<<
  *                 elif t == NPY_DOUBLE:      f = "d"
  *                 elif t == NPY_LONGDOUBLE:  f = "g"
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_FLOAT);
-    if (__pyx_t_1) {
+      case NPY_FLOAT:
       __pyx_v_f = __pyx_k__f;
-      goto __pyx_L13;
-    }
+      break;
 
-    /* "numpy.pxd":269
+      /* "numpy.pxd":269
  *                 elif t == NPY_ULONGLONG:   f = "Q"
  *                 elif t == NPY_FLOAT:       f = "f"
  *                 elif t == NPY_DOUBLE:      f = "d"             # <<<<<<<<<<<<<<
  *                 elif t == NPY_LONGDOUBLE:  f = "g"
  *                 elif t == NPY_CFLOAT:      f = "Zf"
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_DOUBLE);
-    if (__pyx_t_1) {
+      case NPY_DOUBLE:
       __pyx_v_f = __pyx_k__d;
-      goto __pyx_L13;
-    }
+      break;
 
-    /* "numpy.pxd":270
+      /* "numpy.pxd":270
  *                 elif t == NPY_FLOAT:       f = "f"
  *                 elif t == NPY_DOUBLE:      f = "d"
  *                 elif t == NPY_LONGDOUBLE:  f = "g"             # <<<<<<<<<<<<<<
  *                 elif t == NPY_CFLOAT:      f = "Zf"
  *                 elif t == NPY_CDOUBLE:     f = "Zd"
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_LONGDOUBLE);
-    if (__pyx_t_1) {
+      case NPY_LONGDOUBLE:
       __pyx_v_f = __pyx_k__g;
-      goto __pyx_L13;
-    }
+      break;
 
-    /* "numpy.pxd":271
+      /* "numpy.pxd":271
  *                 elif t == NPY_DOUBLE:      f = "d"
  *                 elif t == NPY_LONGDOUBLE:  f = "g"
  *                 elif t == NPY_CFLOAT:      f = "Zf"             # <<<<<<<<<<<<<<
  *                 elif t == NPY_CDOUBLE:     f = "Zd"
  *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_CFLOAT);
-    if (__pyx_t_1) {
+      case NPY_CFLOAT:
       __pyx_v_f = __pyx_k__Zf;
-      goto __pyx_L13;
-    }
+      break;
 
-    /* "numpy.pxd":272
+      /* "numpy.pxd":272
  *                 elif t == NPY_LONGDOUBLE:  f = "g"
  *                 elif t == NPY_CFLOAT:      f = "Zf"
  *                 elif t == NPY_CDOUBLE:     f = "Zd"             # <<<<<<<<<<<<<<
  *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
  *                 elif t == NPY_OBJECT:      f = "O"
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_CDOUBLE);
-    if (__pyx_t_1) {
+      case NPY_CDOUBLE:
       __pyx_v_f = __pyx_k__Zd;
-      goto __pyx_L13;
-    }
+      break;
 
-    /* "numpy.pxd":273
+      /* "numpy.pxd":273
  *                 elif t == NPY_CFLOAT:      f = "Zf"
  *                 elif t == NPY_CDOUBLE:     f = "Zd"
  *                 elif t == NPY_CLONGDOUBLE: f = "Zg"             # <<<<<<<<<<<<<<
  *                 elif t == NPY_OBJECT:      f = "O"
  *                 else:
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_CLONGDOUBLE);
-    if (__pyx_t_1) {
+      case NPY_CLONGDOUBLE:
       __pyx_v_f = __pyx_k__Zg;
-      goto __pyx_L13;
-    }
+      break;
 
-    /* "numpy.pxd":274
+      /* "numpy.pxd":274
  *                 elif t == NPY_CDOUBLE:     f = "Zd"
  *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
  *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
  *                 else:
  *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_OBJECT);
-    if (__pyx_t_1) {
+      case NPY_OBJECT:
       __pyx_v_f = __pyx_k__O;
-      goto __pyx_L13;
-    }
-    /*else*/ {
+      break;
+      default:
 
       /* "numpy.pxd":276
  *                 elif t == NPY_OBJECT:      f = "O"
@@ -3169,8 +3268,8 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P
       __Pyx_Raise(__pyx_t_8, 0, 0, 0);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      break;
     }
-    __pyx_L13:;
 
     /* "numpy.pxd":277
  *                 else:
@@ -3294,7 +3393,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
  *                 stdlib.free(info.format)
  *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
  */
-  __pyx_t_1 = PyArray_HASFIELDS(__pyx_v_self);
+  __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0);
   if (__pyx_t_1) {
 
     /* "numpy.pxd":290
@@ -3316,7 +3415,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s
  *                 stdlib.free(info.strides)
  *                 # info.shape was stored after info.strides in the same block
  */
-  __pyx_t_1 = ((sizeof(npy_intp)) != (sizeof(Py_ssize_t)));
+  __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
   if (__pyx_t_1) {
 
     /* "numpy.pxd":292
@@ -3665,7 +3764,9 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
       __Pyx_INCREF(__pyx_t_4);
       #else
       __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
       __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
       #endif
     } else if (1) {
       __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
@@ -3745,9 +3846,9 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  *             (child.byteorder == c'<' and not little_endian)):
  *             raise ValueError(u"Non-native byte order not supported")
  */
-    __pyx_t_7 = (__pyx_v_child->byteorder == '>');
+    __pyx_t_7 = ((__pyx_v_child->byteorder == '>') != 0);
     if (__pyx_t_7) {
-      __pyx_t_8 = __pyx_v_little_endian;
+      __pyx_t_8 = (__pyx_v_little_endian != 0);
     } else {
       __pyx_t_8 = __pyx_t_7;
     }
@@ -3760,9 +3861,9 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  *             raise ValueError(u"Non-native byte order not supported")
  *             # One could encode it in the format string and have Cython
  */
-      __pyx_t_7 = (__pyx_v_child->byteorder == '<');
+      __pyx_t_7 = ((__pyx_v_child->byteorder == '<') != 0);
       if (__pyx_t_7) {
-        __pyx_t_9 = (!__pyx_v_little_endian);
+        __pyx_t_9 = ((!(__pyx_v_little_endian != 0)) != 0);
         __pyx_t_10 = __pyx_t_9;
       } else {
         __pyx_t_10 = __pyx_t_7;
@@ -3851,7 +3952,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  *             t = child.type_num
  *             if end - f < 5:
  */
-    __pyx_t_7 = (!PyDataType_HASFIELDS(__pyx_v_child));
+    __pyx_t_7 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0);
     if (__pyx_t_7) {
 
       /* "numpy.pxd":821
@@ -3874,7 +3975,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx
  *                 raise RuntimeError(u"Format string allocated too short.")
  * 
  */
-      __pyx_t_7 = ((__pyx_v_end - __pyx_v_f) < 5);
+      __pyx_t_7 = (((__pyx_v_end - __pyx_v_f) < 5) != 0);
       if (__pyx_t_7) {
 
         /* "numpy.pxd":823
@@ -4296,6 +4397,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
   PyObject *__pyx_v_baseptr;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
+  int __pyx_t_2;
   __Pyx_RefNannySetupContext("set_array_base", 0);
 
   /* "numpy.pxd":967
@@ -4306,7 +4408,8 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a
  *      else:
  */
   __pyx_t_1 = (__pyx_v_base == Py_None);
-  if (__pyx_t_1) {
+  __pyx_t_2 = (__pyx_t_1 != 0);
+  if (__pyx_t_2) {
 
     /* "numpy.pxd":968
  *      cdef PyObject* baseptr
@@ -4382,7 +4485,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py
  *         return None
  *     else:
  */
-  __pyx_t_1 = (__pyx_v_arr->base == NULL);
+  __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0);
   if (__pyx_t_1) {
 
     /* "numpy.pxd":977
@@ -4425,7 +4528,11 @@ static PyMethodDef __pyx_methods[] = {
 
 #if PY_MAJOR_VERSION >= 3
 static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
     PyModuleDef_HEAD_INIT,
+  #endif
     __Pyx_NAMESTR("_hierarchical"),
     0, /* m_doc */
     -1, /* m_size */
@@ -4448,10 +4555,14 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_kp_u_9, __pyx_k_9, sizeof(__pyx_k_9), 0, 1, 0, 0},
   {&__pyx_n_s__RuntimeError, __pyx_k__RuntimeError, sizeof(__pyx_k__RuntimeError), 0, 0, 1, 1},
   {&__pyx_n_s__ValueError, __pyx_k__ValueError, sizeof(__pyx_k__ValueError), 0, 0, 1, 1},
+  {&__pyx_n_s____import__, __pyx_k____import__, sizeof(__pyx_k____import__), 0, 0, 1, 1},
   {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
+  {&__pyx_n_s____pyx_getbuffer, __pyx_k____pyx_getbuffer, sizeof(__pyx_k____pyx_getbuffer), 0, 0, 1, 1},
+  {&__pyx_n_s____pyx_releasebuffer, __pyx_k____pyx_releasebuffer, sizeof(__pyx_k____pyx_releasebuffer), 0, 0, 1, 1},
   {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
   {&__pyx_n_s___get_parents, __pyx_k___get_parents, sizeof(__pyx_k___get_parents), 0, 0, 1, 1},
   {&__pyx_n_s___hc_get_descendent, __pyx_k___hc_get_descendent, sizeof(__pyx_k___hc_get_descendent), 0, 0, 1, 1},
+  {&__pyx_n_s__append, __pyx_k__append, sizeof(__pyx_k__append), 0, 0, 1, 1},
   {&__pyx_n_s__children, __pyx_k__children, sizeof(__pyx_k__children), 0, 0, 1, 1},
   {&__pyx_n_s__col, __pyx_k__col, sizeof(__pyx_k__col), 0, 0, 1, 1},
   {&__pyx_n_s__compute_ward_dist, __pyx_k__compute_ward_dist, sizeof(__pyx_k__compute_ward_dist), 0, 0, 1, 1},
@@ -4480,6 +4591,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s__pa, __pyx_k__pa, sizeof(__pyx_k__pa), 0, 0, 1, 1},
   {&__pyx_n_s__parent, __pyx_k__parent, sizeof(__pyx_k__parent), 0, 0, 1, 1},
   {&__pyx_n_s__parents, __pyx_k__parents, sizeof(__pyx_k__parents), 0, 0, 1, 1},
+  {&__pyx_n_s__pop, __pyx_k__pop, sizeof(__pyx_k__pop), 0, 0, 1, 1},
   {&__pyx_n_s__range, __pyx_k__range, sizeof(__pyx_k__range), 0, 0, 1, 1},
   {&__pyx_n_s__res, __pyx_k__res, sizeof(__pyx_k__res), 0, 0, 1, 1},
   {&__pyx_n_s__row, __pyx_k__row, sizeof(__pyx_k__row), 0, 0, 1, 1},
@@ -4488,9 +4600,9 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {0, 0, 0, 0, 0, 0, 0}
 };
 static int __Pyx_InitCachedBuiltins(void) {
-  __pyx_builtin_range = __Pyx_GetName(__pyx_b, __pyx_n_s__range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_builtin_ValueError = __Pyx_GetName(__pyx_b, __pyx_n_s__ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_builtin_RuntimeError = __Pyx_GetName(__pyx_b, __pyx_n_s__RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s__range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s__ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s__RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   return 0;
   __pyx_L1_error:;
   return -1;
@@ -4507,11 +4619,8 @@ static int __Pyx_InitCachedConstants(void) {
  * 
  *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
  */
-  __pyx_k_tuple_3 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_3 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_u_2)); if (unlikely(!__pyx_k_tuple_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_3);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_u_2));
-  PyTuple_SET_ITEM(__pyx_k_tuple_3, 0, ((PyObject *)__pyx_kp_u_2));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_u_2));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_3));
 
   /* "numpy.pxd":219
@@ -4521,11 +4630,8 @@ static int __Pyx_InitCachedConstants(void) {
  * 
  *             info.buf = PyArray_DATA(self)
  */
-  __pyx_k_tuple_5 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_5 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_u_4)); if (unlikely(!__pyx_k_tuple_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_5);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_u_4));
-  PyTuple_SET_ITEM(__pyx_k_tuple_5, 0, ((PyObject *)__pyx_kp_u_4));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_u_4));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_5));
 
   /* "numpy.pxd":257
@@ -4535,11 +4641,8 @@ static int __Pyx_InitCachedConstants(void) {
  *                 if   t == NPY_BYTE:        f = "b"
  *                 elif t == NPY_UBYTE:       f = "B"
  */
-  __pyx_k_tuple_7 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_7 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_u_6)); if (unlikely(!__pyx_k_tuple_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_7);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_u_6));
-  PyTuple_SET_ITEM(__pyx_k_tuple_7, 0, ((PyObject *)__pyx_kp_u_6));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_u_6));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_7));
 
   /* "numpy.pxd":799
@@ -4549,11 +4652,8 @@ static int __Pyx_InitCachedConstants(void) {
  * 
  *         if ((child.byteorder == c'>' and little_endian) or
  */
-  __pyx_k_tuple_10 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_10)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_10 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_u_9)); if (unlikely(!__pyx_k_tuple_10)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_10);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_u_9));
-  PyTuple_SET_ITEM(__pyx_k_tuple_10, 0, ((PyObject *)__pyx_kp_u_9));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_u_9));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_10));
 
   /* "numpy.pxd":803
@@ -4563,11 +4663,8 @@ static int __Pyx_InitCachedConstants(void) {
  *             # One could encode it in the format string and have Cython
  *             # complain instead, BUT: < and > in format strings also imply
  */
-  __pyx_k_tuple_11 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_11)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_11 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_u_6)); if (unlikely(!__pyx_k_tuple_11)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_11);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_u_6));
-  PyTuple_SET_ITEM(__pyx_k_tuple_11, 0, ((PyObject *)__pyx_kp_u_6));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_u_6));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_11));
 
   /* "numpy.pxd":823
@@ -4577,156 +4674,57 @@ static int __Pyx_InitCachedConstants(void) {
  * 
  *             # Until ticket #99 is fixed, use integers to avoid warnings
  */
-  __pyx_k_tuple_13 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_13)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_13 = PyTuple_Pack(1, ((PyObject *)__pyx_kp_u_12)); if (unlikely(!__pyx_k_tuple_13)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_13);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_u_12));
-  PyTuple_SET_ITEM(__pyx_k_tuple_13, 0, ((PyObject *)__pyx_kp_u_12));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_u_12));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_13));
 
-  /* "sklearn/cluster/_hierarchical.pyx":14
+  /* "sklearn/cluster/_hierarchical.pyx":17
  * @cython.wraparound(False)
  * @cython.cdivision(True)
- * def compute_ward_dist(np.ndarray[DOUBLE, ndim=1] m_1,\             # <<<<<<<<<<<<<<
- *                     np.ndarray[DOUBLE, ndim=2] m_2,\
- *                     np.ndarray[INT, ndim=1] coord_row,
+ * def compute_ward_dist(np.ndarray[DOUBLE, ndim=1, mode='c'] m_1,             # <<<<<<<<<<<<<<
+ *                       np.ndarray[DOUBLE, ndim=2, mode='c'] m_2,
+ *                       np.ndarray[INTP, ndim=1, mode='c'] coord_row,
  */
-  __pyx_k_tuple_14 = PyTuple_New(13); if (unlikely(!__pyx_k_tuple_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_14 = PyTuple_Pack(13, ((PyObject *)__pyx_n_s__m_1), ((PyObject *)__pyx_n_s__m_2), ((PyObject *)__pyx_n_s__coord_row), ((PyObject *)__pyx_n_s__coord_col), ((PyObject *)__pyx_n_s__res), ((PyObject *)__pyx_n_s__size_max), ((PyObject *)__pyx_n_s__n_features), ((PyObject *)__pyx_n_s__i), ((PyObject *)__pyx_n_s__j), ((PyObject *)__pyx_n_s__row), ((PyObject *)__pyx_n_s__col), ((PyObject *)__pyx_n_s__pa), ((PyObject *)__pyx_n_s__n)); if (unlikely(!__pyx_k_tuple_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_14);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__m_1));
-  PyTuple_SET_ITEM(__pyx_k_tuple_14, 0, ((PyObject *)__pyx_n_s__m_1));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__m_1));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__m_2));
-  PyTuple_SET_ITEM(__pyx_k_tuple_14, 1, ((PyObject *)__pyx_n_s__m_2));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__m_2));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__coord_row));
-  PyTuple_SET_ITEM(__pyx_k_tuple_14, 2, ((PyObject *)__pyx_n_s__coord_row));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__coord_row));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__coord_col));
-  PyTuple_SET_ITEM(__pyx_k_tuple_14, 3, ((PyObject *)__pyx_n_s__coord_col));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__coord_col));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__res));
-  PyTuple_SET_ITEM(__pyx_k_tuple_14, 4, ((PyObject *)__pyx_n_s__res));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__res));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__size_max));
-  PyTuple_SET_ITEM(__pyx_k_tuple_14, 5, ((PyObject *)__pyx_n_s__size_max));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__size_max));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__n_features));
-  PyTuple_SET_ITEM(__pyx_k_tuple_14, 6, ((PyObject *)__pyx_n_s__n_features));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__n_features));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__i));
-  PyTuple_SET_ITEM(__pyx_k_tuple_14, 7, ((PyObject *)__pyx_n_s__i));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__i));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__j));
-  PyTuple_SET_ITEM(__pyx_k_tuple_14, 8, ((PyObject *)__pyx_n_s__j));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__j));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__row));
-  PyTuple_SET_ITEM(__pyx_k_tuple_14, 9, ((PyObject *)__pyx_n_s__row));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__row));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__col));
-  PyTuple_SET_ITEM(__pyx_k_tuple_14, 10, ((PyObject *)__pyx_n_s__col));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__col));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__pa));
-  PyTuple_SET_ITEM(__pyx_k_tuple_14, 11, ((PyObject *)__pyx_n_s__pa));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__pa));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__n));
-  PyTuple_SET_ITEM(__pyx_k_tuple_14, 12, ((PyObject *)__pyx_n_s__n));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__n));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_14));
-  __pyx_k_codeobj_15 = (PyObject*)__Pyx_PyCode_New(5, 0, 13, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_14, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_16, __pyx_n_s__compute_ward_dist, 14, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_codeobj_15 = (PyObject*)__Pyx_PyCode_New(5, 0, 13, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_14, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_16, __pyx_n_s__compute_ward_dist, 17, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "sklearn/cluster/_hierarchical.pyx":34
+  /* "sklearn/cluster/_hierarchical.pyx":38
  * 
  * 
- * def _hc_get_descendent(int node, children, int n_leaves):             # <<<<<<<<<<<<<<
+ * def _hc_get_descendent(INTP node, children, INTP n_leaves):             # <<<<<<<<<<<<<<
  *     """
  *     Function returning all the descendent leaves of a set of nodes in the tree.
  */
-  __pyx_k_tuple_18 = PyTuple_New(7); if (unlikely(!__pyx_k_tuple_18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_18 = PyTuple_Pack(7, ((PyObject *)__pyx_n_s__node), ((PyObject *)__pyx_n_s__children), ((PyObject *)__pyx_n_s__n_leaves), ((PyObject *)__pyx_n_s__ind), ((PyObject *)__pyx_n_s__descendent), ((PyObject *)__pyx_n_s__i), ((PyObject *)__pyx_n_s__n_indices)); if (unlikely(!__pyx_k_tuple_18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_18);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__node));
-  PyTuple_SET_ITEM(__pyx_k_tuple_18, 0, ((PyObject *)__pyx_n_s__node));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__node));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__children));
-  PyTuple_SET_ITEM(__pyx_k_tuple_18, 1, ((PyObject *)__pyx_n_s__children));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__children));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__n_leaves));
-  PyTuple_SET_ITEM(__pyx_k_tuple_18, 2, ((PyObject *)__pyx_n_s__n_leaves));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__n_leaves));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__ind));
-  PyTuple_SET_ITEM(__pyx_k_tuple_18, 3, ((PyObject *)__pyx_n_s__ind));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__ind));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__descendent));
-  PyTuple_SET_ITEM(__pyx_k_tuple_18, 4, ((PyObject *)__pyx_n_s__descendent));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__descendent));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__n_indices));
-  PyTuple_SET_ITEM(__pyx_k_tuple_18, 5, ((PyObject *)__pyx_n_s__n_indices));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__n_indices));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__i));
-  PyTuple_SET_ITEM(__pyx_k_tuple_18, 6, ((PyObject *)__pyx_n_s__i));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__i));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_18));
-  __pyx_k_codeobj_19 = (PyObject*)__Pyx_PyCode_New(3, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_18, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_16, __pyx_n_s___hc_get_descendent, 34, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_codeobj_19 = (PyObject*)__Pyx_PyCode_New(3, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_18, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_16, __pyx_n_s___hc_get_descendent, 38, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "sklearn/cluster/_hierarchical.pyx":76
+  /* "sklearn/cluster/_hierarchical.pyx":82
  * @cython.boundscheck(False)
  * @cython.wraparound(False)
- * def hc_get_heads(np.ndarray[INT, ndim=1] parents, copy=True):             # <<<<<<<<<<<<<<
- *     """ Return the heads of the forest, as defined by parents
+ * def hc_get_heads(np.ndarray[INTP, ndim=1] parents, copy=True):             # <<<<<<<<<<<<<<
+ *     """Returns the heads of the forest, as defined by parents.
  * 
  */
-  __pyx_k_tuple_20 = PyTuple_New(6); if (unlikely(!__pyx_k_tuple_20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_20 = PyTuple_Pack(6, ((PyObject *)__pyx_n_s__parents), ((PyObject *)__pyx_n_s__copy), ((PyObject *)__pyx_n_s__parent), ((PyObject *)__pyx_n_s__node0), ((PyObject *)__pyx_n_s__node), ((PyObject *)__pyx_n_s__size)); if (unlikely(!__pyx_k_tuple_20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_20);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__parents));
-  PyTuple_SET_ITEM(__pyx_k_tuple_20, 0, ((PyObject *)__pyx_n_s__parents));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__parents));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__copy));
-  PyTuple_SET_ITEM(__pyx_k_tuple_20, 1, ((PyObject *)__pyx_n_s__copy));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__copy));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__parent));
-  PyTuple_SET_ITEM(__pyx_k_tuple_20, 2, ((PyObject *)__pyx_n_s__parent));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__parent));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__node0));
-  PyTuple_SET_ITEM(__pyx_k_tuple_20, 3, ((PyObject *)__pyx_n_s__node0));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__node0));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__node));
-  PyTuple_SET_ITEM(__pyx_k_tuple_20, 4, ((PyObject *)__pyx_n_s__node));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__node));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__size));
-  PyTuple_SET_ITEM(__pyx_k_tuple_20, 5, ((PyObject *)__pyx_n_s__size));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__size));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_20));
-  __pyx_k_codeobj_21 = (PyObject*)__Pyx_PyCode_New(2, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_20, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_16, __pyx_n_s__hc_get_heads, 76, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_21)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_codeobj_21 = (PyObject*)__Pyx_PyCode_New(2, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_20, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_16, __pyx_n_s__hc_get_heads, 82, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_21)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "sklearn/cluster/_hierarchical.pyx":110
+  /* "sklearn/cluster/_hierarchical.pyx":116
  * @cython.boundscheck(False)
  * @cython.wraparound(False)
- * def _get_parents(nodes, heads, np.ndarray[INT, ndim=1] parents,             # <<<<<<<<<<<<<<
- *                  np.ndarray[INT8, ndim=1] not_visited):
- *     """ Return the heads of the given nodes, as defined by parents
+ * def _get_parents(nodes, heads, np.ndarray[INTP, ndim=1] parents,             # <<<<<<<<<<<<<<
+ *                  np.ndarray[INT8, ndim=1, mode='c'] not_visited):
+ *     """Returns the heads of the given nodes, as defined by parents.
  */
-  __pyx_k_tuple_22 = PyTuple_New(6); if (unlikely(!__pyx_k_tuple_22)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_tuple_22 = PyTuple_Pack(6, ((PyObject *)__pyx_n_s__nodes), ((PyObject *)__pyx_n_s__heads), ((PyObject *)__pyx_n_s__parents), ((PyObject *)__pyx_n_s__not_visited), ((PyObject *)__pyx_n_s__parent), ((PyObject *)__pyx_n_s__node)); if (unlikely(!__pyx_k_tuple_22)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_k_tuple_22);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__nodes));
-  PyTuple_SET_ITEM(__pyx_k_tuple_22, 0, ((PyObject *)__pyx_n_s__nodes));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__nodes));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__heads));
-  PyTuple_SET_ITEM(__pyx_k_tuple_22, 1, ((PyObject *)__pyx_n_s__heads));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__heads));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__parents));
-  PyTuple_SET_ITEM(__pyx_k_tuple_22, 2, ((PyObject *)__pyx_n_s__parents));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__parents));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__not_visited));
-  PyTuple_SET_ITEM(__pyx_k_tuple_22, 3, ((PyObject *)__pyx_n_s__not_visited));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__not_visited));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__parent));
-  PyTuple_SET_ITEM(__pyx_k_tuple_22, 4, ((PyObject *)__pyx_n_s__parent));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__parent));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__node));
-  PyTuple_SET_ITEM(__pyx_k_tuple_22, 5, ((PyObject *)__pyx_n_s__node));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__node));
   __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_22));
-  __pyx_k_codeobj_23 = (PyObject*)__Pyx_PyCode_New(4, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_22, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_16, __pyx_n_s___get_parents, 110, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_23)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_k_codeobj_23 = (PyObject*)__Pyx_PyCode_New(4, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_22, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_16, __pyx_n_s___get_parents, 116, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_23)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_RefNannyFinishContext();
   return 0;
   __pyx_L1_error:;
@@ -4751,6 +4749,9 @@ PyMODINIT_FUNC PyInit__hierarchical(void)
 #endif
 {
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannyDeclarations
   #if CYTHON_REFNANNY
   __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
@@ -4788,6 +4789,8 @@ PyMODINIT_FUNC PyInit__hierarchical(void)
   __pyx_m = PyModule_Create(&__pyx_moduledef);
   #endif
   if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  Py_INCREF(__pyx_d);
   #if PY_MAJOR_VERSION >= 3
   {
     PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
@@ -4803,6 +4806,9 @@ PyMODINIT_FUNC PyInit__hierarchical(void)
   if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
   /*--- Initialize various global constants etc. ---*/
   if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)
+  if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
   if (__pyx_module_is_main_sklearn__cluster___hierarchical) {
     if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
   }
@@ -4831,17 +4837,19 @@ PyMODINIT_FUNC PyInit__hierarchical(void)
   /*--- Function import code ---*/
   /*--- Execution code ---*/
 
-  /* "sklearn/cluster/_hierarchical.pyx":1
+  /* "sklearn/cluster/_hierarchical.pyx":3
+ * # Author: Gael Varoquaux <gael.varoquaux@normalesup.org>
+ * 
  * import numpy as np             # <<<<<<<<<<<<<<
  * cimport numpy as np
  * cimport cython
  */
-  __pyx_t_1 = __Pyx_Import(((PyObject *)__pyx_n_s__numpy), 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_Import(((PyObject *)__pyx_n_s__numpy), 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__np, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s__np, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "sklearn/cluster/_hierarchical.pyx":8
+  /* "sklearn/cluster/_hierarchical.pyx":11
  * ctypedef np.int8_t INT8
  * 
  * np.import_array()             # <<<<<<<<<<<<<<
@@ -4850,67 +4858,67 @@ PyMODINIT_FUNC PyInit__hierarchical(void)
  */
   import_array();
 
-  /* "sklearn/cluster/_hierarchical.pyx":14
+  /* "sklearn/cluster/_hierarchical.pyx":17
  * @cython.wraparound(False)
  * @cython.cdivision(True)
- * def compute_ward_dist(np.ndarray[DOUBLE, ndim=1] m_1,\             # <<<<<<<<<<<<<<
- *                     np.ndarray[DOUBLE, ndim=2] m_2,\
- *                     np.ndarray[INT, ndim=1] coord_row,
+ * def compute_ward_dist(np.ndarray[DOUBLE, ndim=1, mode='c'] m_1,             # <<<<<<<<<<<<<<
+ *                       np.ndarray[DOUBLE, ndim=2, mode='c'] m_2,
+ *                       np.ndarray[INTP, ndim=1, mode='c'] coord_row,
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7sklearn_7cluster_13_hierarchical_1compute_ward_dist, NULL, __pyx_n_s_17); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7sklearn_7cluster_13_hierarchical_1compute_ward_dist, NULL, __pyx_n_s_17); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__compute_ward_dist, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s__compute_ward_dist, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "sklearn/cluster/_hierarchical.pyx":34
+  /* "sklearn/cluster/_hierarchical.pyx":38
  * 
  * 
- * def _hc_get_descendent(int node, children, int n_leaves):             # <<<<<<<<<<<<<<
+ * def _hc_get_descendent(INTP node, children, INTP n_leaves):             # <<<<<<<<<<<<<<
  *     """
  *     Function returning all the descendent leaves of a set of nodes in the tree.
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7sklearn_7cluster_13_hierarchical_3_hc_get_descendent, NULL, __pyx_n_s_17); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7sklearn_7cluster_13_hierarchical_3_hc_get_descendent, NULL, __pyx_n_s_17); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s___hc_get_descendent, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s___hc_get_descendent, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "sklearn/cluster/_hierarchical.pyx":76
+  /* "sklearn/cluster/_hierarchical.pyx":82
  * @cython.boundscheck(False)
  * @cython.wraparound(False)
- * def hc_get_heads(np.ndarray[INT, ndim=1] parents, copy=True):             # <<<<<<<<<<<<<<
- *     """ Return the heads of the forest, as defined by parents
+ * def hc_get_heads(np.ndarray[INTP, ndim=1] parents, copy=True):             # <<<<<<<<<<<<<<
+ *     """Returns the heads of the forest, as defined by parents.
  * 
  */
-  __pyx_t_1 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_k_1 = __pyx_t_1;
   __Pyx_GIVEREF(__pyx_t_1);
   __pyx_t_1 = 0;
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7sklearn_7cluster_13_hierarchical_5hc_get_heads, NULL, __pyx_n_s_17); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7sklearn_7cluster_13_hierarchical_5hc_get_heads, NULL, __pyx_n_s_17); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__hc_get_heads, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s__hc_get_heads, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "sklearn/cluster/_hierarchical.pyx":110
+  /* "sklearn/cluster/_hierarchical.pyx":116
  * @cython.boundscheck(False)
  * @cython.wraparound(False)
- * def _get_parents(nodes, heads, np.ndarray[INT, ndim=1] parents,             # <<<<<<<<<<<<<<
- *                  np.ndarray[INT8, ndim=1] not_visited):
- *     """ Return the heads of the given nodes, as defined by parents
+ * def _get_parents(nodes, heads, np.ndarray[INTP, ndim=1] parents,             # <<<<<<<<<<<<<<
+ *                  np.ndarray[INT8, ndim=1, mode='c'] not_visited):
+ *     """Returns the heads of the given nodes, as defined by parents.
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7sklearn_7cluster_13_hierarchical_7_get_parents, NULL, __pyx_n_s_17); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7sklearn_7cluster_13_hierarchical_7_get_parents, NULL, __pyx_n_s_17); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s___get_parents, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s___get_parents, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
   /* "sklearn/cluster/_hierarchical.pyx":1
- * import numpy as np             # <<<<<<<<<<<<<<
- * cimport numpy as np
- * cimport cython
+ * # Author: Gael Varoquaux <gael.varoquaux@normalesup.org>             # <<<<<<<<<<<<<<
+ * 
+ * import numpy as np
  */
   __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s____test__, ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
 
   /* "numpy.pxd":975
@@ -4955,17 +4963,15 @@ end:
 }
 #endif /* CYTHON_REFNANNY */
 
-static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
-    PyObject *result;
-    result = PyObject_GetAttr(dict, name);
-    if (!result) {
-        if (dict != __pyx_b) {
-            PyErr_Clear();
-            result = PyObject_GetAttr(__pyx_b, name);
-        }
-        if (!result) {
-            PyErr_SetObject(PyExc_NameError, name);
-        }
+static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
+    PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name);
+    if (unlikely(!result)) {
+        PyErr_Format(PyExc_NameError,
+#if PY_MAJOR_VERSION >= 3
+            "name '%U' is not defined", name);
+#else
+            "name '%s' is not defined", PyString_AS_STRING(name));
+#endif
     }
     return result;
 }
@@ -5703,6 +5709,117 @@ static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyOb
 #endif
 }
 
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Pop(PyObject* L) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x02040000
+    if (likely(PyList_CheckExact(L))
+        && likely(PyList_GET_SIZE(L) > (((PyListObject*)L)->allocated >> 1))) {
+        Py_SIZE(L) -= 1;
+        return PyList_GET_ITEM(L, PyList_GET_SIZE(L));
+    }
+#if PY_VERSION_HEX >= 0x02050000
+    else if (Py_TYPE(L) == (&PySet_Type)) {
+        return PySet_Pop(L);
+    }
+#endif
+#endif
+    return __Pyx_PyObject_CallMethod0(L, __pyx_n_s__pop);
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+    PyObject *r;
+    if (!j) return NULL;
+    r = PyObject_GetItem(o, j);
+    Py_DECREF(j);
+    return r;
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+                                                              int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (wraparound & unlikely(i < 0)) i += PyList_GET_SIZE(o);
+    if ((!boundscheck) || likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+        PyObject *r = PyList_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+                                                              int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (wraparound & unlikely(i < 0)) i += PyTuple_GET_SIZE(o);
+    if ((!boundscheck) || likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+        PyObject *r = PyTuple_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+                                                     int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (is_list || PyList_CheckExact(o)) {
+        Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+        if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) {
+            PyObject *r = PyList_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    }
+    else if (PyTuple_CheckExact(o)) {
+        Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+        if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+            PyObject *r = PyTuple_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    } else {
+        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+        if (likely(m && m->sq_item)) {
+            if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+                Py_ssize_t l = m->sq_length(o);
+                if (likely(l >= 0)) {
+                    i += l;
+                } else {
+                    if (PyErr_ExceptionMatches(PyExc_OverflowError))
+                        PyErr_Clear();
+                    else
+                        return NULL;
+                }
+            }
+            return m->sq_item(o, i);
+        }
+    }
+#else
+    if (is_list || PySequence_Check(o)) {
+        return PySequence_GetItem(o, i);
+    }
+#endif
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) {
+    PyObject *result;
+#if CYTHON_COMPILING_IN_CPYTHON
+    result = PyDict_GetItem(__pyx_d, name);
+    if (result) {
+        Py_INCREF(result);
+    } else {
+#else
+    result = PyObject_GetItem(__pyx_d, name);
+    if (!result) {
+        PyErr_Clear();
+#endif
+        result = __Pyx_GetBuiltinName(name);
+    }
+    return result;
+}
+
 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
     if (unlikely(!type)) {
         PyErr_Format(PyExc_SystemError, "Missing type object");
@@ -5720,6 +5837,16 @@ static void __Pyx_RaiseBufferFallbackError(void) {
      "Buffer acquisition failed on assignment; and then reacquiring the old buffer failed too!");
 }
 
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
+    if (likely(PyList_CheckExact(L))) {
+        if (unlikely(__Pyx_PyList_Append(L, x) < 0)) return NULL;
+        Py_INCREF(Py_None);
+        return Py_None; /* this is just to have an accurate signature */
+    } else {
+        return __Pyx_PyObject_CallMethod1(L, __pyx_n_s__append, x);
+    }
+}
+
 #if PY_MAJOR_VERSION < 3
 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
                         CYTHON_UNUSED PyObject *cause) {
@@ -5758,24 +5885,23 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
         }
         value = type;
         #if PY_VERSION_HEX < 0x02050000
-            if (PyInstance_Check(type)) {
-                type = (PyObject*) ((PyInstanceObject*)type)->in_class;
-                Py_INCREF(type);
-            }
-            else {
-                type = 0;
-                PyErr_SetString(PyExc_TypeError,
-                    "raise: exception must be an old-style class or instance");
-                goto raise_error;
-            }
-        #else
-            type = (PyObject*) Py_TYPE(type);
+        if (PyInstance_Check(type)) {
+            type = (PyObject*) ((PyInstanceObject*)type)->in_class;
             Py_INCREF(type);
-            if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
-                PyErr_SetString(PyExc_TypeError,
-                    "raise: exception class must be a subclass of BaseException");
-                goto raise_error;
-            }
+        } else {
+            type = 0;
+            PyErr_SetString(PyExc_TypeError,
+                "raise: exception must be an old-style class or instance");
+            goto raise_error;
+        }
+        #else
+        type = (PyObject*) Py_TYPE(type);
+        Py_INCREF(type);
+        if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+            PyErr_SetString(PyExc_TypeError,
+                "raise: exception class must be a subclass of BaseException");
+            goto raise_error;
+        }
         #endif
     }
     __Pyx_ErrRestore(type, value, tb);
@@ -5813,8 +5939,7 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject
         else if (PyTuple_Check(value)) {
             Py_INCREF(value);
             args = value;
-        }
-        else
+        } else
             args = PyTuple_Pack(1, value);
         if (!args)
             goto bad;
@@ -5835,18 +5960,22 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject
             "raise: exception class must be a subclass of BaseException");
         goto bad;
     }
+#if PY_VERSION_HEX >= 0x03030000
+    if (cause) {
+#else
     if (cause && cause != Py_None) {
+#endif
         PyObject *fixed_cause;
-        if (PyExceptionClass_Check(cause)) {
+        if (cause == Py_None) {
+            fixed_cause = NULL;
+        } else if (PyExceptionClass_Check(cause)) {
             fixed_cause = PyObject_CallObject(cause, NULL);
             if (fixed_cause == NULL)
                 goto bad;
-        }
-        else if (PyExceptionInstance_Check(cause)) {
+        } else if (PyExceptionInstance_Check(cause)) {
             fixed_cause = cause;
             Py_INCREF(fixed_cause);
-        }
-        else {
+        } else {
             PyErr_SetString(PyExc_TypeError,
                             "exception causes must derive from "
                             "BaseException");
@@ -5932,27 +6061,23 @@ static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) {
 
 #if PY_MAJOR_VERSION < 3
 static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {
-    CYTHON_UNUSED PyObject *getbuffer_cobj;
   #if PY_VERSION_HEX >= 0x02060000
     if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags);
   #endif
         if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) return __pyx_pw_5numpy_7ndarray_1__getbuffer__(obj, view, flags);
   #if PY_VERSION_HEX < 0x02060000
-    if (obj->ob_type->tp_dict &&
-        (getbuffer_cobj = PyMapping_GetItemString(obj->ob_type->tp_dict,
-                                             "__pyx_getbuffer"))) {
-        getbufferproc func;
-      #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION == 0)
-        func = (getbufferproc) PyCapsule_GetPointer(getbuffer_cobj, "getbuffer(obj, view, flags)");
-      #else
-        func = (getbufferproc) PyCObject_AsVoidPtr(getbuffer_cobj);
-      #endif
-        Py_DECREF(getbuffer_cobj);
-        if (!func)
-            goto fail;
-        return func(obj, view, flags);
-    } else {
-        PyErr_Clear();
+    if (obj->ob_type->tp_dict) {
+        PyObject *getbuffer_cobj = PyObject_GetItem(
+            obj->ob_type->tp_dict, __pyx_n_s____pyx_getbuffer);
+        if (getbuffer_cobj) {
+            getbufferproc func = (getbufferproc) PyCObject_AsVoidPtr(getbuffer_cobj);
+            Py_DECREF(getbuffer_cobj);
+            if (!func)
+                goto fail;
+            return func(obj, view, flags);
+        } else {
+            PyErr_Clear();
+        }
     }
   #endif
     PyErr_Format(PyExc_TypeError, "'%100s' does not have the buffer interface", Py_TYPE(obj)->tp_name);
@@ -5963,7 +6088,6 @@ fail:
 }
 static void __Pyx_ReleaseBuffer(Py_buffer *view) {
     PyObject *obj = view->obj;
-    CYTHON_UNUSED PyObject *releasebuffer_cobj;
     if (!obj) return;
   #if PY_VERSION_HEX >= 0x02060000
     if (PyObject_CheckBuffer(obj)) {
@@ -5973,22 +6097,19 @@ static void __Pyx_ReleaseBuffer(Py_buffer *view) {
   #endif
         if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) { __pyx_pw_5numpy_7ndarray_3__releasebuffer__(obj, view); return; }
   #if PY_VERSION_HEX < 0x02060000
-    if (obj->ob_type->tp_dict &&
-        (releasebuffer_cobj = PyMapping_GetItemString(obj->ob_type->tp_dict,
-                                                      "__pyx_releasebuffer"))) {
-        releasebufferproc func;
-      #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION == 0)
-        func = (releasebufferproc) PyCapsule_GetPointer(releasebuffer_cobj, "releasebuffer(obj, view)");
-      #else
-        func = (releasebufferproc) PyCObject_AsVoidPtr(releasebuffer_cobj);
-      #endif
-        Py_DECREF(releasebuffer_cobj);
-        if (!func)
-            goto fail;
-        func(obj, view);
-        return;
-    } else {
-        PyErr_Clear();
+    if (obj->ob_type->tp_dict) {
+        PyObject *releasebuffer_cobj = PyObject_GetItem(
+            obj->ob_type->tp_dict, __pyx_n_s____pyx_releasebuffer);
+        if (releasebuffer_cobj) {
+            releasebufferproc func = (releasebufferproc) PyCObject_AsVoidPtr(releasebuffer_cobj);
+            Py_DECREF(releasebuffer_cobj);
+            if (!func)
+                goto fail;
+            func(obj, view);
+            return;
+        } else {
+            PyErr_Clear();
+        }
     }
   #endif
     goto nofail;
@@ -6003,16 +6124,18 @@ nofail:
 #endif /*  PY_MAJOR_VERSION < 3 */
 
 
-    static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, long level) {
-    PyObject *py_import = 0;
+        static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
     PyObject *empty_list = 0;
     PyObject *module = 0;
     PyObject *global_dict = 0;
     PyObject *empty_dict = 0;
     PyObject *list;
-    py_import = __Pyx_GetAttrString(__pyx_b, "__import__");
+    #if PY_VERSION_HEX < 0x03030000
+    PyObject *py_import;
+    py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s____import__);
     if (!py_import)
         goto bad;
+    #endif
     if (from_list)
         list = from_list;
     else {
@@ -6032,13 +6155,17 @@ nofail:
         #if PY_MAJOR_VERSION >= 3
         if (level == -1) {
             if (strchr(__Pyx_MODULE_NAME, '.')) {
-                /* try package relative import first */
+                #if PY_VERSION_HEX < 0x03030000
                 PyObject *py_level = PyInt_FromLong(1);
                 if (!py_level)
                     goto bad;
                 module = PyObject_CallFunctionObjArgs(py_import,
                     name, global_dict, empty_dict, list, py_level, NULL);
                 Py_DECREF(py_level);
+                #else
+                module = PyImport_ImportModuleLevelObject(
+                    name, global_dict, empty_dict, list, 1);
+                #endif
                 if (!module) {
                     if (!PyErr_ExceptionMatches(PyExc_ImportError))
                         goto bad;
@@ -6049,12 +6176,17 @@ nofail:
         }
         #endif
         if (!module) {
+            #if PY_VERSION_HEX < 0x03030000
             PyObject *py_level = PyInt_FromLong(level);
             if (!py_level)
                 goto bad;
             module = PyObject_CallFunctionObjArgs(py_import,
                 name, global_dict, empty_dict, list, py_level, NULL);
             Py_DECREF(py_level);
+            #else
+            module = PyImport_ImportModuleLevelObject(
+                name, global_dict, empty_dict, list, level);
+            #endif
         }
     }
     #else
@@ -6066,12 +6198,96 @@ nofail:
         name, global_dict, empty_dict, list, NULL);
     #endif
 bad:
-    Py_XDECREF(empty_list);
+    #if PY_VERSION_HEX < 0x03030000
     Py_XDECREF(py_import);
+    #endif
+    Py_XDECREF(empty_list);
     Py_XDECREF(empty_dict);
     return module;
 }
 
+static CYTHON_INLINE Py_intptr_t __Pyx_PyInt_from_py_Py_intptr_t(PyObject* x) {
+    const Py_intptr_t neg_one = (Py_intptr_t)-1, const_zero = (Py_intptr_t)0;
+    const int is_unsigned = const_zero < neg_one;
+    if (sizeof(Py_intptr_t) == sizeof(char)) {
+        if (is_unsigned)
+            return (Py_intptr_t)__Pyx_PyInt_AsUnsignedChar(x);
+        else
+            return (Py_intptr_t)__Pyx_PyInt_AsSignedChar(x);
+    } else if (sizeof(Py_intptr_t) == sizeof(short)) {
+        if (is_unsigned)
+            return (Py_intptr_t)__Pyx_PyInt_AsUnsignedShort(x);
+        else
+            return (Py_intptr_t)__Pyx_PyInt_AsSignedShort(x);
+    } else if (sizeof(Py_intptr_t) == sizeof(int)) {
+        if (is_unsigned)
+            return (Py_intptr_t)__Pyx_PyInt_AsUnsignedInt(x);
+        else
+            return (Py_intptr_t)__Pyx_PyInt_AsSignedInt(x);
+    } else if (sizeof(Py_intptr_t) == sizeof(long)) {
+        if (is_unsigned)
+            return (Py_intptr_t)__Pyx_PyInt_AsUnsignedLong(x);
+        else
+            return (Py_intptr_t)__Pyx_PyInt_AsSignedLong(x);
+    } else if (sizeof(Py_intptr_t) == sizeof(PY_LONG_LONG)) {
+        if (is_unsigned)
+            return (Py_intptr_t)__Pyx_PyInt_AsUnsignedLongLong(x);
+        else
+            return (Py_intptr_t)__Pyx_PyInt_AsSignedLongLong(x);
+    }  else {
+        #if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+        PyErr_SetString(PyExc_RuntimeError,
+                        "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+        #else
+        Py_intptr_t val;
+        PyObject *v = __Pyx_PyNumber_Int(x);
+        #if PY_MAJOR_VERSION < 3
+        if (likely(v) && !PyLong_Check(v)) {
+            PyObject *tmp = v;
+            v = PyNumber_Long(tmp);
+            Py_DECREF(tmp);
+        }
+        #endif
+        if (likely(v)) {
+            int one = 1; int is_little = (int)*(unsigned char *)&one;
+            unsigned char *bytes = (unsigned char *)&val;
+            int ret = _PyLong_AsByteArray((PyLongObject *)v,
+                                          bytes, sizeof(val),
+                                          is_little, !is_unsigned);
+            Py_DECREF(v);
+            if (likely(!ret))
+                return val;
+        }
+        #endif
+        return (Py_intptr_t)-1;
+    }
+}
+
+static CYTHON_INLINE PyObject *__Pyx_PyInt_to_py_Py_intptr_t(Py_intptr_t val) {
+    const Py_intptr_t neg_one = (Py_intptr_t)-1, const_zero = (Py_intptr_t)0;
+    const int is_unsigned = const_zero < neg_one;
+    if ((sizeof(Py_intptr_t) == sizeof(char))  ||
+        (sizeof(Py_intptr_t) == sizeof(short))) {
+        return PyInt_FromLong((long)val);
+    } else if ((sizeof(Py_intptr_t) == sizeof(int)) ||
+               (sizeof(Py_intptr_t) == sizeof(long))) {
+        if (is_unsigned)
+            return PyLong_FromUnsignedLong((unsigned long)val);
+        else
+            return PyInt_FromLong((long)val);
+    } else if (sizeof(Py_intptr_t) == sizeof(PY_LONG_LONG)) {
+        if (is_unsigned)
+            return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)val);
+        else
+            return PyLong_FromLongLong((PY_LONG_LONG)val);
+    } else {
+        int one = 1; int little = (int)*(unsigned char *)&one;
+        unsigned char *bytes = (unsigned char *)&val;
+        return _PyLong_FromByteArray(bytes, sizeof(Py_intptr_t),
+                                     little, !is_unsigned);
+    }
+}
+
 #if CYTHON_CCOMPLEX
   #ifdef __cplusplus
     static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
@@ -6502,10 +6718,15 @@ static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
     return (int)__Pyx_PyInt_AsLong(x);
 }
 
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+#if CYTHON_USE_PYLONG_INTERNALS
+#include "longintrepr.h"
+#endif
+#endif
 static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
     const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
     const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
+#if PY_MAJOR_VERSION < 3
     if (likely(PyInt_Check(x))) {
         long val = PyInt_AS_LONG(x);
         if (is_unsigned && unlikely(val < 0)) {
@@ -6518,6 +6739,16 @@ static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
 #endif
     if (likely(PyLong_Check(x))) {
         if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+#if CYTHON_USE_PYLONG_INTERNALS
+            if (sizeof(digit) <= sizeof(unsigned long)) {
+                switch (Py_SIZE(x)) {
+                    case  0: return 0;
+                    case  1: return (unsigned long) ((PyLongObject*)x)->ob_digit[0];
+                }
+            }
+#endif
+#endif
             if (unlikely(Py_SIZE(x) < 0)) {
                 PyErr_SetString(PyExc_OverflowError,
                                 "can't convert negative value to unsigned long");
@@ -6525,6 +6756,17 @@ static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
             }
             return (unsigned long)PyLong_AsUnsignedLong(x);
         } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+#if CYTHON_USE_PYLONG_INTERNALS
+            if (sizeof(digit) <= sizeof(unsigned long)) {
+                switch (Py_SIZE(x)) {
+                    case  0: return 0;
+                    case  1: return +(unsigned long) ((PyLongObject*)x)->ob_digit[0];
+                    case -1: return -(unsigned long) ((PyLongObject*)x)->ob_digit[0];
+                }
+            }
+#endif
+#endif
             return (unsigned long)PyLong_AsLong(x);
         }
     } else {
@@ -6537,10 +6779,15 @@ static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
     }
 }
 
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+#if CYTHON_USE_PYLONG_INTERNALS
+#include "longintrepr.h"
+#endif
+#endif
 static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
     const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
     const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
+#if PY_MAJOR_VERSION < 3
     if (likely(PyInt_Check(x))) {
         long val = PyInt_AS_LONG(x);
         if (is_unsigned && unlikely(val < 0)) {
@@ -6553,6 +6800,16 @@ static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObje
 #endif
     if (likely(PyLong_Check(x))) {
         if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+#if CYTHON_USE_PYLONG_INTERNALS
+            if (sizeof(digit) <= sizeof(unsigned PY_LONG_LONG)) {
+                switch (Py_SIZE(x)) {
+                    case  0: return 0;
+                    case  1: return (unsigned PY_LONG_LONG) ((PyLongObject*)x)->ob_digit[0];
+                }
+            }
+#endif
+#endif
             if (unlikely(Py_SIZE(x) < 0)) {
                 PyErr_SetString(PyExc_OverflowError,
                                 "can't convert negative value to unsigned PY_LONG_LONG");
@@ -6560,6 +6817,17 @@ static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObje
             }
             return (unsigned PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
         } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+#if CYTHON_USE_PYLONG_INTERNALS
+            if (sizeof(digit) <= sizeof(unsigned PY_LONG_LONG)) {
+                switch (Py_SIZE(x)) {
+                    case  0: return 0;
+                    case  1: return +(unsigned PY_LONG_LONG) ((PyLongObject*)x)->ob_digit[0];
+                    case -1: return -(unsigned PY_LONG_LONG) ((PyLongObject*)x)->ob_digit[0];
+                }
+            }
+#endif
+#endif
             return (unsigned PY_LONG_LONG)PyLong_AsLongLong(x);
         }
     } else {
@@ -6572,10 +6840,15 @@ static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObje
     }
 }
 
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+#if CYTHON_USE_PYLONG_INTERNALS
+#include "longintrepr.h"
+#endif
+#endif
 static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
     const long neg_one = (long)-1, const_zero = 0;
     const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
+#if PY_MAJOR_VERSION < 3
     if (likely(PyInt_Check(x))) {
         long val = PyInt_AS_LONG(x);
         if (is_unsigned && unlikely(val < 0)) {
@@ -6588,6 +6861,16 @@ static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
 #endif
     if (likely(PyLong_Check(x))) {
         if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+#if CYTHON_USE_PYLONG_INTERNALS
+            if (sizeof(digit) <= sizeof(long)) {
+                switch (Py_SIZE(x)) {
+                    case  0: return 0;
+                    case  1: return (long) ((PyLongObject*)x)->ob_digit[0];
+                }
+            }
+#endif
+#endif
             if (unlikely(Py_SIZE(x) < 0)) {
                 PyErr_SetString(PyExc_OverflowError,
                                 "can't convert negative value to long");
@@ -6595,6 +6878,17 @@ static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
             }
             return (long)PyLong_AsUnsignedLong(x);
         } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+#if CYTHON_USE_PYLONG_INTERNALS
+            if (sizeof(digit) <= sizeof(long)) {
+                switch (Py_SIZE(x)) {
+                    case  0: return 0;
+                    case  1: return +(long) ((PyLongObject*)x)->ob_digit[0];
+                    case -1: return -(long) ((PyLongObject*)x)->ob_digit[0];
+                }
+            }
+#endif
+#endif
             return (long)PyLong_AsLong(x);
         }
     } else {
@@ -6607,10 +6901,15 @@ static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
     }
 }
 
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+#if CYTHON_USE_PYLONG_INTERNALS
+#include "longintrepr.h"
+#endif
+#endif
 static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
     const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
     const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
+#if PY_MAJOR_VERSION < 3
     if (likely(PyInt_Check(x))) {
         long val = PyInt_AS_LONG(x);
         if (is_unsigned && unlikely(val < 0)) {
@@ -6623,6 +6922,16 @@ static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
 #endif
     if (likely(PyLong_Check(x))) {
         if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+#if CYTHON_USE_PYLONG_INTERNALS
+            if (sizeof(digit) <= sizeof(PY_LONG_LONG)) {
+                switch (Py_SIZE(x)) {
+                    case  0: return 0;
+                    case  1: return (PY_LONG_LONG) ((PyLongObject*)x)->ob_digit[0];
+                }
+            }
+#endif
+#endif
             if (unlikely(Py_SIZE(x) < 0)) {
                 PyErr_SetString(PyExc_OverflowError,
                                 "can't convert negative value to PY_LONG_LONG");
@@ -6630,6 +6939,17 @@ static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
             }
             return (PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
         } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+#if CYTHON_USE_PYLONG_INTERNALS
+            if (sizeof(digit) <= sizeof(PY_LONG_LONG)) {
+                switch (Py_SIZE(x)) {
+                    case  0: return 0;
+                    case  1: return +(PY_LONG_LONG) ((PyLongObject*)x)->ob_digit[0];
+                    case -1: return -(PY_LONG_LONG) ((PyLongObject*)x)->ob_digit[0];
+                }
+            }
+#endif
+#endif
             return (PY_LONG_LONG)PyLong_AsLongLong(x);
         }
     } else {
@@ -6642,10 +6962,15 @@ static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
     }
 }
 
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+#if CYTHON_USE_PYLONG_INTERNALS
+#include "longintrepr.h"
+#endif
+#endif
 static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
     const signed long neg_one = (signed long)-1, const_zero = 0;
     const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
+#if PY_MAJOR_VERSION < 3
     if (likely(PyInt_Check(x))) {
         long val = PyInt_AS_LONG(x);
         if (is_unsigned && unlikely(val < 0)) {
@@ -6658,6 +6983,16 @@ static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
 #endif
     if (likely(PyLong_Check(x))) {
         if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+#if CYTHON_USE_PYLONG_INTERNALS
+            if (sizeof(digit) <= sizeof(signed long)) {
+                switch (Py_SIZE(x)) {
+                    case  0: return 0;
+                    case  1: return (signed long) ((PyLongObject*)x)->ob_digit[0];
+                }
+            }
+#endif
+#endif
             if (unlikely(Py_SIZE(x) < 0)) {
                 PyErr_SetString(PyExc_OverflowError,
                                 "can't convert negative value to signed long");
@@ -6665,6 +7000,17 @@ static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
             }
             return (signed long)PyLong_AsUnsignedLong(x);
         } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+#if CYTHON_USE_PYLONG_INTERNALS
+            if (sizeof(digit) <= sizeof(signed long)) {
+                switch (Py_SIZE(x)) {
+                    case  0: return 0;
+                    case  1: return +(signed long) ((PyLongObject*)x)->ob_digit[0];
+                    case -1: return -(signed long) ((PyLongObject*)x)->ob_digit[0];
+                }
+            }
+#endif
+#endif
             return (signed long)PyLong_AsLong(x);
         }
     } else {
@@ -6677,10 +7023,15 @@ static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
     }
 }
 
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+#if CYTHON_USE_PYLONG_INTERNALS
+#include "longintrepr.h"
+#endif
+#endif
 static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
     const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
     const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
+#if PY_MAJOR_VERSION < 3
     if (likely(PyInt_Check(x))) {
         long val = PyInt_AS_LONG(x);
         if (is_unsigned && unlikely(val < 0)) {
@@ -6693,6 +7044,16 @@ static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject*
 #endif
     if (likely(PyLong_Check(x))) {
         if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+#if CYTHON_USE_PYLONG_INTERNALS
+            if (sizeof(digit) <= sizeof(signed PY_LONG_LONG)) {
+                switch (Py_SIZE(x)) {
+                    case  0: return 0;
+                    case  1: return (signed PY_LONG_LONG) ((PyLongObject*)x)->ob_digit[0];
+                }
+            }
+#endif
+#endif
             if (unlikely(Py_SIZE(x) < 0)) {
                 PyErr_SetString(PyExc_OverflowError,
                                 "can't convert negative value to signed PY_LONG_LONG");
@@ -6700,6 +7061,17 @@ static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject*
             }
             return (signed PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
         } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+#if CYTHON_USE_PYLONG_INTERNALS
+            if (sizeof(digit) <= sizeof(signed PY_LONG_LONG)) {
+                switch (Py_SIZE(x)) {
+                    case  0: return 0;
+                    case  1: return +(signed PY_LONG_LONG) ((PyLongObject*)x)->ob_digit[0];
+                    case -1: return -(signed PY_LONG_LONG) ((PyLongObject*)x)->ob_digit[0];
+                }
+            }
+#endif
+#endif
             return (signed PY_LONG_LONG)PyLong_AsLongLong(x);
         }
     } else {
@@ -6757,6 +7129,10 @@ static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class
     PyObject *result = 0;
     PyObject *py_name = 0;
     char warning[200];
+    Py_ssize_t basicsize;
+#ifdef Py_LIMITED_API
+    PyObject *py_basicsize;
+#endif
     py_module = __Pyx_ImportModule(module_name);
     if (!py_module)
         goto bad;
@@ -6776,7 +7152,19 @@ static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class
             module_name, class_name);
         goto bad;
     }
-    if (!strict && (size_t)((PyTypeObject *)result)->tp_basicsize > size) {
+#ifndef Py_LIMITED_API
+    basicsize = ((PyTypeObject *)result)->tp_basicsize;
+#else
+    py_basicsize = PyObject_GetAttrString(result, "__basicsize__");
+    if (!py_basicsize)
+        goto bad;
+    basicsize = PyLong_AsSsize_t(py_basicsize);
+    Py_DECREF(py_basicsize);
+    py_basicsize = 0;
+    if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred())
+        goto bad;
+#endif
+    if (!strict && (size_t)basicsize > size) {
         PyOS_snprintf(warning, sizeof(warning),
             "%s.%s size changed, may indicate binary incompatibility",
             module_name, class_name);
@@ -6786,7 +7174,7 @@ static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class
         if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad;
         #endif
     }
-    else if ((size_t)((PyTypeObject *)result)->tp_basicsize != size) {
+    else if ((size_t)basicsize != size) {
         PyErr_Format(PyExc_ValueError,
             "%s.%s has the wrong size, try recompiling",
             module_name, class_name);
@@ -6992,27 +7380,82 @@ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
     return 0;
 }
 
-
-/* Type Conversion Functions */
-
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(char* c_str) {
+    return __Pyx_PyUnicode_FromStringAndSize(c_str, strlen(c_str));
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) {
+    Py_ssize_t ignore;
+    return __Pyx_PyObject_AsStringAndSize(o, &ignore);
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) {
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+    if (
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+            __Pyx_sys_getdefaultencoding_not_ascii &&
+#endif
+            PyUnicode_Check(o)) {
+#if PY_VERSION_HEX < 0x03030000
+        char* defenc_c;
+        PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL);
+        if (!defenc) return NULL;
+        defenc_c = PyBytes_AS_STRING(defenc);
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+        {
+            char* end = defenc_c + PyBytes_GET_SIZE(defenc);
+            char* c;
+            for (c = defenc_c; c < end; c++) {
+                if ((unsigned char) (*c) >= 128) {
+                    PyUnicode_AsASCIIString(o);
+                    return NULL;
+                }
+            }
+        }
+#endif /*__PYX_DEFAULT_STRING_ENCODING_IS_ASCII*/
+        *length = PyBytes_GET_SIZE(defenc);
+        return defenc_c;
+#else /* PY_VERSION_HEX < 0x03030000 */
+        if (PyUnicode_READY(o) == -1) return NULL;
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+        if (PyUnicode_IS_ASCII(o)) {
+            *length = PyUnicode_GET_DATA_SIZE(o);
+            return PyUnicode_AsUTF8(o);
+        } else {
+            PyUnicode_AsASCIIString(o);
+            return NULL;
+        }
+#else /* __PYX_DEFAULT_STRING_ENCODING_IS_ASCII */
+        return PyUnicode_AsUTF8AndSize(o, length);
+#endif /* __PYX_DEFAULT_STRING_ENCODING_IS_ASCII */
+#endif /* PY_VERSION_HEX < 0x03030000 */
+    } else
+#endif /* __PYX_DEFAULT_STRING_ENCODING_IS_ASCII  || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT */
+    {
+        char* result;
+        int r = PyBytes_AsStringAndSize(o, &result, length);
+        if (r < 0) {
+            return NULL;
+        } else {
+            return result;
+        }
+    }
+}
 static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
    int is_true = x == Py_True;
    if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
    else return PyObject_IsTrue(x);
 }
-
 static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
   PyNumberMethods *m;
   const char *name = NULL;
   PyObject *res = NULL;
-#if PY_VERSION_HEX < 0x03000000
+#if PY_MAJOR_VERSION < 3
   if (PyInt_Check(x) || PyLong_Check(x))
 #else
   if (PyLong_Check(x))
 #endif
     return Py_INCREF(x), x;
   m = Py_TYPE(x)->tp_as_number;
-#if PY_VERSION_HEX < 0x03000000
+#if PY_MAJOR_VERSION < 3
   if (m && m->nb_int) {
     name = "int";
     res = PyNumber_Int(x);
@@ -7028,7 +7471,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
   }
 #endif
   if (res) {
-#if PY_VERSION_HEX < 0x03000000
+#if PY_MAJOR_VERSION < 3
     if (!PyInt_Check(res) && !PyLong_Check(res)) {
 #else
     if (!PyLong_Check(res)) {
@@ -7046,7 +7489,6 @@ static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
   }
   return res;
 }
-
 static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
   Py_ssize_t ival;
   PyObject* x = PyNumber_Index(b);
@@ -7055,7 +7497,6 @@ static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
   Py_DECREF(x);
   return ival;
 }
-
 static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
 #if PY_VERSION_HEX < 0x02050000
    if (ival <= LONG_MAX)
@@ -7069,14 +7510,12 @@ static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
    return PyInt_FromSize_t(ival);
 #endif
 }
-
 static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
    unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
-   if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
-       return (size_t)-1;
-   } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
-       PyErr_SetString(PyExc_OverflowError,
-                       "value too large to convert to size_t");
+   if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
+       if ((val != (unsigned PY_LONG_LONG)-1) || !PyErr_Occurred())
+           PyErr_SetString(PyExc_OverflowError,
+                           "value too large to convert to size_t");
        return (size_t)-1;
    }
    return (size_t)val;
diff --git a/sklearn/cluster/_hierarchical.pyx b/sklearn/cluster/_hierarchical.pyx
index 881c126a64ce922ee1c527786e0dad8e2ce50662..c07b90c71d1681f0bc185b27a6d6c6c14830d6d1 100644
--- a/sklearn/cluster/_hierarchical.pyx
+++ b/sklearn/cluster/_hierarchical.pyx
@@ -1,8 +1,11 @@
+# Author: Gael Varoquaux <gael.varoquaux@normalesup.org>
+
 import numpy as np
 cimport numpy as np
 cimport cython
+
 ctypedef np.float64_t DOUBLE
-ctypedef np.int_t INT
+ctypedef np.npy_intp INTP
 ctypedef np.int8_t INT8
 
 np.import_array()
@@ -11,41 +14,42 @@ np.import_array()
 @cython.boundscheck(False)
 @cython.wraparound(False)
 @cython.cdivision(True)
-def compute_ward_dist(np.ndarray[DOUBLE, ndim=1] m_1,\
-                    np.ndarray[DOUBLE, ndim=2] m_2,\
-                    np.ndarray[INT, ndim=1] coord_row,
-                    np.ndarray[INT, ndim=1] coord_col,\
-                    np.ndarray[DOUBLE, ndim=1] res):
-    cdef int size_max = coord_row.shape[0]
-    cdef int n_features = m_2.shape[1]
-    cdef int i, j, row, col
+def compute_ward_dist(np.ndarray[DOUBLE, ndim=1, mode='c'] m_1,
+                      np.ndarray[DOUBLE, ndim=2, mode='c'] m_2,
+                      np.ndarray[INTP, ndim=1, mode='c'] coord_row,
+                      np.ndarray[INTP, ndim=1, mode='c'] coord_col,
+                      np.ndarray[DOUBLE, ndim=1, mode='c'] res):
+    cdef INTP size_max = coord_row.shape[0]
+    cdef INTP n_features = m_2.shape[1]
+    cdef INTP i, j, row, col
     cdef DOUBLE pa, n
+
     for i in range(size_max):
         row = coord_row[i]
         col = coord_col[i]
         n = (m_1[row] * m_1[col]) / (m_1[row] + m_1[col])
         pa = 0.
         for j in range(n_features):
-            pa += (m_2[row, j] / m_1[row] - m_2[col, j] / m_1[col])**2
+            pa += (m_2[row, j] / m_1[row] - m_2[col, j] / m_1[col]) ** 2
         res[i] = pa * n
     return res
 
 
-def _hc_get_descendent(int node, children, int n_leaves):
+def _hc_get_descendent(INTP node, children, INTP n_leaves):
     """
     Function returning all the descendent leaves of a set of nodes in the tree.
 
     Parameters
     ----------
-    node : int
+    node : integer
         The node for which we want the descendents.
 
-    children : list of pairs. Length of n_nodes
+    children : list of pairs, length n_nodes
         The children of each non-leaf node. Values less than `n_samples` refer
         to leaves of the tree. A greater value `i` indicates a node with
         children `children[i - n_samples]`.
 
-    n_leaves : int
+    n_leaves : integer
         Number of leaves.
 
     Returns
@@ -56,11 +60,12 @@ def _hc_get_descendent(int node, children, int n_leaves):
     if node < n_leaves:
         return ind
     descendent = []
+
     # It is actually faster to do the accounting of the number of
     # elements is the list ourselves: len is a lengthy operation on a
     # chained list
-    cdef int n_indices = 1
-    cdef int i
+    cdef INTP i, n_indices = 1
+
     while n_indices:
         i = ind.pop()
         if i < n_leaves:
@@ -74,29 +79,29 @@ def _hc_get_descendent(int node, children, int n_leaves):
 
 @cython.boundscheck(False)
 @cython.wraparound(False)
-def hc_get_heads(np.ndarray[INT, ndim=1] parents, copy=True):
-    """ Return the heads of the forest, as defined by parents
-    
+def hc_get_heads(np.ndarray[INTP, ndim=1] parents, copy=True):
+    """Returns the heads of the forest, as defined by parents.
+
     Parameters
-    ===========
-    parents: array of integers
+    ----------
+    parents : array of integers
         The parent structure defining the forest (ensemble of trees)
-    copy: boolean
+    copy : boolean
         If copy is False, the input 'parents' array is modified inplace
 
     Returns
-    =======
-    heads: array of integers of same shape as parents
+    -------
+    heads : array of integers of same shape as parents
         The indices in the 'parents' of the tree heads
 
     """
-    cdef unsigned int parent, node0, node, size
+    cdef INTP parent, node0, node, size
     if copy:
         parents = np.copy(parents)
     size = parents.size
-    for node0 in range(size):
-        # Start from the top of the tree and go down
-        node0 = size - node0 - 1
+
+    # Start from the top of the tree and go down
+    for node0 in range(size - 1, -1, -1):
         node = node0
         parent = parents[node]
         while parent != node:
@@ -108,25 +113,26 @@ def hc_get_heads(np.ndarray[INT, ndim=1] parents, copy=True):
 
 @cython.boundscheck(False)
 @cython.wraparound(False)
-def _get_parents(nodes, heads, np.ndarray[INT, ndim=1] parents,
-                 np.ndarray[INT8, ndim=1] not_visited):
-    """ Return the heads of the given nodes, as defined by parents
-    
-    Modifies in-place 'heads' and 'not_visited'
+def _get_parents(nodes, heads, np.ndarray[INTP, ndim=1] parents,
+                 np.ndarray[INT8, ndim=1, mode='c'] not_visited):
+    """Returns the heads of the given nodes, as defined by parents.
+
+    Modifies 'heads' and 'not_visited' in-place.
 
     Parameters
-    ===========
-    nodes: list of integers
+    ----------
+    nodes : list of integers
         The nodes to start from
-    heads: list of integers
+    heads : list of integers
         A list to hold the results (modified inplace)
-    parents: array of integers
+    parents : array of integers
         The parent structure defining the tree
-    not_visited:
+    not_visited
         The tree nodes to consider (modified inplace)
 
     """
-    cdef unsigned int parent, node
+    cdef INTP parent, node
+
     for node in nodes:
         parent = parents[node]
         while parent != node:
diff --git a/sklearn/cluster/hierarchical.py b/sklearn/cluster/hierarchical.py
index 3d4b9165dd9e9813699ff73aa381b42994e5b613..8e101f3f63c90b316cfc7b92e21ea1326ec18325 100644
--- a/sklearn/cluster/hierarchical.py
+++ b/sklearn/cluster/hierarchical.py
@@ -95,7 +95,7 @@ def ward_tree(X, connectivity=None, n_components=None, copy=True,
                           'structured Ward clustering (i.e. with '
                           'explicit connectivity.', stacklevel=2)
         out = hierarchy.ward(X)
-        children_ = out[:, :2].astype(np.int)
+        children_ = out[:, :2].astype(np.intp)
         return children_, 1, n_samples, None
 
     # Compute the number of nodes
@@ -140,27 +140,27 @@ def ward_tree(X, connectivity=None, n_components=None, copy=True,
         coord_row.extend(len(row) * [ind, ])
         coord_col.extend(row)
 
-    coord_row = np.array(coord_row, dtype=np.int)
-    coord_col = np.array(coord_col, dtype=np.int)
+    coord_row = np.array(coord_row, dtype=np.intp, order='C')
+    coord_col = np.array(coord_col, dtype=np.intp, order='C')
 
     # build moments as a list
-    moments_1 = np.zeros(n_nodes)
+    moments_1 = np.zeros(n_nodes, order='C')
     moments_1[:n_samples] = 1
-    moments_2 = np.zeros((n_nodes, n_features))
+    moments_2 = np.zeros((n_nodes, n_features), order='C')
     moments_2[:n_samples] = X
-    inertia = np.empty(len(coord_row), dtype=np.float)
+    inertia = np.empty(len(coord_row), dtype=np.float, order='C')
     _hierarchical.compute_ward_dist(moments_1, moments_2, coord_row, coord_col,
                                     inertia)
     inertia = list(six.moves.zip(inertia, coord_row, coord_col))
     heapify(inertia)
 
     # prepare the main fields
-    parent = np.arange(n_nodes, dtype=np.int)
+    parent = np.arange(n_nodes, dtype=np.intp)
     heights = np.zeros(n_nodes)
     used_node = np.ones(n_nodes, dtype=bool)
     children = []
 
-    not_visited = np.empty(n_nodes, dtype=np.int8)
+    not_visited = np.empty(n_nodes, dtype=np.int8, order='C')
 
     # recursive merge loop
     for k in range(n_samples, n_nodes):
@@ -186,11 +186,11 @@ def ward_tree(X, connectivity=None, n_components=None, copy=True,
         # List comprehension is faster than a for loop
         [A[l].append(k) for l in coord_col]
         A.append(coord_col)
-        coord_col = np.array(coord_col, dtype=np.int)
-        coord_row = np.empty_like(coord_col)
+        coord_col = np.array(coord_col, dtype=np.intp, order='C')
+        coord_row = np.empty(coord_col.shape, dtype=np.intp, order='C')
         coord_row.fill(k)
         n_additions = len(coord_row)
-        ini = np.empty(n_additions, dtype=np.float)
+        ini = np.empty(n_additions, dtype=np.float, order='C')
 
         _hierarchical.compute_ward_dist(moments_1, moments_2,
                                         coord_row, coord_col, ini)
@@ -268,7 +268,7 @@ def _hc_cut(n_clusters, children, n_leaves):
         # Insert the 2 children and remove the largest node
         heappush(nodes, -these_children[0])
         heappushpop(nodes, -these_children[1])
-    label = np.zeros(n_leaves, dtype=np.int)
+    label = np.zeros(n_leaves, dtype=np.intp)
     for i, node in enumerate(nodes):
         label[_hierarchical._hc_get_descendent(-node, children, n_leaves)] = i
     return label
diff --git a/sklearn/cluster/tests/test_hierarchical.py b/sklearn/cluster/tests/test_hierarchical.py
index 2121eef7d416577767d223c247c0aefe817264c6..8c4f06598bae38db622cccc2801290bb8e512d3e 100644
--- a/sklearn/cluster/tests/test_hierarchical.py
+++ b/sklearn/cluster/tests/test_hierarchical.py
@@ -87,6 +87,8 @@ def test_ward_clustering():
     clustering.fit(X)
     labels = clustering.labels_
     assert_true(np.size(np.unique(labels)) == 10)
+    # Turn caching off now
+    clustering = Ward(n_clusters=10, connectivity=connectivity)
     # Check that we obtain the same solution with early-stopping of the
     # tree building
     clustering.compute_full_tree = False
diff --git a/sklearn/metrics/__init__.py b/sklearn/metrics/__init__.py
index f3aca8f62b115d543d12fd4b6da550aeba28d357..1b63fc1c8bb7a9c29f38101212fd01d8bd97e4b4 100644
--- a/sklearn/metrics/__init__.py
+++ b/sklearn/metrics/__init__.py
@@ -6,7 +6,7 @@ and pairwise metrics and distance computations.
 from .metrics import (accuracy_score,
                       average_precision_score,
                       auc,
-                      auc_score,
+                      roc_auc_score,
                       classification_report,
                       confusion_matrix,
                       explained_variance_score,
@@ -31,6 +31,9 @@ from .metrics import (accuracy_score,
 from .metrics import zero_one
 from .metrics import zero_one_score
 
+# Deprecated in 0.16
+from .metrics import auc_score
+
 from .scorer import make_scorer, SCORERS
 
 from . import cluster
@@ -54,7 +57,7 @@ __all__ = ['accuracy_score',
            'adjusted_mutual_info_score',
            'adjusted_rand_score',
            'auc',
-           'auc_score',
+           'roc_auc_score',
            'average_precision_score',
            'classification_report',
            'cluster',
diff --git a/sklearn/metrics/metrics.py b/sklearn/metrics/metrics.py
index 982f34e2ac9abd000e5d36afe1d1d70509e565f4..99c2a4d287b0dbac4df4c396df5cae1211d357ec 100644
--- a/sklearn/metrics/metrics.py
+++ b/sklearn/metrics/metrics.py
@@ -133,7 +133,7 @@ def auc(x, y, reorder=False):
     """Compute Area Under the Curve (AUC) using the trapezoidal rule
 
     This is a general function, given points on a curve.  For computing the
-    area under the ROC-curve, see :func:`auc_score`.
+    area under the ROC-curve, see :func:`roc_auc_score`.
 
     Parameters
     ----------
@@ -163,7 +163,10 @@ def auc(x, y, reorder=False):
 
     See also
     --------
-    auc_score : Computes the area under the ROC curve
+    roc_auc_score : Computes the area under the ROC curve
+
+    precision_recall_curve :
+        Compute precision-recall pairs for different probability thresholds
 
     """
     x, y = check_arrays(x, y)
@@ -292,7 +295,7 @@ def average_precision_score(y_true, y_score):
 
     See also
     --------
-    auc_score : Area under the ROC curve
+    roc_auc_score : Area under the ROC curve
 
     precision_recall_curve :
         Compute precision-recall pairs for different probability thresholds
@@ -310,7 +313,8 @@ def average_precision_score(y_true, y_score):
     precision, recall, thresholds = precision_recall_curve(y_true, y_score)
     return auc(recall, precision)
 
-
+@deprecated("Function 'auc_score' has been renamed to "
+            "'roc_auc_score' and will be removed in release 0.16.")
 def auc_score(y_true, y_score):
     """Compute Area Under the Curve (AUC) from prediction scores
 
@@ -350,6 +354,49 @@ def auc_score(y_true, y_score):
     >>> auc_score(y_true, y_scores)
     0.75
 
+    """
+    return roc_auc_score(y_true, y_score)
+
+
+def roc_auc_score(y_true, y_score):
+    """Compute Area Under the Curve (AUC) from prediction scores
+
+    Note: this implementation is restricted to the binary classification task.
+
+    Parameters
+    ----------
+
+    y_true : array, shape = [n_samples]
+        True binary labels.
+
+    y_score : array, shape = [n_samples]
+        Target scores, can either be probability estimates of the positive
+        class, confidence values, or binary decisions.
+
+    Returns
+    -------
+    auc : float
+
+    References
+    ----------
+    .. [1] `Wikipedia entry for the Receiver operating characteristic
+            <http://en.wikipedia.org/wiki/Receiver_operating_characteristic>`_
+
+    See also
+    --------
+    average_precision_score : Area under the precision-recall curve
+
+    roc_curve : Compute Receiver operating characteristic (ROC)
+
+    Examples
+    --------
+    >>> import numpy as np
+    >>> from sklearn.metrics import roc_auc_score
+    >>> y_true = np.array([0, 0, 1, 1])
+    >>> y_scores = np.array([0.1, 0.4, 0.35, 0.8])
+    >>> roc_auc_score(y_true, y_scores)
+    0.75
+
     """
     if len(np.unique(y_true)) != 2:
         raise ValueError("AUC is defined for binary classification only")
@@ -593,7 +640,7 @@ def roc_curve(y_true, y_score, pos_label=None):
 
     See also
     --------
-    auc_score : Compute Area Under the Curve (AUC) from prediction scores
+    roc_auc_score : Compute Area Under the Curve (AUC) from prediction scores
 
     Notes
     -----
diff --git a/sklearn/metrics/scorer.py b/sklearn/metrics/scorer.py
index fb4a55b36b955b4dd7f8409a89e7176dce180d72..e5c829cad394ddda9c5d82b61322ea202cf57fc5 100644
--- a/sklearn/metrics/scorer.py
+++ b/sklearn/metrics/scorer.py
@@ -23,7 +23,7 @@ from warnings import warn
 import numpy as np
 
 from . import (r2_score, mean_squared_error, accuracy_score, f1_score,
-               auc_score, average_precision_score, precision_score,
+               roc_auc_score, average_precision_score, precision_score,
                recall_score, log_loss)
 
 from .cluster import adjusted_rand_score
@@ -253,8 +253,8 @@ accuracy_scorer = make_scorer(accuracy_score)
 f1_scorer = make_scorer(f1_score)
 
 # Score functions that need decision values
-auc_scorer = make_scorer(auc_score, greater_is_better=True,
-                         needs_threshold=True)
+roc_auc_scorer = make_scorer(roc_auc_score, greater_is_better=True,
+                             needs_threshold=True)
 average_precision_scorer = make_scorer(average_precision_score,
                                        needs_threshold=True)
 precision_scorer = make_scorer(precision_score)
@@ -269,7 +269,7 @@ adjusted_rand_scorer = make_scorer(adjusted_rand_score)
 
 SCORERS = dict(r2=r2_scorer,
                mean_squared_error=mean_squared_error_scorer,
-               accuracy=accuracy_scorer, f1=f1_scorer, roc_auc=auc_scorer,
+               accuracy=accuracy_scorer, f1=f1_scorer, roc_auc=roc_auc_scorer,
                average_precision=average_precision_scorer,
                precision=precision_scorer, recall=recall_scorer,
                log_loss=log_loss_scorer,
diff --git a/sklearn/metrics/tests/test_metrics.py b/sklearn/metrics/tests/test_metrics.py
index aef165e291a88ce59ed52ac411049a7408251f97..5a7dec3783cd2db7bc702fbff16dd2b784ec51a1 100644
--- a/sklearn/metrics/tests/test_metrics.py
+++ b/sklearn/metrics/tests/test_metrics.py
@@ -46,6 +46,7 @@ from sklearn.metrics import (accuracy_score,
                              precision_score,
                              recall_score,
                              r2_score,
+                             roc_auc_score,
                              roc_curve,
                              zero_one,
                              zero_one_score,
@@ -106,7 +107,7 @@ CLASSIFICATION_METRICS = {
 }
 
 THRESHOLDED_METRICS = {
-    "auc_score": auc_score,
+    "roc_auc_score": roc_auc_score,
     "average_precision_score": average_precision_score,
 }
 
@@ -299,14 +300,33 @@ def make_prediction(dataset=None, binary=False):
     return y_true, y_pred, probas_pred
 
 
+def _auc(y_true, y_score):
+    pos_label = np.unique(y_true)[1]
+
+    # Count the number of times positive samples are correctly ranked above
+    # negative samples.
+    pos = y_score[y_true == pos_label]
+    neg = y_score[y_true != pos_label]
+    diff_matrix = pos.reshape(1, -1) - neg.reshape(-1, 1)
+    n_correct = np.sum(diff_matrix > 0)
+
+    return n_correct / float(len(pos) * len(neg))
+
+
 def test_roc_curve():
     """Test Area under Receiver Operating Characteristic (ROC) curve"""
     y_true, _, probas_pred = make_prediction(binary=True)
 
     fpr, tpr, thresholds = roc_curve(y_true, probas_pred)
     roc_auc = auc(fpr, tpr)
-    assert_array_almost_equal(roc_auc, 0.90, decimal=2)
-    assert_almost_equal(roc_auc, auc_score(y_true, probas_pred))
+    expected_auc = _auc(y_true, probas_pred)
+    assert_array_almost_equal(roc_auc, expected_auc, decimal=2)
+    assert_almost_equal(roc_auc, roc_auc_score(y_true, probas_pred))
+
+    with warnings.catch_warnings(record=True):
+        assert_almost_equal(roc_auc, auc_score(y_true, probas_pred))
+
+
     assert_equal(fpr.shape, tpr.shape)
     assert_equal(fpr.shape, thresholds.shape)
 
@@ -461,7 +481,7 @@ def test_auc_errors():
 
 
 def test_auc_score_non_binary_class():
-    """Test that auc_score function returns an error when trying to compute AUC
+    """Test that roc_auc_score function returns an error when trying to compute AUC
     for non-binary class values.
     """
     rng = check_random_state(404)
@@ -469,18 +489,39 @@ def test_auc_score_non_binary_class():
     # y_true contains only one class value
     y_true = np.zeros(10, dtype="int")
     assert_raise_message(ValueError, "AUC is defined for binary "
-                         "classification only", auc_score, y_true, y_pred)
+                         "classification only", roc_auc_score, y_true, y_pred)
     y_true = np.ones(10, dtype="int")
     assert_raise_message(ValueError, "AUC is defined for binary "
-                         "classification only", auc_score, y_true, y_pred)
+                         "classification only", roc_auc_score, y_true, y_pred)
     y_true = -np.ones(10, dtype="int")
     assert_raise_message(ValueError, "AUC is defined for binary "
-                         "classification only", auc_score, y_true, y_pred)
+                         "classification only", roc_auc_score, y_true, y_pred)
     # y_true contains three different class values
     y_true = rng.randint(0, 3, size=10)
     assert_raise_message(ValueError, "AUC is defined for binary "
-                         "classification only", auc_score, y_true, y_pred)
+                         "classification only", roc_auc_score, y_true, y_pred)
 
+    with warnings.catch_warnings(record=True):
+        rng = check_random_state(404)
+        y_pred = rng.rand(10)
+        # y_true contains only one class value
+        y_true = np.zeros(10, dtype="int")
+        assert_raise_message(ValueError, "AUC is defined for binary "
+                             "classification only", auc_score,
+                             y_true, y_pred)
+        y_true = np.ones(10, dtype="int")
+        assert_raise_message(ValueError, "AUC is defined for binary "
+                             "classification only", auc_score, y_true,
+                             y_pred)
+        y_true = -np.ones(10, dtype="int")
+        assert_raise_message(ValueError, "AUC is defined for binary "
+                             "classification only", auc_score, y_true,
+                             y_pred)
+        # y_true contains three different class values
+        y_true = rng.randint(0, 3, size=10)
+        assert_raise_message(ValueError, "AUC is defined for binary "
+                             "classification only", auc_score, y_true,
+                             y_pred)
 
 def test_precision_recall_f1_score_binary():
     """Test Precision Recall and F1 Score for binary classification task"""
@@ -871,16 +912,23 @@ def test_precision_recall_curve_errors():
 
 
 def test_score_scale_invariance():
-    # Test that average_precision_score and auc_score are invariant by
+    # Test that average_precision_score and roc_auc_score are invariant by
     # the scaling or shifting of probabilities
     y_true, _, probas_pred = make_prediction(binary=True)
 
-    roc_auc = auc_score(y_true, probas_pred)
-    roc_auc_scaled = auc_score(y_true, 100 * probas_pred)
-    roc_auc_shifted = auc_score(y_true, probas_pred - 10)
+    roc_auc = roc_auc_score(y_true, probas_pred)
+    roc_auc_scaled = roc_auc_score(y_true, 100 * probas_pred)
+    roc_auc_shifted = roc_auc_score(y_true, probas_pred - 10)
     assert_equal(roc_auc, roc_auc_scaled)
     assert_equal(roc_auc, roc_auc_shifted)
 
+    with warnings.catch_warnings():
+        roc_auc = auc_score(y_true, probas_pred)
+        roc_auc_scaled = auc_score(y_true, 100 * probas_pred)
+        roc_auc_shifted = auc_score(y_true, probas_pred - 10)
+        assert_equal(roc_auc, roc_auc_scaled)
+        assert_equal(roc_auc, roc_auc_shifted)
+
     pr_auc = average_precision_score(y_true, probas_pred)
     pr_auc_scaled = average_precision_score(y_true, 100 * probas_pred)
     pr_auc_shifted = average_precision_score(y_true, probas_pred - 10)
@@ -912,7 +960,7 @@ def test_losses():
                  1 - zero_one_loss(y_true, y_pred))
 
     with warnings.catch_warnings(record=True):
-    # Throw deprecated warning
+        # Throw deprecated warning
         assert_equal(zero_one_score(y_true, y_pred),
                      1 - zero_one_loss(y_true, y_pred))
 
diff --git a/sklearn/metrics/tests/test_score_objects.py b/sklearn/metrics/tests/test_score_objects.py
index 8c4eb4e275e8d8ab1ad54b780ef54fff62c190f6..040a24fafbd66f54a8a86471d340e80b597371dd 100644
--- a/sklearn/metrics/tests/test_score_objects.py
+++ b/sklearn/metrics/tests/test_score_objects.py
@@ -3,7 +3,7 @@ import pickle
 from sklearn.utils.testing import assert_almost_equal
 from sklearn.utils.testing import assert_raises
 
-from sklearn.metrics import (f1_score, r2_score, auc_score, fbeta_score,
+from sklearn.metrics import (f1_score, r2_score, roc_auc_score, fbeta_score,
                              log_loss)
 from sklearn.metrics.cluster import adjusted_rand_score
 from sklearn.metrics import make_scorer, SCORERS
@@ -67,8 +67,8 @@ def test_thresholded_scorers():
     clf = LogisticRegression(random_state=0)
     clf.fit(X_train, y_train)
     score1 = SCORERS['roc_auc'](clf, X_test, y_test)
-    score2 = auc_score(y_test, clf.decision_function(X_test))
-    score3 = auc_score(y_test, clf.predict_proba(X_test)[:, 1])
+    score2 = roc_auc_score(y_test, clf.decision_function(X_test))
+    score3 = roc_auc_score(y_test, clf.predict_proba(X_test)[:, 1])
     assert_almost_equal(score1, score2)
     assert_almost_equal(score1, score3)
 
@@ -80,7 +80,7 @@ def test_thresholded_scorers():
     clf = DecisionTreeClassifier()
     clf.fit(X_train, y_train)
     score1 = SCORERS['roc_auc'](clf, X_test, y_test)
-    score2 = auc_score(y_test, clf.predict_proba(X_test)[:, 1])
+    score2 = roc_auc_score(y_test, clf.predict_proba(X_test)[:, 1])
     assert_almost_equal(score1, score2)
 
     # Test that an exception is raised on more than two classes
diff --git a/sklearn/pls.py b/sklearn/pls.py
index 68c0a2afa7d3940d54fdb82396b37f91a9a9f15f..db1aeb043ed11f7a7c1517f94bc339ea7a1789db 100644
--- a/sklearn/pls.py
+++ b/sklearn/pls.py
@@ -4,4 +4,4 @@ from .cross_decomposition import CCA, PLSSVD, PLSRegression, PLSCanonical
 
 
 warnings.warn("This module has been moved to cross_decomposition and will be "
-              "removed in 0.15", DeprecationWarning)
+              "removed in 0.16", DeprecationWarning)
diff --git a/sklearn/preprocessing/label.py b/sklearn/preprocessing/label.py
index 69922e10b2b017c61faca890d6fe12a7a249dc5a..79c3e494d59c52f0580e02f7b4039626f269f5f9 100644
--- a/sklearn/preprocessing/label.py
+++ b/sklearn/preprocessing/label.py
@@ -66,7 +66,7 @@ class LabelEncoder(BaseEstimator, TransformerMixin):
 
     def _check_fitted(self):
         if not hasattr(self, "classes_"):
-            raise ValueError("LabelNormalizer was not fitted yet.")
+            raise ValueError("LabelEncoder was not fitted yet.")
 
     def fit(self, y):
         """Fit label encoder
diff --git a/sklearn/tests/test_grid_search.py b/sklearn/tests/test_grid_search.py
index c7c3a70c7d035bcc0104f2ed14ebd759863ae98d..c932b7bb10b6d7b248de515df4b968d386ce0857 100644
--- a/sklearn/tests/test_grid_search.py
+++ b/sklearn/tests/test_grid_search.py
@@ -36,7 +36,7 @@ from sklearn.tree import DecisionTreeClassifier
 from sklearn.cluster import KMeans, MeanShift
 from sklearn.metrics import f1_score
 from sklearn.metrics import make_scorer
-from sklearn.metrics import auc_score
+from sklearn.metrics import roc_auc_score
 from sklearn.cross_validation import KFold, StratifiedKFold
 
 
@@ -572,7 +572,7 @@ def test_grid_search_score_consistency():
                 if score == "f1":
                     correct_score = f1_score(y[test], clf.predict(X[test]))
                 elif score == "roc_auc":
-                    correct_score = auc_score(y[test],
+                    correct_score = roc_auc_score(y[test],
                                               clf.decision_function(X[test]))
                 assert_almost_equal(correct_score, scores[i])
                 i += 1
diff --git a/sklearn/tests/test_random_projection.py b/sklearn/tests/test_random_projection.py
index 33c91f7ce33113a0ad6932cdc311933f23f53b53..d214c4156f39db0c3138f0c11081bddab0bf2ef5 100644
--- a/sklearn/tests/test_random_projection.py
+++ b/sklearn/tests/test_random_projection.py
@@ -53,7 +53,7 @@ def densify(matrix):
 
 
 n_samples, n_features = (10, 1000)
-n_nonzeros = n_samples * n_features / 100.
+n_nonzeros = int(n_samples * n_features / 100.)
 data, data_csr = make_sparse_random_data(n_samples, n_features, n_nonzeros)