Quantum operator: operating and measuring qubits

The quantum operator is designed to represent a quantum circuits, or a group of quantum gates and measurements. Quantum operators can be also used to represent operation errors (using a serial of quantum gates) and the time delay during the measurements or operations.

Quantum operator has two modes: the synchronous and asynchronous mode. In synchronous model, it can not describe the time delay in operating qubits. While in asynchronous mode, quantum operators works as an independent entity. Quantum nodes uses events to control the operator and get the measuring results.

QuantumOperator has the following initiate parameters:

  • node, the quantum node that equips this operator

  • gate, it is a function to represent the quantum circuits. Its input is one or multiple qubits, and it returns a list of measurement results.

  • delay, the time delay of this operator. delay can be a float or a DelayModel.

  • name, the name of this operator

Here is an example of the quantum operator in synchronous mode:

def gate_z_and_measure(qubit: Qubit):
    # first perform Hadamard gate to the qubit, and then measure the qubit
    H(qubit=qubit)
    result = qubit.measure()
    return result


n1 = QNode("n1")
o1 = QuantumOperator(name="o1", node=n1, gate=gate_z_and_measure)

# add_operator can be used to equip the node with the operator
n1.add_operator(o1)

s = Simulator(0, 10, 1000)
n1.install(s)

qubit = Qubit()
ret = o1.operate(qubit)
assert(ret in [0, 1])

s.run()

Operators’ operate function can perform the circuits to the input qubits in synchronous mode.

Asynchronous mode

In the asynchronous mode, quantum nodes will use OperateRequestEvent to active the operator, and listen to the OperateResponseEvent to get the measure result. In detail, OperateRequestEvent.qubits is a list of the input qubits, and OperateResponseEvent.result delivers the measure result. Here is an example of the asynchronous mode. The time delay is set to 0.5s, and an application RecvOperateApp is installed on the node to listen to and handle the OperateResponseEvent.

class RecvOperateApp(Application):
    def __init__(self):
        super().__init__()
        self.add_handler(self.OperateResponseEventhandler, [OperateResponseEvent], [])

    def OperateResponseEventhandler(self, node, event: Event) -> Optional[bool]:
        result = event.result
        assert(self._simulator.tc.sec == 0.5)
        assert(result in [0, 1])

n1 = QNode("n1")
o1 = QuantumOperator(name="o1", node=n1, gate=gate_z_and_measure, delay=0.5)

n1.add_operator(o1)
a1 = RecvOperateApp()
n1.add_apps(a1)

s = Simulator(0, 10, 1000)
n1.install(s)

qubit = Qubit()
request = OperateRequestEvent(o1, qubits=[qubit], t=s.time(sec=0), by=n1)
s.add_event(request)

s.run()