mirror of https://github.com/Qiskit/qiskit.git
Obtain a reduced coupling_map for a subgraph of a device (#2225)
* reduced_coupling_map * style * new headers * make reduce a CouplingMap method * get rid of 'backend' * fix test for python version dependent ordering * fix idx
This commit is contained in:
parent
1b4a6976b7
commit
25bed6f9f0
|
@ -23,8 +23,9 @@ CNOT gates. The object has a distance function that can be used to map quantum c
|
|||
onto a device with this coupling.
|
||||
"""
|
||||
import numpy as np
|
||||
import scipy.sparse as sp
|
||||
import scipy.sparse.csgraph as cs
|
||||
import networkx as nx
|
||||
|
||||
from qiskit.transpiler.exceptions import CouplingError
|
||||
|
||||
|
||||
|
@ -185,6 +186,45 @@ class CouplingMap:
|
|||
raise CouplingError(
|
||||
"Nodes %s and %s are not connected" % (str(physical_qubit1), str(physical_qubit2)))
|
||||
|
||||
def reduce(self, mapping):
|
||||
"""Returns a reduced coupling map that
|
||||
corresponds to the subgraph of qubits
|
||||
selected in the mapping.
|
||||
|
||||
Args:
|
||||
mapping (list): A mapping of reduced qubits to device
|
||||
qubits.
|
||||
|
||||
Returns:
|
||||
CouplingMap: A reduced coupling_map for the selected qubits.
|
||||
|
||||
Raises:
|
||||
CouplingError: Reduced coupling map must be connected.
|
||||
"""
|
||||
reduced_qubits = len(mapping)
|
||||
inv_map = [None]*(max(mapping)+1)
|
||||
for idx, val in enumerate(mapping):
|
||||
inv_map[val] = idx
|
||||
|
||||
reduced_cmap = []
|
||||
|
||||
for edge in self.get_edges():
|
||||
if edge[0] in mapping and edge[1] in mapping:
|
||||
reduced_cmap.append([inv_map[edge[0]], inv_map[edge[1]]])
|
||||
|
||||
# Verify coupling_map is connected
|
||||
rows = np.array([edge[0] for edge in reduced_cmap], dtype=int)
|
||||
cols = np.array([edge[1] for edge in reduced_cmap], dtype=int)
|
||||
data = np.ones_like(rows)
|
||||
|
||||
mat = sp.coo_matrix((data, (rows, cols)),
|
||||
shape=(reduced_qubits, reduced_qubits)).tocsr()
|
||||
|
||||
if cs.connected_components(mat)[0] != 1:
|
||||
raise CouplingError('coupling_map must be connected.')
|
||||
|
||||
return CouplingMap(reduced_cmap)
|
||||
|
||||
def __str__(self):
|
||||
"""Return a string representation of the coupling graph."""
|
||||
string = ""
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
from qiskit.transpiler import CouplingMap
|
||||
from qiskit.transpiler.exceptions import CouplingError
|
||||
from qiskit.test.mock import FakeRueschlikon
|
||||
from qiskit.test import QiskitTestCase
|
||||
|
||||
|
||||
|
@ -78,3 +79,22 @@ class CouplingTest(QiskitTestCase):
|
|||
self.assertEqual(coupling.physical_qubits, qubits_expected)
|
||||
self.assertEqual(coupling.get_edges(), edges_expected)
|
||||
self.assertEqual(2, coupling.distance(0, 2))
|
||||
|
||||
def test_successful_reduced_map(self):
|
||||
"""Generate a reduced map
|
||||
"""
|
||||
fake = FakeRueschlikon()
|
||||
cmap = fake.configuration().coupling_map
|
||||
coupling_map = CouplingMap(cmap)
|
||||
out = coupling_map.reduce([12, 11, 10, 9]).get_edges()
|
||||
ans = [(1, 2), (3, 2), (0, 1)]
|
||||
self.assertEqual(set(out), set(ans))
|
||||
|
||||
def test_failed_reduced_map(self):
|
||||
"""Generate a bad disconnected reduced map
|
||||
"""
|
||||
fake = FakeRueschlikon()
|
||||
cmap = fake.configuration().coupling_map
|
||||
coupling_map = CouplingMap(cmap)
|
||||
with self.assertRaises(CouplingError):
|
||||
coupling_map.reduce([12, 11, 10, 3])
|
||||
|
|
Loading…
Reference in New Issue