First, create a custom gate. A possible way to do that is from a circuit:
from qiskit import QuantumCircuit
subcircuit = QuantumCircuit(3, name='myGate')
subcircuit.h(0)
subcircuit.h(1)
subcircuit.ccx(0,1,2)
my_gate = subcircuit.to_gate()
Then, create a controlled version of that gate. You need to specify how many controls you have. For example, 1:
controlled_my_gate = my_gate.control(1)
You can add this controlled custom gate to a circuit with append
:
circuit = QuantumCircuit(4)
circuit.append(controlled_my_gate, [0,1,2,3])
circuit.draw('text')
q_0: ─────■─────
┌────┴────┐
q_1: ┤0 ├
│ │
q_2: ┤1 myGate ├
│ │
q_3: ┤2 ├
└─────────┘
The method decompose
will tell you how this controlled gate is built:
circuit.decompose().draw('text', fold=-1)
q_0: ───────■───────────────■───────────────■──────────■───■──────────■───■─────────■───■────────■──────────■────■───■────────■──────────■───■──────────────■────────
┌──────┴───────┐ │ │ │ │ │ │ │ │ │ │ │ │P(π/4) │ │ │ │
q_1: ┤ U(π/2,0,π,0) ├───────┼───────────────┼──────────┼───┼──────────■───┼─────────┼───┼────────┼──────────■────■───■────────┼──────────■───┼──────────────┼────────
└──────────────┘┌──────┴───────┐ │ │ │ │ │ │ │P(π/4) │ │ ┌─┴─┐ │P(-π/4) ┌─┴─┐ │ │
q_2: ────────────────┤ U(π/2,0,π,0) ├───────┼──────────■───┼──────────┼───┼─────────■───■────────┼──────────┼──┤ X ├──────────■────────┤ X ├─┼──────────────┼────────
└──────────────┘┌──────┴───────┐┌─┴─┐ │P(-π/4) ┌─┴─┐ │P(π/4) ┌─┴─┐ │P(-π/4) ┌─┴─┐└───┘ └───┘ │P(π/4) ┌──────┴───────┐
q_3: ────────────────────────────────┤ U(π/2,0,π,0) ├┤ X ├─■────────┤ X ├─■───────┤ X ├──────────■────────┤ X ├──────────────────────────────■───────┤ U(π/2,0,π,0) ├
└──────────────┘└───┘ └───┘ └───┘ └───┘ └──────────────┘
I think it roughly follows the method in the attached paper.