Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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 @@ -276,6 +276,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