def _build_internal_circuit(self) -> qiskit.QuantumCircuit: control_reg = create_register(self.num_control_qubits, name='control') state_reg = create_register(self._oracle.num_state_qubits, name='state') output_reg = self._oracle.get_register('output', []) ancilla_reg = create_ancillas_for(self._oracle, self._a_op, self._rs_op) circuit = create_circuit(control_reg, state_reg, output_reg, ancilla_reg, name=self.name) self._oracle(circuit, control=control_reg, state=state_reg, output=output_reg, ancilla=ancilla_reg) self._a_op.apply_inverse(circuit, state_reg, ancilla=ancilla_reg) self._rs_op(circuit, control=control_reg, state=state_reg, ancilla=ancilla_reg) self._a_op(circuit, state_reg, ancilla=ancilla_reg) return circuit
def _build_internal_circuit(self) -> qiskit.QuantumCircuit: state_reg = create_register(self._q_op.num_target_qubits, name='state') output_reg = create_register(self.num_output_qubits, name='output') ancilla_reg = create_register( max(self._a_op.num_ancillas, self._q_op.num_ancillas), name='ancilla', reg_type='ancilla' ) circuit = create_circuit(state_reg, output_reg, ancilla_reg, name=self.name) # reverse qubits output_reg = output_reg[::-1] # apply A operator self._a_op(circuit, state_reg, ancilla_reg) # apply Hadamard on output register circuit.h(output_reg) # apply controlled-Q operator for k, q in enumerate(output_reg): for _ in range(2**k): self._q_op(circuit, q, state_reg, ancilla_reg) # reverse qubits output_reg = output_reg[::-1] # apply inverse QFT qft(circuit, output_reg, do_swaps=False, inverse=True) return circuit
def _build_internal_circuit(self) -> qiskit.QuantumCircuit: control_reg = create_register(self.num_control_qubits, name='control') state_reg = create_register(self.num_state_qubits, name='state') circuit = create_circuit(control_reg, state_reg, name=self.name) ref_state = [1] * self.num_state_qubits target_states = self.target_states if self.reverse: target_states = [ state for state in get_basis_states(self.num_state_qubits, out_type='list') if state not in target_states ] for state in target_states: for bit, rbit, q in zip(state, ref_state, state_reg): if bool(bit) is not bool(rbit): circuit.x(q) circuit.mcp(self.phase, control_reg[:] + state_reg[:-1], state_reg[-1]) ref_state = state for bit, q in zip(ref_state, state_reg): if not bit: circuit.x(q) return circuit
def _build_internal_circuit(self) -> qiskit.QuantumCircuit: state_reg = create_register(self.oracle.get_register('state').size, name='state') output_reg = create_register(1, name='output') ancilla_reg = create_ancillas_for(self.state_loading_op, self.oracle) circuit = create_circuit(state_reg, ancilla_reg, name=self.name) self.state_loading_op(circuit, state=state_reg, ancilla=ancilla_reg) self.oracle(circuit, state=state_reg, output=output_reg, ancilla=ancilla_reg) return circuit
def _build_internal_circuit(self) -> qiskit.QuantumCircuit: state_reg = create_register(self._q_op.get_register('state').size, name='state') output_reg = create_register(1, name='output') ancilla_reg = create_ancillas_for(self._a_op, self._q_op, name='ancilla') circuit = create_circuit(state_reg, output_reg, ancilla_reg, name=self.name) # apply A operator self._a_op(circuit, state=state_reg, output=output_reg, ancilla=ancilla_reg) # apply Q operator for _ in range(self.num_q_applications): self._q_op(circuit, state=state_reg, output=output_reg, ancilla=ancilla_reg) return circuit
def _build_internal_circuit(self) -> qiskit.QuantumCircuit: state_reg = create_register(self.rs_op.get_register('state').size, name='state') output_reg = create_register(1, name='output') ancilla_reg = create_ancillas_for(self.a_op, self.rs_op) circuit = create_circuit(state_reg, output_reg, ancilla_reg, name=self.name) # Add pi phase to states with output qubit = |0> circuit.x(output_reg) circuit.p(np.pi, output_reg) circuit.x(output_reg) # A^dag self.a_op.apply_inverse(circuit) # Reflection on source state self.rs_op(circuit) # A self.a_op(circuit) return circuit
def to_phase_oracle(self, num_controls: int = 0) -> PhaseOracle: control_reg = create_register(num_controls, 'control') state_reg = create_register(self.num_state_qubits, 'state') output_reg = create_register(1, 'ancilla', reg_type='ancilla') circuit = create_circuit(control_reg, state_reg, output_reg, name='Controlled' + self.name) if num_controls > 0: circuit.mcx(control_reg, output_reg) else: circuit.x(output_reg) circuit.h(output_reg) circuit = self.apply(circuit, state_reg, output_reg) circuit.h(output_reg) if num_controls > 0: circuit.mcx(control_reg, output_reg) else: circuit.x(output_reg) ret = PhaseOracle(self.target_states, num_control_qubits=num_controls, reverse=self.reverse) ret._set_internal_circuit(circuit) return ret
def create_ancillas_for(*operators: QuantumOperator, name: typing.Optional[str] = 'ancilla'): num_ancillas = max(op.num_ancillas for op in operators) return create_register(num_ancillas, name=name, reg_type='ancilla')
def grover_circuit( target: typing.Union[typing.Sequence[BinarySequenceType], BinarySequenceType], source: BinarySequenceType = None, niter: typing.Union[int, None] = None, oracle_type: str = 'phase', measure: bool = True, ) -> qiskit.QuantumCircuit: assert len(target) > 0 # Input is a single target if not isinstance(target[0], typing.Sequence): target = [target] # number of qubits num_qubits = len(target[0]) # number of targets num_targets = len(target) # initial (source) state to start with if source is None: source = [0] * num_qubits # get optimal number of iterations if niter is None: niter = optimal_iterations(num_qubits, num_targets=num_targets) # quantum circuit qreg = qiskit.QuantumRegister(num_qubits, name='q') qc = qiskit.QuantumCircuit(qreg, name='grover') # initialize # construct source source_sv = state_to_sv(source) init_source_op = InitializeSourceOperator(state_vector=source_sv) init_source_op(qc, qreg) # construct equal superposition a_op = DiffusionOperator(num_qubits=num_qubits, source_state_vector=source_sv) a_op(qc, qreg) # Grover iterations rs_op = PhaseOracle(target_state=source) if oracle_type == 'phase': oracle = PhaseOracle(target_state=target) elif oracle_type == 'bool': oracle = BooleanOracle(target_state=target).to_phase_oracle() else: raise ValueError("Unknown oracle type %s", oracle_type) grover_op = GroverIterate(a_op=a_op, rs_op=rs_op, oracle=oracle) ancilla = create_register(grover_op.num_ancillas, name='ancilla') add_registers_to_circuit(qc, ancilla) for _ in range(niter): grover_op(qc, qreg, ancilla=ancilla) # measurement if measure: creg = qiskit.ClassicalRegister( grover_op.get_register('state').size, 'output') qc.add_register(creg) qc.measure(grover_op.get_register('state'), creg) return qc