...

/

The Oracle and Amplifier Functions

The Oracle and Amplifier Functions

Learn the concept of the oracle and amplifier functions.

The oracle‐function

Press + to interact
def oracle(passenger, group, q_p, q_r, draw=False):
# Create a sub-circuit
o_qc = QuantumCircuit(q_p, q_r)
# loop through all passengers
for pos in range(0, 2**QUBITS):
if pos >= len(group.index):
break
bpos = encode(pos)
# select the state representing the passenger
select_state(bpos, o_qc, q_p)
# apply the rules
apply_rules(passenger, group.iloc[[pos]], o_qc, q_p, q_r)
# un-select the state representing the passenger
select_state(bpos, o_qc, q_p)
if draw:
o_qc.barrier()
if draw:
return o_qc.draw()
else:
# We return the oracle as a gate
Oracle = 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 (232^3) 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

Press + to interact
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 XX ...