# How to implement controlled multiqubit gates in qiskit?

To implement a stabilizer code I need to measure stabilizer generators, as shown in Fig. 10.16 in Nielsen & Chuang. Is there a way for controlled multiqubit gates in qiskit?

## A general controlled unitary

Let $$CU$$ denote the 'controlled' version of the $$n$$-qubit unitary $$U$$:

$$$$CU = |0\rangle\langle0|\otimes I_{t} + |1\rangle\langle1|\otimes U_{t},$$$$

where the operation acts on a Hilbert space $$\mathcal{H}_{c}\otimes \mathcal{H}_{t}$$, with $$c$$ denoting the control qubit and $$t$$ denoting the target qubits (in your case, the data qubits). I have added a subscript $$t$$ in the equation as well to indicate this subsystem.

Normally, to implement $$CU$$ one needs to compile it to the gateset used by the platform on which it is implemented. Qiskit generally uses only two-qubit multi-qubit gates, so higher-dimensional gates need to be compiled. See for instance this previous question or the paper referred to in an answer there.

However, there is a shortcut for the unitary you describe: we can write $$U = U_{i}^{\otimes n}$$, where each $$U_{i}$$ is a single-qubit unitary (In your case, all $$U_{i}$$ are either $$X$$ or $$I$$); we can always write the unitary like this when concerning stabilizer codes.

Now we can rewrite $$CU$$ as: $$$$CU = \prod_{i \in n}|0\rangle\langle 0| \otimes I_{i} + |1\rangle\langle 1| \otimes U_{i}.$$$$

That is to say, we can replace the entire multi-qubit controlled unitary by the succession of controlled version of all individual $$U_{i}$$'s.

That means for you that you can apply a controlled $$X$$ (or $$I$$) operation to every different data qubit, from your ancilla. Of course the controlled $$I$$ operation need not be actually performed.

## Implementation on physical hardware

Note that this is easier said than done on an actual physical platform: you are then strongly limited by the connectivity between the various qubits on the chip. Steane's code has weight-four stabilizers, meaning that you need to connect one qubit (the ancilla) to 4 data qubits; moreover this needs to be done for multiple subsets of the data qubits. This is a very strong requirement and there are not many physical chips (if any) where you can actually perform this.

A planar implementation of the Steane code can be found in the picture in box 1 on page 3 of this paper; each of the $$3$$ faces is a stabilizer (e.g. an ancilla qubit), so the drawn vertices are in fact not actual connections between qubits.

## Sidenote on implementing stabilizer error correction on current-gen hardware

As a sidenote, also please realize that when performing physical implementation, you will not be able to implement error correction, as you won't have quick enough access to the measurement outcomes of the stabilizer-ancilla measurements which give you the error measurement. That is, the binary-controlled (i.e. controlled by a classical bit - the measurement outcome) used in the error correction process will probably not be possible.

For doing that in Qiskit, first create a multi qubit gate as a custom gate:

from qiskit import *
x_circuit = QuantumCircuit(3, name='Xs')
x_circuit.x(range(3))

xs_gate = x_circuit.to_gate()


Then create a controlled version of that custom gate:

cxs_gate = xs_gate.control()


Finally, use that controlled custom gate in a circuit:

circuit = QuantumCircuit(8)
circuit.append(cxs_gate, [0,2,6,4])
print(circuit)

q_0: ───■───
│
q_1: ───┼───
┌──┴──┐
q_2: ┤0    ├
│     │
q_3: ┤     ├
│     │
q_4: ┤2 Xs ├
│     │
q_5: ┤     ├
│     │
q_6: ┤1    ├
└─────┘
q_7: ───────


You can decompose one level to see how it works internally:

print(circuit.decompose())

q_0: ──■────■────■──
│    │    │
q_1: ──┼────┼────┼──
┌─┴─┐  │    │
q_2: ┤ X ├──┼────┼──
└───┘  │    │
q_3: ───────┼────┼──
│  ┌─┴─┐
q_4: ───────┼──┤ X ├
│  └───┘
q_5: ───────┼───────
┌─┴─┐
q_6: ─────┤ X ├─────
└───┘
q_7: ───────────────