跳转至

AmplitudeAmplification

QuICT.algorithm.quantum_algorithm.AmplitudeAmplification

AmplitudeAmplification(work_bits: int, targ_phase_flip: CompositeGate, work_state_prep: Optional[CompositeGate] = None, zero_phase_flip: Optional[CompositeGate] = None)

Quantum Amplitude Amplificaiton.

Qubit Arrangement: |work_bits> |ancilla>

References

[1]: Brassard, Gilles, Peter Hoyer, Michele Mosca, and Alain Tapp. “Quantum Amplitude Amplification and Estimation,” 305:53-74, 2002. https://doi.org/10.1090/conm/305/05215.

Parameters:

  • work_bits (int) –

    The number of qubits required for the quantum state, in which the amplitude is about to be amplified.

  • targ_phase_flip (CompositeGate) –

    The oracle for flipping targets phases: I - 2\sum_x{|x><x|}.

  • work_state_prep (CompositeGate | None, default: None ) –

    Optional initial state preparation gate. A default euqally superposition gate, \(H^{\otimes n}\), will be used if not provided.

  • zero_phase_flip (CompositeGate | None, default: None ) –

    Optional flip-around-zero-state gate: I - 2|0><0|. Will use a default method if not provided.

Source code in QuICT/algorithm/quantum_algorithm/amplitude_amplification/qaa.py
def __init__(
    self,
    work_bits: int,
    targ_phase_flip: CompositeGate,
    work_state_prep: Optional[CompositeGate] = None,
    zero_phase_flip: Optional[CompositeGate] = None
) -> None:
    r"""
    Args:
        work_bits (int): The number of qubits required for the quantum state, in which the amplitude is
            about to be amplified.
        targ_phase_flip (CompositeGate): The oracle for flipping targets phases: I - 2\sum_x{|x><x|}.
        work_state_prep (CompositeGate | None): Optional initial state preparation gate. A default euqally
            superposition gate, $H^{\otimes n}$, will be used if not provided.
        zero_phase_flip (CompositeGate | None): Optional flip-around-zero-state gate: I - 2|0><0|. Will use
            a default method if not provided.
    """
    if work_bits < 2:
        raise ValueError(f"work_bits can not be less than 2, but given {work_bits}.")

    self._work_bits = work_bits
    self._oracle = targ_phase_flip

    if work_state_prep is None:
        self._work_state_prep = self._default_state_prep(work_bits)
    else:
        self._work_state_prep = work_state_prep

    if zero_phase_flip is None:
        self._zero_phase_flip = self._default_phase_flip(work_bits)
    else:
        self._zero_phase_flip = zero_phase_flip

    # Allocate qubits
    reg_manager = QRegManager()
    num_ancilla = reg_manager.ancilla_num(
        [self._oracle, self._work_state_prep, self._zero_phase_flip]
    )
    self._work_reg = reg_manager.alloc(work_bits)
    self._ancilla_reg = reg_manager.alloc(num_ancilla)
    self._total_qubits = reg_manager.allocated

    # Get input composite gates' application indices
    gate_mapper = QubitAligner(self._work_reg, self._ancilla_reg)
    self._o_reg = gate_mapper.getMap(self._oracle)
    self._sp_reg = gate_mapper.getMap(self._work_state_prep)
    self._zFlip_reg = gate_mapper.getMap(self._zero_phase_flip)

circuit

circuit(iteration: int, include_phase: bool = False) -> Circuit

Construct the quantum amplitude amplification circuit Args: iteration (int): Number of times to apply the amplify operator Q in the circuit. include_phase (bool): When set to True, the circuit will include the global -1 phase in Q = -A * S_0 * A^(-1) * O.

Returns:

  • Circuit ( Circuit ) –

    the QAA circuit.

Source code in QuICT/algorithm/quantum_algorithm/amplitude_amplification/qaa.py
def circuit(
    self,
    iteration: int,
    include_phase: bool = False
) -> Circuit:
    """ Construct the quantum amplitude amplification circuit
    Args:
        iteration (int): Number of times to apply the amplify operator Q in the circuit.
        include_phase (bool): When set to `True`, the circuit will include the global -1 phase
            in Q = -A * S_0 * A^(-1) * O.

    Returns:
        Circuit: the QAA circuit.
    """
    qaa_circ = Circuit(self._total_qubits)

    self._work_state_prep | qaa_circ(self._sp_reg)

    Q_it = self._iteration_op(include_phase)
    for _ in range(iteration):
        Q_it | qaa_circ

    return qaa_circ

run

run(iteration: int, include_phase: bool = False, backend=StateVectorSimulator(), shots: int = 1) -> Dict[str, int]

Construct and run the quantum amplitude amplification circuit. Args: iteration (int): Number of times to apply the amplify operator Q in the circuit. include_phase (bool): When set to True, the circuit will include the global -1 phase in Q = -A * S_0 * A^(-1) * O. backend (Any): A device to run the qaa circuit. shots (int): Number of runs for the circuit.

Source code in QuICT/algorithm/quantum_algorithm/amplitude_amplification/qaa.py
def run(
    self,
    iteration: int,
    include_phase: bool = False,
    backend=StateVectorSimulator(),
    shots: int = 1
) -> Dict[str, int]:
    """ Construct and run the quantum amplitude amplification circuit.
    Args:
        iteration (int): Number of times to apply the amplify operator Q in the circuit.
        include_phase (bool): When set to `True`, the circuit will include the global -1 phase
            in Q = -A * S_0 * A^(-1) * O.
        backend (Any): A device to run the qaa circuit.
        shots (int): Number of runs for the circuit.
    """
    qaa_circ = self.circuit(iteration, include_phase)

    final_sv = backend.run(qaa_circ)
    final_density_diag = (final_sv * final_sv.conj()).real
    traced_diag = np.sum(
        final_density_diag.reshape(
            (1 << len(self._work_reg), 1 << len(self._ancilla_reg))
        ),
        axis=1
    )

    if backend.device == "GPU":
        traced_diag = traced_diag.get()

    sample_array = np.random.choice(a=len(traced_diag), p=traced_diag, size=shots)
    unique, counts = np.unique(sample_array, return_counts=True)

    measure_dict = {}
    for i in range(len(unique)):
        key_str = np.binary_repr(unique[i], width=len(self._work_reg))
        measure_dict[key_str] = counts[i]

    return measure_dict