如何将 QCircuit 图形拆分成多行

如何将 QCircuit 图形拆分成多行

我正在使用 Qiskit 的draw('latex_source')方法来获取我的电路的乳胶图。这个电路深度很大,因此很宽。我希望将其分成多行,就像使用foldQiskitmpl或 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 的对齐环境中。

相关内容