The Oracle and Amplifier Functions
Learn the concept of the oracle and amplifier functions.
The oracle‐function
def oracle(passenger, group, q_p, q_r, draw=False):# Create a sub-circuito_qc = QuantumCircuit(q_p, q_r)# loop through all passengersfor pos in range(0, 2**QUBITS):if pos >= len(group.index):breakbpos = encode(pos)# select the state representing the passengerselect_state(bpos, o_qc, q_p)# apply the rulesapply_rules(passenger, group.iloc[[pos]], o_qc, q_p, q_r)# un-select the state representing the passengerselect_state(bpos, o_qc, q_p)if draw:o_qc.barrier()if draw:return o_qc.draw()else:# We return the oracle as a gateOracle = o_qc.to_gate()Oracle.name = "oracle"return Oracle
The oracle
function takes four mandatory parameters and one optional parameter. The passenger
denotes the passenger whose relative we search. The group
is the excerpt of the Pandas dataframe
with the potential candidates being the relative. q_p
is the QuantumRegister
representing the passengers. q_r
is the QuantumRegister
representing the rules. These are all mandatory parameters. Finally, the draw
is an optional boolean parameter.
We create a separate QuantumCircuit
in line 3 that includes the two registers we took as parameters in this function. The oracle loops through all possible states we can represent with the specified number of qubits in line 6. With QUBITS=3
, there are 2**3=8
() states. We stop once the position of the current state exceeds the number of passengers we consider in lines 7 and 8.
For each used state that represents a passenger, we calculate the binary position in line 10, select the state that represents this passenger in line 13, apply the rules that govern whether the passenger is the relative in line 16, and unselect the passenger again in line 19.
The result of the oracle
function depends on the draw
parameter. If it is True
, we call the circuit’s draw
function. If it is False
, we turn the whole oracle circuit into a custom quantum gate in line 28 and specify a custom name in line 29. Custom gates can’t include barriers. Therefore, we only structure the visual representation of the oracle subcircuit if we draw it in lines 21 and 22.
The apparent question is how to select a state and apply the rules. We postponed the respective implementation by calling functions. Let’s take a look.
The select_state
function
def select_state(bpos, qc, qubits):for i in range(0, QUBITS):if bpos[::-1][i] == "0":qc.x(qubits[i])
The select_state
function selects or unselects a state. It takes the binary position, the quantum circuit (qc
), and the qubits
representing the passengers as parameters. This function loops through all the qubits in line 2 that we use for representing a passenger. If the binary string has a 0
at the position the qubit represents, we apply the ...