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
2 changes: 2 additions & 0 deletions .pylintdict
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,8 @@ mol
morse
mpl
mul
multi
multigraph
multinomial
mypy
namelist
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2021.
# (C) Copyright IBM 2021, 2022.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
Expand All @@ -11,11 +11,14 @@
# that they have been altered from the originals.

"""General Lattice."""

from copy import deepcopy
from dataclasses import asdict, dataclass
from typing import Callable, List, Optional, Sequence, Tuple, Union
import numbers

import numpy as np

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

Expand Down Expand Up @@ -113,17 +116,24 @@ def __init__(self, graph: PyGraph) -> None:
graph: Input graph for Lattice. `graph.multigraph` must be False.

Raises:
ValueError: If `graph.multigraph` is True for a given graph, it is invalid.
ValueError: If the input graph is a multigraph.
ValueError: If the graph edges are non-numeric.
"""
if graph.multigraph:
raise ValueError(
f"Invalid `graph.multigraph` {graph.multigraph} is given. "
"`graph.multigraph` must be `False`."
)
if graph.edges() == [None] * graph.num_edges():
weighted_edges = [edge + (1.0,) for edge in graph.edge_list()]
for start, end, weight in weighted_edges:
graph.update_edge(start, end, weight)

# validate the edge weights
for edge_index, edge in graph.edge_index_map().items():
weight = edge[2]
if weight is None or weight == {}:
# None or {} is updated to be 1
graph.update_edge_by_index(edge_index, 1)
elif not isinstance(weight, numbers.Number):
raise ValueError(f"Unsupported weight {weight} on edge with index {edge_index}.")

self._graph = graph

self.pos: Optional[dict] = None
Expand Down
21 changes: 21 additions & 0 deletions releasenotes/notes/lattice-edge-typecheck-3f5b4896fe26c8dc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
fixes:
- |
Add a type check for the input graphs to
:class:`~qiskit_nature.problems.second_quantization.lattice.lattices.Lattice`
which asserts that the edge weights of the graph are either numeric (or one of `None` or `{}`
which is replaced by a unit weight). This prevents possibly unexpected errors in the
application stack when an operator is constructed from the lattice.

In particular, the following now raises a `ValueError`:

.. code-block:: python

from retworkx import PyGraph
from qiskit_nature.problems.second_quantization.lattice import Lattice

graph = PyGraph(multigraph=False)
graph.add_nodes_from(range(3))
graph.add_edges_from([(0, 1, 1), (1, 2, "banana")]) # banana is not a valid weight!

lattice = Lattice(graph)
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2021.
# (C) Copyright IBM 2021, 2022.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
Expand Down Expand Up @@ -133,3 +133,29 @@ 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)

def test_nonnumeric_weight_raises(self):
"""Test the initialization with a graph with non-numeric edge weights raises."""
graph = PyGraph(multigraph=False)
graph.add_nodes_from(range(3))
graph.add_edges_from([(0, 1, 1), (1, 2, "banana")])

with self.assertRaises(ValueError):
_ = Lattice(graph)

def test_edges_removed(self):
"""Test the initialization with a graph where edges have been removed."""
graph = PyGraph(multigraph=False)
graph.add_nodes_from(range(3))
graph.add_edges_from([(0, 1, 1), (1, 2, 1)])
graph.remove_edge_from_index(0)

lattice = Lattice(graph)

target_graph = PyGraph(multigraph=False)
target_graph.add_nodes_from(range(3))
target_graph.add_edges_from([(1, 2, 1)])

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