我正在使用 Qiskit 的draw('latex_source')
方法来获取我的电路的乳胶图。这个电路深度很大,因此很宽。我希望将其分成多行,就像使用fold
Qiskitmpl
或 ASCII 图纸中的参数一样。
是否有一种简单的方法可以自动将电路分成多个折叠?
编辑:示例:假设这是图:
\documentclass[border=5px]{standalone}
\usepackage[braket, qm]{qcircuit}
\usepackage{graphicx}
\begin{document}
\scalebox{1.0}{{$\mathrm{global\,phase:\,} \mathrm{\frac{\pi}{2}}$}
\Qcircuit @R=1em @C=0.75em { \\
\nghost{{q}_{0} : } & \lstick{\ket{0}} & \gate{\mathrm{H}} & \qw & \qw & \qw & \qw & \qw & \qw & \qw & \qw & \qw & \qw & \targ & \gate{\mathrm{R_Z}\,(\mathrm{-1.0})} & \targ & \qw \\
\nghost{{q}_{1} : } & \lstick{\ket{0}} & \gate{\mathrm{H}} & \ctrl{1} & \qw & \ctrl{1} & \gate{\mathrm{H}} & \gate{\mathrm{R_X}\,(\mathrm{\frac{\pi}{2}})} & \ctrl{1} & \qw & \ctrl{1} & \gate{\mathrm{R_Z}\,(\mathrm{\frac{\pi}{2}})} & \gate{\mathrm{R_Y}\,(\mathrm{-0.5})} & \qw & \qw & \qw& \qw \\
\nghost{{q}_{2} : } & \lstick{\ket{0}} & \gate{\mathrm{H}} & \targ & \gate{\mathrm{R_Z}\,(\mathrm{-1.0})} & \targ & \gate{\mathrm{H}} & \gate{\mathrm{R_X}\,(\mathrm{\frac{\pi}{2}})} & \targ & \gate{\mathrm{R_Z}\,(\mathrm{-1.0})} & \targ & \gate{\mathrm{R_X}\,(\mathrm{\frac{-\pi}{2}})} & \qw & \ctrl{-2} & \qw & \ctrl{-2} & \qw \\
\\ }}
\end{document}
这个数字对于单行来说太长了(这只是一个例子,实际数字是这个数字的 5 倍宽)。因此,我希望将其分成两行。
答案1
有趣的是,我正要问同样的问题时,却发现你一天前也问过这个问题。我最终的做法是使用以下 LayeredCircuit 类解决了 Qiskit 端的问题:
from qiskit import QuantumCircuit
from qiskit.converters import circuit_to_dag, dag_to_circuit
class LayeredCircuit:
"""Turn ciruit into list of circuits of depth 1"""
def __init__(self, circuits = []):
self._current_index = 0
self._layers = []
self.num_qubits = 0
arg_error = 'Argument must be one of QuantumCircuit, LayeredCircuit,
or list of QuantumCircuits of equal size.'
if isinstance(circuits, QuantumCircuit):
circuits = [circuits]
if isinstance(circuits, LayeredCircuit):
circuits = circuits._layers
if not isinstance(circuits, list):
raise TypeError(arg_error)
if circuits:
self.num_qubits = len(circuits[0].qubits)
for circuit in circuits:
if not isinstance(circuit, QuantumCircuit):
raise TypeError(arg_error)
if not len(circuit.qubits) == self.num_qubits:
raise TypeError(arg_error)
dag = circuit_to_dag(circuit)
for layer in dag.layers():
qc = dag_to_circuit(layer['graph'])
qc.global_phase = 0 # ignore all global phases
self._layers.append(qc)
def __iter__(self):
return self
def __next__(self):
if self._current_index < len(self.layers):
l = self._layers[self._current_index]
self._current_index += 1
return l
else:
raise StopIteration
def __getitem__(self, i):
if isinstance(i, slice):
return LayeredCircuit(self._layers[i])
elif isinstance(i, int):
return self._layers[i]
else:
raise TypeError('Invalid argument type.')
def __len__(self):
return len(self._layers)
def append(self, other):
"""Appends another LayeredCircuit"""
if not isinstance(other, LayeredCircuit):
other = LayeredCircuit(other)
for layer in other:
self._layers.append(layer)
def merge(self):
"""Returns the merged QuantumCircuit of all layers"""
qc = QuantumCircuit(self.num_qubits)
for layer in self._layers:
qc.compose(layer,range(self.num_qubits),inplace=True)
return qc
def draw(self, *args, **kwargs):
"""Draws the merged circuit, same syntax as QuantumCircuit.draw()"""
return self.merge().draw(*args, **kwargs)
def latex(self):
"""Returns LaTeX Qcircuit code"""
doc = self.draw('latex_source')
return '\Qcircuit' + doc.split('\Qcircuit')[1].split('}\n\end{document}')[0]
然后你可以打印电路的各个部分,例如
print(LayeredCircuit(qc)[0:5].latex())
为了我的目的,我将其与循环结合起来:
c = LayeredCircuit(qc)
l = len(c)
n = 17
for i in range(l//n+1):
print('&\\begin{array}{c}\\tiny')
print(c[i*n:min(l,(i+1)*n)].latex())
print('\\end{array}\\\\')
然后我将其复制粘贴到 LaTeX 的对齐环境中。