示例#1
0
def cry(self, theta, q_control, q_target):
    """
    Apply Controlled-RY (cry) Gate.

    Args:
        self (QuantumCircuit): The circuit to apply the ch gate on.
        theta (float): The rotation angle.
        q_control ((QuantumRegister, int)): The control qubit.
        q_target ((QuantumRegister, int)): The target qubit.
    """

    if not is_qubit(q_control):
        raise AquaError('A qubit is expected for the control.')
    if not self.has_register(q_control[0]):
        raise AquaError('The control qubit is expected to be part of the circuit.')

    if not is_qubit(q_target):
        raise AquaError('A qubit is expected for the target.')
    if not self.has_register(q_target[0]):
        raise AquaError('The target qubit is expected to be part of the circuit.')

    if q_control == q_target:
        raise AquaError('The control and target need to be different qubits.')

    self.u3(theta / 2, 0, 0, q_target)
    self.cx(q_control, q_target)
    self.u3(-theta / 2, 0, 0, q_target)
    self.cx(q_control, q_target)
    return self
def ch(self, q_control, q_target):
    """
    Apply Controlled-Hadamard (ch) Gate.

    Note that this implementation of the ch uses a single cx gate,
    which is more efficient than what's currently provided in Terra.

    Args:
        self (QuantumCircuit): The circuit to apply the ch gate on.
        q_control ((QuantumRegister, int)): The control qubit.
        q_target ((QuantumRegister, int)): The target qubit.
    """
    if not is_qubit(q_control):
        raise AquaError('A qubit is expected for the control.')
    if not self.has_register(q_control[0]):
        raise AquaError(
            'The control qubit is expected to be part of the circuit.')

    if not is_qubit(q_target):
        raise AquaError('A qubit is expected for the target.')
    if not self.has_register(q_target[0]):
        raise AquaError(
            'The target qubit is expected to be part of the circuit.')

    if q_control == q_target:
        raise AquaError('The control and target need to be different qubits.')

    self.u3(-7 / 4 * pi, 0, 0, q_target)
    self.cx(q_control, q_target)
    self.u3(7 / 4 * pi, 0, 0, q_target)
    return self
示例#3
0
def rcccx(self, q_control_1, q_control_2, q_control_3, q_target):
    """
    Apply 3-Control Relative-Phase Toffoli gate from q_control_1, q_control_2, and q_control_3 to q_target.

    The implementation is based on https://arxiv.org/pdf/1508.03273.pdf Figure 4

    Args:
        self (QuantumCircuit): The QuantumCircuit object to apply the rcccx gate on.
        q_control_1 (tuple(QuantumRegister, int)): The 1st control qubit.
        q_control_2 (tuple(QuantumRegister, int)): The 2nd control qubit.
        q_control_3 (tuple(QuantumRegister, int)): The 3rd control qubit.
        q_target (tuple(QuantumRegister, int)): The target qubit.

    """
    if not is_qubit(q_control_1):
        raise AquaError('A qubit is expected for the first control.')
    if not self.has_register(q_control_1[0]):
        raise AquaError(
            'The first control qubit is expected to be part of the circuit.')

    if not is_qubit(q_control_2):
        raise AquaError('A qubit is expected for the second control.')
    if not self.has_register(q_control_2[0]):
        raise AquaError(
            'The second control qubit is expected to be part of the circuit.')

    if not is_qubit(q_target):
        raise AquaError('A qubit is expected for the target.')
    if not self.has_register(q_target[0]):
        raise AquaError(
            'The target qubit is expected to be part of the circuit.')

    self._check_dups([q_control_1, q_control_2, q_control_3, q_target])
    _apply_rcccx(self, q_control_1, q_control_2, q_control_3, q_target)
def mct(self, q_controls, q_target, q_ancilla, mode='basic'):
    """
    Apply Multiple-Control Toffoli operation
    Args:
        q_controls: The list of control qubits
        q_target: The target qubit
        q_ancilla: The list of ancillary qubits
        mode (string): The implementation mode to use
    """

    if len(q_controls) == 1:  # cx
        self.cx(q_controls[0], q_target)
    elif len(q_controls) == 2:  # ccx
        self.ccx(q_controls[0], q_controls[1], q_target)
    else:
        # check controls
        if isinstance(q_controls, QuantumRegister):
            control_qubits = [qb for qb in q_controls]
        elif isinstance(q_controls, list):
            control_qubits = q_controls
        else:
            raise AquaError(
                'MCT needs a list of qubits or a quantum register for controls.'
            )

        # check target
        if is_qubit(q_target):
            target_qubit = q_target
        else:
            raise AquaError('MCT needs a single qubit as target.')

        # check ancilla
        if q_ancilla is None:
            ancillary_qubits = []
        elif isinstance(q_ancilla, QuantumRegister):
            ancillary_qubits = [qb for qb in q_ancilla]
        elif isinstance(q_ancilla, list):
            ancillary_qubits = q_ancilla
        else:
            raise AquaError(
                'MCT needs None or a list of qubits or a quantum register for ancilla.'
            )

        all_qubits = control_qubits + [target_qubit] + ancillary_qubits

        self._check_qargs(all_qubits)
        self._check_dups(all_qubits)

        if mode == 'basic':
            _ccx_v_chain(self, control_qubits, target_qubit, ancillary_qubits)
        elif mode == 'advanced':
            _multicx(self, [*control_qubits, target_qubit],
                     ancillary_qubits[0] if ancillary_qubits else None)
        elif mode == 'noancilla':
            _multicx_noancilla(self, [*control_qubits, target_qubit])
        else:
            raise AquaError(
                'Unrecognized mode for building MCT circuit: {}.'.format(mode))
def mcry(self, theta, q_controls, q_target, q_ancillae):
    """
    Apply Multiple-Control RY (mcry) Gate.

    Args:
        self (QuantumCircuit): The circuit to apply the ch gate on.
        theta (float): The rotation angle.
        q_controls (QuantumRegister | (QuantumRegister, int)): The control qubits.
        q_target ((QuantumRegister, int)): The target qubit.
        q_ancillae (QuantumRegister | (QuantumRegister, int)): The ancillary qubits.
    """

    # check controls
    if isinstance(q_controls, QuantumRegister):
        control_qubits = [qb for qb in q_controls]
    elif isinstance(q_controls, list):
        control_qubits = q_controls
    else:
        raise AquaError(
            'The mcry gate needs a list of qubits or a quantum register for controls.'
        )

    # check target
    if is_qubit(q_target):
        target_qubit = q_target
    else:
        raise AquaError('The mcry gate needs a single qubit as target.')

    # check ancilla
    if q_ancillae is None:
        ancillary_qubits = []
    elif isinstance(q_ancillae, QuantumRegister):
        ancillary_qubits = [qb for qb in q_ancillae]
    elif isinstance(q_ancillae, list):
        ancillary_qubits = q_ancillae
    else:
        raise AquaError(
            'The mcry gate needs None or a list of qubits or a quantum register for ancilla.'
        )

    all_qubits = control_qubits + [target_qubit] + ancillary_qubits

    self._check_qargs(all_qubits)
    self._check_dups(all_qubits)

    self.u3(theta / 2, 0, 0, q_target)
    self.mct(q_controls, q_target, q_ancillae)
    self.u3(-theta / 2, 0, 0, q_target)
    self.mct(q_controls, q_target, q_ancillae)
    return self