Repository: Qiskit/retworkx
Pull request #302 (2021-04-05 21:59:07)

Fix floyd_warshall_numpy dispatcher
<!--
⚠️ Your pull request title should be short detailed and understandable for all.
⚠️ If your pull request fixes an open issue, please link to the issue.

- [x] I ran rustfmt locally
- [x] I have added the tests to cover my changes.
- [x] I have updated the documentation accordingly.
- [x] I have read the CONTRIBUTING document.
-->

Fix bug found during #291 benchmarking. 

`floyd_warshall_numpy` was dispatching to the wrong function and calling `adjacency_matrix` instead of `graph_floyd_warshall_numpy` and `digraph_floyd_warshall_numpy`.

coveralls: ## Pull Request Test Coverage Report for [Build 720550595](https://coveralls.io/builds/38545222)

* **0** of **0**   changed or added relevant lines in **0** files are covered.
* No unchanged relevant lines lost coverage.
* Overall coverage remained the same at **96.686%**

---



|  Totals | [![Coverage Status](https://coveralls.io/builds/38545222/badge)](https://coveralls.io/builds/38545222) |
| :-- | --: |
| Change from base [Build 719210672](https://coveralls.io/builds/38531845): |  0.0% |
| Covered Lines: | 6155 |
| Relevant Lines: | 6366 |

---
##### 💛  - [Coveralls](https://coveralls.io)


Patch:
diff --git a/tests/releasenotes/notes/complement-361c90c7dda69df8.yaml b/releasenotes/notes/complement-361c90c7dda69df8.yaml
similarity index 100%
rename from tests/releasenotes/notes/complement-361c90c7dda69df8.yaml
rename to releasenotes/notes/complement-361c90c7dda69df8.yaml
diff --git a/releasenotes/notes/floyd-warshall-fix-d8ec2131dfaeab82.yaml b/releasenotes/notes/floyd-warshall-fix-d8ec2131dfaeab82.yaml
new file mode 100644
index 00000000..3a9eef02
--- /dev/null
+++ b/releasenotes/notes/floyd-warshall-fix-d8ec2131dfaeab82.yaml
@@ -0,0 +1,6 @@
+---
+fixes:
+  - |
+    Fix bug in :func:`~retworkx.floyd_warshall_numpy` in which the dispatcher mistakenly called 
+    :func:`~retworkx.adjacency_matrix` instead of :func:`~retworkx.graph_floyd_warshall_numpy`
+    and :func:`~retworkx.digraph_floyd_warshall_numpy`.
\ No newline at end of file
diff --git a/retworkx/__init__.py b/retworkx/__init__.py
index 2e7c462e..3e248fde 100644
--- a/retworkx/__init__.py
+++ b/retworkx/__init__.py
@@ -207,23 +207,23 @@ def _graph_all_simple_paths(graph, from_, to, min_depth=None, cutoff=None):
 
 @functools.singledispatch
 def floyd_warshall_numpy(graph, weight_fn=None, default_weight=1.0):
-    """Return the adjacency matrix for a graph object
+    """Find all-pairs shortest path lengths using Floyd's algorithm
 
-    In the case where there are multiple edges between nodes the value in the
-    output matrix will be the sum of the edges' weights.
+    Floyd's algorithm is used for finding shortest paths in dense graphs
+    or graphs with negative weights (where Dijkstra's algorithm fails).
 
-    :param graph: The graph used to generate the adjacency matrix from. Can
+    :param graph: The graph to run Floyd's algorithm on. Can
         either be a :class:`~retworkx.PyGraph` or :class:`~retworkx.PyDiGraph`
     :param callable weight_fn: A callable object (function, lambda, etc) which
         will be passed the edge object and expected to return a ``float``. This
         tells retworkx/rust how to extract a numerical weight as a ``float``
         for edge object. Some simple examples are::
 
-            adjacency_matrix(graph, weight_fn: lambda x: 1)
+            floyd_warshall_numpy(graph, weight_fn: lambda x: 1)
 
         to return a weight of 1 for all edges. Also::
 
-            adjacency_matrix(graph, weight_fn: lambda x: float(x))
+            floyd_warshall_numpy(graph, weight_fn: lambda x: float(x))
 
         to cast the edge object as a float as the weight. If this is not
         specified a default value (either ``default_weight`` or 1) will be used
@@ -231,22 +231,26 @@ def floyd_warshall_numpy(graph, weight_fn=None, default_weight=1.0):
     :param float default_weight: If ``weight_fn`` is not used this can be
         optionally used to specify a default weight to use for all edges.
 
-     :return: The adjacency matrix for the input dag as a numpy array
-     :rtype: numpy.ndarray
+    :returns: A matrix of shortest path distances between nodes. If there is no
+        path between two nodes then the corresponding matrix entry will be
+        ``np.inf``.
+    :rtype: numpy.ndarray
     """
     raise TypeError("Invalid Input Type %s for graph" % type(graph))
 
 
 @floyd_warshall_numpy.register(PyDiGraph)
 def _digraph_floyd_warshall_numpy(graph, weight_fn=None, default_weight=1.0):
-    return digraph_adjacency_matrix(graph, weight_fn=weight_fn,
-                                    default_weight=default_weight)
+    return digraph_floyd_warshall_numpy(
+        graph, weight_fn=weight_fn, default_weight=default_weight
+    )
 
 
 @floyd_warshall_numpy.register(PyGraph)
 def _graph_floyd_warshall_numpy(graph, weight_fn=None, default_weight=1.0):
-    return graph_adjacency_matrix(graph, weight_fn=weight_fn,
-                                  default_weight=default_weight)
+    return graph_floyd_warshall_numpy(
+        graph, weight_fn=weight_fn, default_weight=default_weight
+    )
 
 
 @functools.singledispatch


Test patch:
diff --git a/tests/test_dispatch.py b/tests/test_dispatch.py
index 61481918..6e9ee1b8 100644
--- a/tests/test_dispatch.py
+++ b/tests/test_dispatch.py
@@ -51,6 +51,13 @@ class TestDispatchPyGraph(unittest.TestCase):
         res = retworkx.floyd_warshall_numpy(self.graph)
         self.assertIsInstance(res, numpy.ndarray)
 
+        if self.class_type == "PyGraph":
+            expected_res = retworkx.graph_floyd_warshall_numpy(self.graph)
+        else:
+            expected_res = retworkx.digraph_floyd_warshall_numpy(self.graph)
+
+        self.assertTrue(numpy.array_equal(expected_res, res))
+
     def test_astar_shortest_path(self):
         res = retworkx.astar_shortest_path(self.graph, 0, lambda _: True,
                                            lambda _: 1, lambda _: 1)