Skip to content

Commit

Permalink
Linting and fixing test
Browse files Browse the repository at this point in the history
  • Loading branch information
jaygambetta authored and ajavadia committed Dec 19, 2018
1 parent 2cf3cfe commit ef58e5f
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 79 deletions.
15 changes: 6 additions & 9 deletions examples/python/commutation_relation.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
from qiskit import *
from qiskit.tools.visualization import *
from qiskit.converters import circuit_to_dag

from qiskit.transpiler import PassManager
from qiskit.transpiler.passes import CommutationAnalysis, CommutationTransformation
from qiskit.transpiler import transpile_dag
from qiskit.transpiler import transpile

qr = QuantumRegister(5, 'qr')
circuit = QuantumCircuit(qr)
Expand All @@ -21,14 +19,13 @@
circuit.cx(qr[2], qr[3])
circuit.cx(qr[3], qr[2])

dag = circuit_to_dag(circuit)
circuit.draw(interactive=True, output='latex')

dag_drawer(dag)
print(circuit.draw())

pm = PassManager()

pm.append([CommutationAnalysis(), CommutationTransformation()])

dag = transpile_dag(dag, pass_manager=pm)
dag_drawer(dag)
# TODO make it not needed to have a backend
backend_device = BasicAer.get_backend('qasm_simulator')
circuit = transpile(circuit, backend_device, pass_manager=pm)
print(circuit.draw())
6 changes: 3 additions & 3 deletions qiskit/dagcircuit/_dagcircuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -1468,9 +1468,9 @@ def collect_runs(self, namelist):
# Iterate through the nodes of self in topological order
# and form tuples containing sequences of gates
# on the same qubit(s).
ts = list(self.node_nums_in_topological_order())
nodes_seen = dict(zip(ts, [False] * len(ts)))
for node in ts:
tops_node = list(self.node_nums_in_topological_order())
nodes_seen = dict(zip(tops_node, [False] * len(tops_node)))
for node in tops_node:
nd = self.multi_graph.node[node]
if nd["type"] == "op" and nd["name"] in namelist \
and not nodes_seen[node]:
Expand Down
112 changes: 51 additions & 61 deletions qiskit/transpiler/passes/commutation_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
A rule-based analysis would be potentially faster, but more limited.
"""

import numpy as np
from collections import defaultdict
import numpy as np

from qiskit.transpiler._basepasses import AnalysisPass

Expand All @@ -40,10 +40,10 @@ def run(self, dag):
Run the pass on the DAG, and write the discovered commutation relations
into the property_set.
"""
ts = list(dag.node_nums_in_topological_order())
tops_node = list(dag.node_nums_in_topological_order())

# Initiation of the node_order
for num, node in enumerate(ts):
for num, node in enumerate(tops_node):
self.node_order[node] = num

# Initiate the commutation set
Expand All @@ -57,7 +57,7 @@ def run(self, dag):
self.property_set['commutation_set'][wire_name] = []

# Add edges to the dictionary for each qubit
for node in ts:
for node in tops_node:
for edge in dag.multi_graph.edges([node], data=True):

edge_name = edge[2]['name']
Expand All @@ -83,31 +83,22 @@ def run(self, dag):
self.property_set['commutation_set'][wire_name].append([node])

if node not in self.property_set['commutation_set'][wire_name][-1]:
if _commute(dag.multi_graph.node[node], dag.multi_graph.node[self.property_set['commutation_set'][wire_name][-1][-1]]):
test_node = self.property_set['commutation_set'][wire_name][-1][-1]
if _commute(dag.multi_graph.node[node], dag.multi_graph.node[test_node]):
self.property_set['commutation_set'][wire_name][-1].append(node)

else:
self.property_set['commutation_set'][wire_name].append([node])
temp_len = len(self.property_set['commutation_set'][wire_name])
self.property_set['commutation_set'][(node, wire_name)] = temp_len - 1

self.property_set['commutation_set'][(node, wire_name)] = len(self.property_set['commutation_set'][wire_name]) - 1

# Output the grouped set for testing
# for wire in dag.wires:
# wire_name = "{0}[{1}]".format(str(wire[0].name), str(wire[1]))
# print(wire_name)
# for group in self.property_set['commutation_set'][wire_name]:
# print(group)
def _get_node_order(node):
"""Get order of edges on a wire"""
return self.node_order[node]

def _GateMasterDef(name = '', para = None):
def _gate_master_def(name, para=None):
if name == 'h':
return 1. / np.sqrt(2) * np.array([[1.0, 1.0],
[1.0, -1.0]], dtype=np.complex)
if name == 'x':
return np.array([[0.0, 1.0],
[1.0,0.0]], dtype=np.complex)
[1.0, 0.0]], dtype=np.complex)
if name == 'y':
return np.array([[0.0, -1.0j],
[1.0j, 0.0]], dtype=np.complex)
Expand All @@ -128,10 +119,10 @@ def _GateMasterDef(name = '', para = None):
[0.0, 0.0, -1.0j, 0.0]], dtype=np.complex)
if name == 'z':
return np.array([[1.0, 0.0],
[0.0,-1.0]], dtype=np.complex)
[0.0, -1.0]], dtype=np.complex)
if name == 't':
return np.array([[1.0, 0.0],
[0.0,np.exp(1j * np.pi / 4.0)]], dtype=np.complex)
[0.0, np.exp(1j * np.pi / 4.0)]], dtype=np.complex)
if name == 's':
return np.array([[1.0, 0.0],
[0.0, np.exp(1j * np.pi / 2.0)]], dtype=np.complex)
Expand All @@ -154,64 +145,65 @@ def _GateMasterDef(name = '', para = None):
dtype=np.complex)
if name == 'u2':
return 1. / np.sqrt(2) * np.array(
[[1, -np.exp(1j * float(para[1]))],
[np.exp(1j * float(para[0])), np.exp(1j * (float(para[0]) + float(para[1])))]],
dtype=np.complex)
[[1, -np.exp(1j * float(para[1]))],
[np.exp(1j * float(para[0])), np.exp(1j * (float(para[0]) + float(para[1])))]],
dtype=np.complex)
if name == 'u3':
return 1./np.sqrt(2) * np.array(
[[np.cos(float(para[0]) / 2.),
-np.exp(1j * float(para[2])) * np.sin(float(para[0]) / 2.)],
[np.exp(1j * float(para[1])) * np.sin(float(para[0]) / 2.),
np.cos(float(para[0]) / 2.) * np.exp(1j * (float(para[2]) + float(para[1])))]],
dtype=np.complex)
[[np.cos(float(para[0]) / 2.),
-np.exp(1j * float(para[2])) * np.sin(float(para[0]) / 2.)],
[np.exp(1j * float(para[1])) * np.sin(float(para[0]) / 2.),
np.cos(float(para[0]) / 2.) * np.exp(1j * (float(para[2]) + float(para[1])))]],
dtype=np.complex)

if name == 'P0':
return np.array([[1.0, 0.0], [0.0,0.0]], dtype = np.complex)
return np.array([[1.0, 0.0], [0.0, 0.0]], dtype=np.complex)

if name == 'P1':
return np.array([[0.0, 0.0], [0.0,1.0]], dtype = np.complex)
return np.array([[0.0, 0.0], [0.0, 1.0]], dtype=np.complex)

if name == 'Id':
return np.identity(2)


return None

def _calc_product(node1, node2):

wire_num = len(set(node1["qargs"] + node2["qargs"]))
wires = sorted(list(map(lambda x: "{0}[{1}]".format(str(x[0].name), str(x[1])), list(set(node1["qargs"] + node2["qargs"])))))
final_U = np.identity(2 ** wire_num, dtype = np.complex)

wires = sorted(list(map(lambda x: "{0}[{1}]".format(str(x[0].name), str(x[1])),
list(set(node1["qargs"] + node2["qargs"])))))
final_unitary = np.identity(2 ** wire_num, dtype=np.complex)

for node in [node1, node2]:

qstate_list = [np.identity(2)] * wire_num

if node['name'] == 'cx' or node['name'] == 'cy' or node['name'] == 'cz':
qstate_list_ext = [np.identity(2)] * wire_num

node_ctrl = "{0}[{1}]".format(str(node["qargs"][0][0].name), str(node["qargs"][0][1]))
node_tgt = "{0}[{1}]".format(str(node["qargs"][1][0].name), str(node["qargs"][1][1]))
ctrl = wires.index(node_ctrl)
tgt = wires.index(node_tgt)

qstate_list[ctrl] = _GateMasterDef(name = 'P0')
qstate_list[tgt] = _GateMasterDef(name = 'Id')
qstate_list_ext[ctrl] = _GateMasterDef(name = 'P1')
if node['name'] == 'cx':
qstate_list_ext[tgt] = _GateMasterDef(name = 'x')
if node['name'] == 'cy':
qstate_list_ext[tgt] = _GateMasterDef(name = 'y')
if node['name'] == 'cz':
qstate_list_ext[tgt] = _GateMasterDef(name = 'z')

rt_list = [qstate_list] + [qstate_list_ext]

qstate_list_ext = [np.identity(2)] * wire_num

node_ctrl = "{0}[{1}]".format(str(node["qargs"][0][0].name), str(node["qargs"][0][1]))
node_tgt = "{0}[{1}]".format(str(node["qargs"][1][0].name), str(node["qargs"][1][1]))
ctrl = wires.index(node_ctrl)
tgt = wires.index(node_tgt)

qstate_list[ctrl] = _gate_master_def(name='P0')
qstate_list[tgt] = _gate_master_def(name='Id')
qstate_list_ext[ctrl] = _gate_master_def(name='P1')
if node['name'] == 'cx':
qstate_list_ext[tgt] = _gate_master_def(name='x')
if node['name'] == 'cy':
qstate_list_ext[tgt] = _gate_master_def(name='y')
if node['name'] == 'cz':
qstate_list_ext[tgt] = _gate_master_def(name='z')

rt_list = [qstate_list] + [qstate_list_ext]

else:

mat = _GateMasterDef(name = node['name'])
node_num = "{0}[{1}]".format(str(node["qargs"][0][0].name), str(node["qargs"][0][1]))
mat = _gate_master_def(name=node['name'], para=node['op'].param)
node_num = "{0}[{1}]".format(str(node["qargs"][0][0].name),
str(node["qargs"][0][1]))
qstate_list[wires.index(node_num)] = mat

rt_list = [qstate_list]
Expand All @@ -221,9 +213,8 @@ def _calc_product(node1, node2):
for state in rt_list:
crt = crt + _kron_list(state)

final_U = np.dot(crt, final_U)

return final_U
final_unitary = np.dot(crt, final_unitary)
return final_unitary

def _kron_list(args):
ret = args[0]
Expand All @@ -234,7 +225,6 @@ def _kron_list(args):
def _matrix_commute(node1, node2):
# Good for composite gates or any future
# user-defined gate of equal or less than 2 qubits.

if set(node1["qargs"]) & set(node2["qargs"]) == set():
return True

Expand Down
5 changes: 0 additions & 5 deletions qiskit/transpiler/passes/commutation_transformation.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@

from qiskit.transpiler._basepasses import TransformationPass
from qiskit.transpiler.passes import CommutationAnalysis
from qiskit.transpiler import AnalysisPass
import numpy as np


class CommutationTransformation(TransformationPass):
Expand Down Expand Up @@ -66,9 +64,6 @@ def run(self, dag):

for next_node in wire_commutation_set[c_set_ind + 1]:

nd = dag.multi_graph.node[node1]
next_nd = dag.multi_graph.node[next_node]

edge_on_wire = False
for temp_edge in dag.multi_graph.edges([node1], data=True):
if temp_edge[1] == next_node and temp_edge[2]['name'] == wire_name:
Expand Down
4 changes: 3 additions & 1 deletion test/python/transpiler/test_commutation_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,22 @@
import unittest

from qiskit import QuantumRegister, QuantumCircuit
from qiskit.dagcircuit import DAGCircuit
from qiskit.transpiler import PropertySet
from qiskit.transpiler.passes import CommutationAnalysis
from qiskit.converters import circuit_to_dag
from ..common import QiskitTestCase


class TestCommutationAnalysis(QiskitTestCase):
"""Test the Communttion pass."""

def setUp(self):

self.pass_ = CommutationAnalysis()
self.pset = self.pass_.property_set = PropertySet()

def test_commutation_set_property_is_created(self):
"""Test property is created"""
qr = QuantumRegister(3, 'qr')
circuit = QuantumCircuit(qr)
circuit.h(qr)
Expand Down Expand Up @@ -216,6 +217,7 @@ def test_jordan_wigner_type_circuit(self):
self.assertEqual(self.pset["commutation_set"]["qr[5]"], [[11], [17], [18], [19], [12]])

def test_all_commute_circuit(self):
"""Test circuit with that all commute"""
qr = QuantumRegister(5, 'qr')
circuit = QuantumCircuit(qr)
circuit.cx(qr[0], qr[1])
Expand Down

0 comments on commit ef58e5f

Please sign in to comment.