Skip to content

Commit

Permalink
Merge pull request #115 from chensgit169/master
Browse files Browse the repository at this point in the history
fix: merge fixing of circuitPlot from stable/0.3
  • Loading branch information
beizhansl committed Nov 23, 2023
2 parents 4b7fa41 + 49ee886 commit 07ff991
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 12 deletions.
1 change: 0 additions & 1 deletion quafu/elements/element_gates/rotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ def matrix(self):

class RZGate(ParametricGate, SingleQubitGate):
name = "RZ"


def __init__(self, pos: int, paras: float = 0.):
ParametricGate.__init__(self, pos, paras=paras)
Expand Down
61 changes: 50 additions & 11 deletions quafu/visualisation/circuitPlot.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
from matplotlib.collections import PolyCollection, PatchCollection, LineCollection
from matplotlib.patches import Circle, Arc
from matplotlib.text import Text

from quafu.elements import Instruction, ControlledGate
from typing import Dict

from matplotlib.path import Path
from matplotlib.collections import PathCollection
# this line for developers only
# from quafu.circuits.quantum_circuit import QuantumCircuit

Expand All @@ -46,7 +48,7 @@
"""

su2_gate_names = ['x', 'y', 'z', 'id', 'w',
'h', 't', 'tdg', 's', 'sdg', 'sx', 'sy', 'sw',
'h', 't', 'tdg', 's', 'sdg', 'sx', 'sy', 'sw', 'sxdg', 'sydg', 'swdg',
'p',
'rx', 'ry', 'rz',
]
Expand Down Expand Up @@ -104,6 +106,7 @@ def __init__(self, qc):
self._swap_points = []
self._iswap_points = []
self._barrier_points = []
self._white_path_points = []

self._text_list = []

Expand Down Expand Up @@ -202,10 +205,14 @@ def _process_ins(self, ins: Instruction, append: bool = True):
self._proc_swap(depth, ins.pos, name == 'iswap')
elif name in r2_gate_names:
# TODO: combine into one box
self._proc_su2(name[-1], depth, ins.pos[0], paras)
self._proc_su2(name[-1], depth, ins.pos[1], paras)
self._ctrl_wire_points.append([[depth, ins.pos[0]], [depth, ins.pos[1]]])

self._proc_su2(name[:-1], depth, min(ins.pos), None)
self._proc_su2(name[:-1], depth, max(ins.pos), paras)
elif isinstance(ins, ControlledGate):
self._proc_ctrl(depth, ins)
elif name == 'delay':
self._delay(depth, ins.pos, ins.duration, ins.unit)
else:
raise NotImplementedError(f'Gate {name} is not supported yet.\n'
f'If this should occur, please report a bug.')
Expand All @@ -226,7 +233,7 @@ def _circuit_wires(self):
x1 = self.xs[-1] - 1
self._h_wire_points.append([[x0, y], [x1, y]])

def _inits_label(self, labels: dict = None):
def _inits_label(self, labels: Dict[int, str] = None):
""" qubit-labeling """
if labels is None:
labels = self.q_label
Expand All @@ -241,7 +248,7 @@ def _inits_label(self, labels: dict = None):
)
self._text_list.append(txt)

def _measured_label(self, labels: dict = None):
def _measured_label(self, labels: Dict[int, str] = None):
""" measured qubit-labeling """
if labels is None:
labels = self.c_label
Expand Down Expand Up @@ -336,9 +343,18 @@ def _measure_label(self, x, y):
#########################################################################
# region # # # # processing-functions: decompose ins into graphical elements # # #
def _proc_su2(self, id_name, depth, pos, paras):
if id_name in ['x', 'y', 'z', 'h', 'id', 's', 't', 'p', 'u']:
if id_name in ['x', 'y', 'z', 'h', 'id', 's', 't', 'p', 'w']:
fc = '#EE7057'
label = id_name.capitalize()
label = id_name.capitalize()[0]
elif id_name in ['sw', 'swdg', 'sx', 'sxdg', 'sy', 'sydg']:
fc = '#EE7057'
if id_name[-2:] == 'dg':
label = r'$\sqrt{%s}^\dagger$' % id_name[1]
else:
label = r'$\sqrt{%s}$' % id_name[1]
elif id_name in ['sdg', 'tdg']:
fc = '#EE7057'
label = id_name[0] + r'$^\dagger$'
elif id_name in ['rx', 'ry', 'rz']:
fc = '#6366F1'
label = id_name.upper()
Expand All @@ -348,7 +364,7 @@ def _proc_su2(self, id_name, depth, pos, paras):

if id_name in ['rx', 'ry', 'rz', 'p']:
# too long to display: r'$\theta=$' + f'{paras:.3f}' (TODO)
para_txt = f'({paras:.3f})'
para_txt = f'({paras:.3f})' if paras else None
else:
para_txt = None

Expand All @@ -358,6 +374,19 @@ def _proc_su2(self, id_name, depth, pos, paras):
self._para_label(x=x, y=y, para_txt=para_txt)
self._gate_bbox(x=x, y=y, fc=fc)

def _delay(self, depth, pos, paras, unit):
fc = BLUE

para_txt = '%d%s' % (paras, unit)

x = depth
y = self.used_qbit_y[pos]
xs = self._a * np.array([-1, 0, 1, -1, 0, 1, -1, 0]) / 4 + x
ys = self._a * np.array([1, 0, -1, -1, 0, 1, 1, 0]) / 3 + y
self._white_path_points.append(np.column_stack((xs, ys)))
self._para_label(x=x, y=y, para_txt=para_txt)
self._gate_bbox(x=x, y=y, fc=fc)

def _proc_ctrl(self, depth, ins: ControlledGate, ctrl_type: bool = True):
# control part
p0, p1 = np.max(ins.pos), np.min(ins.pos)
Expand All @@ -378,11 +407,11 @@ def _proc_ctrl(self, depth, ins: ControlledGate, ctrl_type: bool = True):
if tar_name == 'x':
self._not_points.append((depth, x))
else:
self._proc_su2(tar_name, depth, pos, None)
self._proc_su2(tar_name, depth, pos, ins.paras)
elif name == 'cswap':
self._swap_points += [[depth, self.used_qbit_y[p]] for p in ins.targs]
elif name == 'ccx':
self._not_points.append((depth, self.used_qbit_y[ins.targs]))
self._not_points.append((depth, self.used_qbit_y[ins.targs[0]]))
else:
from quafu.elements.element_gates import ControlledU
assert isinstance(ins, ControlledU), f'unknown gate: {name}, {ins.__class__.__name__}'
Expand Down Expand Up @@ -543,6 +572,14 @@ def _render_txt(self):
for txt in self._text_list:
plt.gca().add_artist(txt)

def _render_white_path(self):
path_collection = PathCollection([Path(points) for points in self._white_path_points],
facecolor='none',
edgecolor='white',
zorder=4,
linewidth=2)
plt.gca().add_collection(path_collection)

def _render_circuit(self):
self._render_h_wires()
self._render_ctrl_wires()
Expand All @@ -553,4 +590,6 @@ def _render_circuit(self):
self._render_measure()
self._render_barrier()
self._render_closed_patch()
self._render_white_path()
self._render_txt()

0 comments on commit 07ff991

Please sign in to comment.