Exemplo n.º 1
0
def mcu3(self, theta, phi, lam, control_qubits, target_qubit):
    """
    Apply Multiple-Controlled U3 gate
    Args:
        theta: angle theta
        phi: angle phi
        lam: angle lambda
        control_qubits: The list of control qubits
        target_qubit: The target qubit
    """
    if isinstance(target_qubit, QuantumRegister) and len(target_qubit) == 1:
        target_qubit = target_qubit[0]
    temp = []

    self._check_qargs(control_qubits)
    temp += control_qubits

    self._check_qargs([target_qubit])
    temp.append(target_qubit)

    self._check_dups(temp)
    n_c = len(control_qubits)
    if n_c == 1:  # cu3
        apply_cu3(self, theta, phi, lam, control_qubits[0], target_qubit)
    else:
        _apply_mcu3(self, theta, phi, lam, control_qubits, target_qubit)
Exemplo n.º 2
0
def mcu3(self, theta, phi, lam, control_qubits, target_qubit):
    """
    Apply Multiple-Controlled U3 gate

    Args:
        self (QuantumCircuit): The QuantumCircuit object to apply the mcu3 gate on.
        theta (float): angle theta
        phi (float): angle phi
        lam (float): angle lambda
        control_qubits (list(tuple(QuantumRegister, int))): The list of control qubits
        target_qubit (tuple(QuantumRegister, int)): The target qubit
    """
    if isinstance(target_qubit, QuantumRegister) and len(target_qubit) == 1:
        target_qubit = target_qubit[0]
    temp = []

    self._check_qargs(control_qubits)
    temp += control_qubits

    self._check_qargs([target_qubit])
    temp.append(target_qubit)

    self._check_dups(temp)
    n_c = len(control_qubits)
    if n_c == 1:  # cu3
        apply_cu3(self, theta, phi, lam, control_qubits[0], target_qubit)
    else:
        _apply_mcu3(self, theta, phi, lam, control_qubits, target_qubit)
Exemplo n.º 3
0
def mcrx(self, theta, q_controls, q_target, use_basis_gates=False):
    """
    Apply Multiple-Controlled X rotation gate

    Args:
        self (QuantumCircuit): The QuantumCircuit object to apply the mcrx gate on.
        theta (float): angle theta
        q_controls (list[Qubit]): The list of control qubits
        q_target (Qubit): The target qubit
        use_basis_gates (bool): use basis gates
    Raises:
        AquaError: invalid input
    """

    # 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 mcrx gate needs a list of qubits or a quantum register for controls.'
        )

    # check target
    if isinstance(q_target, Qubit):
        target_qubit = q_target
    else:
        raise AquaError('The mcrx gate needs a single qubit as target.')

    all_qubits = control_qubits + [target_qubit]

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

    n_c = len(control_qubits)
    if n_c == 1:  # cu3
        apply_cu3(self,
                  theta,
                  -pi / 2,
                  pi / 2,
                  control_qubits[0],
                  target_qubit,
                  use_basis_gates=use_basis_gates)
    else:
        theta_step = theta * (1 / (2**(n_c - 1)))
        _apply_mcu3_graycode(self,
                             theta_step,
                             -pi / 2,
                             pi / 2,
                             control_qubits,
                             target_qubit,
                             use_basis_gates=use_basis_gates)
Exemplo n.º 4
0
def mcrz(self, lam, q_controls, q_target, use_basis_gates=False):
    """
    Apply Multiple-Controlled Z rotation gate

    Args:
        self (QuantumCircuit): The QuantumCircuit object to apply the mcrz gate on.
        phi (float): angle phi
        control_qubits (list of Qubit): The list of control qubits
        target_qubit (Qubit): The target qubit
    """

    # 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 mcrz gate needs a list of qubits or a quantum register for controls.'
        )

    # check target
    if isinstance(q_target, Qubit):
        target_qubit = q_target
    else:
        raise AquaError('The mcrz gate needs a single qubit as target.')

    all_qubits = control_qubits + [target_qubit]

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

    n_c = len(control_qubits)
    if n_c == 1:  # cu3
        apply_cu3(self,
                  0,
                  0,
                  lam,
                  control_qubits[0],
                  target_qubit,
                  use_basis_gates=use_basis_gates)
    else:
        lam_step = lam * (1 / (2**(n_c - 1)))
        _apply_mcu3_graycode(self,
                             0,
                             0,
                             lam_step,
                             control_qubits,
                             target_qubit,
                             use_basis_gates=use_basis_gates)
Exemplo n.º 5
0
def _apply_mcu3_graycode(circuit, theta, phi, lam, ctls, tgt, use_basis_gates):
    """Apply multi-controlled u3 gate from ctls to tgt using graycode
    pattern with single-step angles theta, phi, lam."""

    n = len(ctls)

    gray_code = list(GrayCode(n).generate_gray())
    last_pattern = None

    for pattern in gray_code:
        if '1' not in pattern:
            continue
        if last_pattern is None:
            last_pattern = pattern
        # find left most set bit
        lm_pos = list(pattern).index('1')

        # find changed bit
        comp = [i != j for i, j in zip(pattern, last_pattern)]
        if True in comp:
            pos = comp.index(True)
        else:
            pos = None
        if pos is not None:
            if pos != lm_pos:
                circuit.cx(ctls[pos], ctls[lm_pos])
            else:
                indices = [i for i, x in enumerate(pattern) if x == '1']
                for idx in indices[1:]:
                    circuit.cx(ctls[idx], ctls[lm_pos])
        # check parity and undo rotation
        if pattern.count('1') % 2 == 0:
            # inverse CU3: u3(theta, phi, lamb)^dagger = u3(-theta, -lam, -phi)
            apply_cu3(circuit,
                      -theta,
                      -lam,
                      -phi,
                      ctls[lm_pos],
                      tgt,
                      use_basis_gates=use_basis_gates)
        else:
            apply_cu3(circuit,
                      theta,
                      phi,
                      lam,
                      ctls[lm_pos],
                      tgt,
                      use_basis_gates=use_basis_gates)
        last_pattern = pattern
Exemplo n.º 6
0
def _apply_mcu3(circuit, theta, phi, lam, ctls, tgt):
    """Apply multi-controlled u3 gate from ctls to tgt with angles theta,
    phi, lam."""

    n = len(ctls)

    gray_code = list(GrayCode(n).generate_gray())
    last_pattern = None

    theta_angle = theta * (1 / (2**(n - 1)))
    phi_angle = phi * (1 / (2**(n - 1)))
    lam_angle = lam * (1 / (2**(n - 1)))

    for pattern in gray_code:
        if not '1' in pattern:
            continue
        if last_pattern is None:
            last_pattern = pattern
        #find left most set bit
        lm_pos = list(pattern).index('1')

        #find changed bit
        comp = [i != j for i, j in zip(pattern, last_pattern)]
        if True in comp:
            pos = comp.index(True)
        else:
            pos = None
        if pos is not None:
            if pos != lm_pos:
                circuit.cx(ctls[pos], ctls[lm_pos])
            else:
                indices = [i for i, x in enumerate(pattern) if x == '1']
                for idx in indices[1:]:
                    circuit.cx(ctls[idx], ctls[lm_pos])
        #check parity
        if pattern.count('1') % 2 == 0:
            #inverse
            apply_cu3(circuit, -theta_angle, phi_angle, lam_angle,
                      ctls[lm_pos], tgt)
        else:
            apply_cu3(circuit, theta_angle, phi_angle, lam_angle, ctls[lm_pos],
                      tgt)
        last_pattern = pattern
Exemplo n.º 7
0
def mcry(self,
         theta,
         q_controls,
         q_target,
         q_ancillae,
         mode='basic',
         use_basis_gates=False):
    """
    Apply Multiple-Controlled Y rotation gate

    Args:
        self (QuantumCircuit): The QuantumCircuit object to apply the mcry gate on.
        theta (float): angle theta
        q_controls (list[Qubit]): The list of control qubits
        q_target (Qubit): The target qubit
        q_ancillae (Union(QuantumRegister,tuple(QuantumRegister, int))):
                The list of ancillary qubits.
        mode (str): The implementation mode to use
        use_basis_gates (bool): use basis gates
    Raises:
        AquaError: invalid input
    """

    # 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 isinstance(q_target, Qubit):
        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)

    if mode == 'basic':
        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)
    elif mode == 'noancilla':
        n_c = len(control_qubits)
        if n_c == 1:  # cu3
            apply_cu3(self,
                      theta,
                      0,
                      0,
                      control_qubits[0],
                      target_qubit,
                      use_basis_gates=use_basis_gates)
        else:
            theta_step = theta * (1 / (2**(n_c - 1)))
            _apply_mcu3_graycode(self,
                                 theta_step,
                                 0,
                                 0,
                                 control_qubits,
                                 target_qubit,
                                 use_basis_gates=use_basis_gates)
    else:
        raise AquaError(
            'Unrecognized mode for building MCRY circuit: {}.'.format(mode))