Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .pylintdict
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ natom
nd
ndarray
nelec
networkx
neuropeptide
nicholas
nielsen
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,15 @@

import numpy as np

from retworkx import NodeIndices, PyGraph, WeightedEdgeList, adjacency_matrix
from retworkx import NodeIndices, PyGraph, WeightedEdgeList, adjacency_matrix, networkx_converter
from retworkx.visualization import mpl_draw

from qiskit.utils import optionals as _optionals

if _optionals.HAS_NETWORKX:
# pylint: disable=unused-import
import networkx as nx

if _optionals.HAS_MATPLOTLIB:
# pylint: disable=unused-import
from matplotlib.axes import Axes
Expand Down Expand Up @@ -109,15 +113,21 @@ class LatticeDrawStyle:
class Lattice:
"""General Lattice."""

def __init__(self, graph: PyGraph) -> None:
def __init__(self, graph: Union[PyGraph, "nx.Graph"]) -> None:
"""
Args:
graph: Input graph for Lattice. `graph.multigraph` must be False.
graph: Input graph for Lattice. Can be provided as ``retworkx.PyGraph``, which is
used internally, or, for convenience, as ``networkx.Graph``. The graph
cannot be a multigraph.

Raises:
ValueError: If the input graph is a multigraph.
ValueError: If the graph edges are non-numeric.
"""
if not isinstance(graph, PyGraph):
_optionals.HAS_NETWORKX.require_now("Lattice construction from networkx.Graph")
graph = networkx_converter(graph)

if graph.multigraph:
raise ValueError(
f"Invalid `graph.multigraph` {graph.multigraph} is given. "
Expand Down
17 changes: 17 additions & 0 deletions releasenotes/notes/lattice-from-networkx-20c7c8119af77f36.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
features:
- |
Add the option to initialize a :class:`~qiskit_nature.problems.second_quantization.lattice.Lattice`
from a ``networkx.Graph`` object, which will be internally converted to a ``retworkx.PyGraph``
for performance.

For example, you can now construct a lattice as

.. code-block:: python

import networkx as nx
from qiskit_nature.problems.second_quantization.lattice import Lattice

# 3-regular random graph on 6 nodes
graph = nx.generators.random_graphs.random_regular_graph(3, n=6)
lattice = Lattice(graph)
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,19 @@
"""Test for Lattice."""
from test import QiskitNatureTestCase

import unittest
import numpy as np
from numpy.testing import assert_array_equal

from retworkx import PyGraph, is_isomorphic

from qiskit.utils import optionals as _optionals

from qiskit_nature.problems.second_quantization.lattice import Lattice

if _optionals.HAS_NETWORKX:
import networkx as nx


class TestLattice(QiskitNatureTestCase):
"""Test Lattice."""
Expand Down Expand Up @@ -134,6 +141,22 @@ def test_to_adjacency_matrix(self):
target_matrix = np.array([[0, 1, 1], [1, 0, 0], [1, 0, 1]])
assert_array_equal(lattice.to_adjacency_matrix(), target_matrix)

@unittest.skipIf(not _optionals.HAS_NETWORKX, "networkx not available.")
def test_from_networkx(self):
"""Test initialization from a networkx graph."""
graph = nx.Graph()
graph.add_nodes_from(range(5))
graph.add_edges_from([(i, i + 1) for i in range(4)])
lattice = Lattice(graph)

target_graph = PyGraph()
target_graph.add_nodes_from(range(5))
target_graph.add_edges_from([(i, i + 1, 1) for i in range(4)])

self.assertTrue(
is_isomorphic(lattice.graph, target_graph, edge_matcher=lambda x, y: x == y)
)

def test_nonnumeric_weight_raises(self):
"""Test the initialization with a graph with non-numeric edge weights raises."""
graph = PyGraph(multigraph=False)
Expand Down