예제 #1
0
    def _define(self):
        definition = []
        qr = QuantumRegister(self.num_qubits)
        oracle_qr = [qr[i] for i in self.oracle_qubits]

        # Prepare the auxiliary qubit into the Hadamard minus state.
        definition.append((HGate(), [qr[-1]], []))
        definition.append((ZGate(), [qr[-1]], []))

        # Add the boolean oracle whose behavior is
        # determined by the auxiliary qubit.
        definition.append((BooleanOracleGate(self.classical_boolean_oracle),
                           oracle_qr + [qr[-1]], []))

        # Add the inverse of the quantum algorithm.
        definition.append((self.quantum_algorithm.inverse(), qr[:-1], []))

        # Add the 'inversion around the mean' operator as a
        # special boolean oracle that behaves as a phase oracle
        # because of how was set the auxiliary qubit.
        definition.append(
            (BooleanOracleGate([1] + [0] * (2**(self.num_qubits - 1) - 1)),
             qr[:], []))

        # Add the quantum algorithm.
        definition.append((self.quantum_algorithm, qr[:-1], []))

        # Revert the auxiliary qubit to zero.
        definition.append((ZGate(), [qr[-1]], []))
        definition.append((HGate(), [qr[-1]], []))

        self.definition = definition
 def build_correction(self):
     # Build Correction Circuit
     circ = QuantumCircuit(self.code, self.syndrm)
     circ.append(XGate().control(4, ctrl_state='0010'),
                 [self.syndrm[i] for i in range(4)] + [self.code[0]])
     circ.append(YGate().control(4, ctrl_state='1110'),
                 [self.syndrm[i] for i in range(4)] + [self.code[0]])
     circ.append(ZGate().control(4, ctrl_state='1100'),
                 [self.syndrm[i] for i in range(4)] + [self.code[0]])
     circ.append(XGate().control(4, ctrl_state='0101'),
                 [self.syndrm[i] for i in range(4)] + [self.code[1]])
     circ.append(YGate().control(4, ctrl_state='1101'),
                 [self.syndrm[i] for i in range(4)] + [self.code[1]])
     circ.append(ZGate().control(4, ctrl_state='1000'),
                 [self.syndrm[i] for i in range(4)] + [self.code[1]])
     circ.append(XGate().control(4, ctrl_state='1010'),
                 [self.syndrm[i] for i in range(4)] + [self.code[2]])
     circ.append(YGate().control(4, ctrl_state='1011'),
                 [self.syndrm[i] for i in range(4)] + [self.code[2]])
     circ.append(ZGate().control(4, ctrl_state='0001'),
                 [self.syndrm[i] for i in range(4)] + [self.code[2]])
     circ.append(XGate().control(4, ctrl_state='0100'),
                 [self.syndrm[i] for i in range(4)] + [self.code[3]])
     circ.append(YGate().control(4, ctrl_state='0111'),
                 [self.syndrm[i] for i in range(4)] + [self.code[3]])
     circ.append(ZGate().control(4, ctrl_state='0011'),
                 [self.syndrm[i] for i in range(4)] + [self.code[3]])
     circ.append(XGate().control(4, ctrl_state='1001'),
                 [self.syndrm[i] for i in range(4)] + [self.code[4]])
     circ.append(YGate().control(4, ctrl_state='1111'),
                 [self.syndrm[i] for i in range(4)] + [self.code[4]])
     circ.append(ZGate().control(4, ctrl_state='0110'),
                 [self.syndrm[i] for i in range(4)] + [self.code[4]])
     return circ
예제 #3
0
    def to_instruction(self):
        """Convert to Pauli circuit instruction."""
        from math import pi

        pauli, phase = self._to_label(self.z,
                                      self.x,
                                      self._phase[0],
                                      full_group=False,
                                      return_phase=True)
        if len(pauli) == 1:
            gate = {
                "I": IGate(),
                "X": XGate(),
                "Y": YGate(),
                "Z": ZGate()
            }[pauli]
        else:
            gate = PauliGate(pauli)
        if not phase:
            return gate
        # Add global phase
        circuit = QuantumCircuit(self.num_qubits, name=str(self))
        circuit.global_phase = -phase * pi / 2
        circuit.append(gate, range(self.num_qubits))
        return circuit.to_instruction()
예제 #4
0
 def setUp(self):
     super().setUp()
     self.ops = {
         'X': XGate(),
         'Y': YGate(),
         'Z': ZGate(),
         'H': HGate(),
         'S': SGate()
     }
예제 #5
0
    def from_label(cls, label):
        """Return a tensor product of single-qubit operators.

        Args:
            label (string): single-qubit operator string.

        Returns:
            Operator: The N-qubit operator.

        Raises:
            QiskitError: if the label contains invalid characters, or the
                         length of the label is larger than an explicitly
                         specified num_qubits.

        Additional Information:
            The labels correspond to the single-qubit matrices:
            'I': [[1, 0], [0, 1]]
            'X': [[0, 1], [1, 0]]
            'Y': [[0, -1j], [1j, 0]]
            'Z': [[1, 0], [0, -1]]
            'H': [[1, 1], [1, -1]] / sqrt(2)
            'S': [[1, 0], [0 , 1j]]
            'T': [[1, 0], [0, (1+1j) / sqrt(2)]]
            '0': [[1, 0], [0, 0]]
            '1': [[0, 0], [0, 1]]
            '+': [[0.5, 0.5], [0.5 , 0.5]]
            '-': [[0.5, -0.5], [-0.5 , 0.5]]
            'r': [[0.5, -0.5j], [0.5j , 0.5]]
            'l': [[0.5, 0.5j], [-0.5j , 0.5]]
        """
        # Check label is valid
        label_mats = {
            'I': IGate().to_matrix(),
            'X': XGate().to_matrix(),
            'Y': YGate().to_matrix(),
            'Z': ZGate().to_matrix(),
            'H': HGate().to_matrix(),
            'S': SGate().to_matrix(),
            'T': TGate().to_matrix(),
            '0': np.array([[1, 0], [0, 0]], dtype=complex),
            '1': np.array([[0, 0], [0, 1]], dtype=complex),
            '+': np.array([[0.5, 0.5], [0.5, 0.5]], dtype=complex),
            '-': np.array([[0.5, -0.5], [-0.5, 0.5]], dtype=complex),
            'r': np.array([[0.5, -0.5j], [0.5j, 0.5]], dtype=complex),
            'l': np.array([[0.5, 0.5j], [-0.5j, 0.5]], dtype=complex),
        }
        if re.match(r'^[IXYZHST01rl\-+]+$', label) is None:
            raise QiskitError('Label contains invalid characters.')
        # Initialize an identity matrix and apply each gate
        num_qubits = len(label)
        op = Operator(np.eye(2 ** num_qubits, dtype=complex))
        for qubit, char in enumerate(reversed(label)):
            if char != 'I':
                op = op.compose(label_mats[char], qargs=[qubit])
        return op
예제 #6
0
    def from_label(label):
        """Return a tensor product of single-qubit Clifford gates.

        Args:
            label (string): single-qubit operator string.

        Returns:
            Clifford: The N-qubit Clifford operator.

        Raises:
            QiskitError: if the label contains invalid characters.

        Additional Information:
            The labels correspond to the single-qubit Cliffords are

            * - Label
              - Stabilizer
              - Destabilizer
            * - ``"I"``
              - +Z
              - +X
            * - ``"X"``
              - -Z
              - +X
            * - ``"Y"``
              - -Z
              - -X
            * - ``"Z"``
              - +Z
              - -X
            * - ``"H"``
              - +X
              - +Z
            * - ``"S"``
              - +Z
              - +Y
        """
        # Check label is valid
        label_gates = {
            'I': IGate(),
            'X': XGate(),
            'Y': YGate(),
            'Z': ZGate(),
            'H': HGate(),
            'S': SGate()
        }
        if re.match(r'^[IXYZHS\-+]+$', label) is None:
            raise QiskitError('Label contains invalid characters.')
        # Initialize an identity matrix and apply each gate
        num_qubits = len(label)
        op = Clifford(np.eye(2 * num_qubits, dtype=np.bool))
        for qubit, char in enumerate(reversed(label)):
            _append_circuit(op, label_gates[char], qargs=[qubit])
        return op
예제 #7
0
 def to_instruction(self):
     """Convert to Pauli circuit instruction."""
     from qiskit.circuit import QuantumCircuit, QuantumRegister
     from qiskit.circuit.library.standard_gates import IGate, XGate, YGate, ZGate
     gates = {'I': IGate(), 'X': XGate(), 'Y': YGate(), 'Z': ZGate()}
     label = self.to_label()
     num_qubits = self.num_qubits
     qreg = QuantumRegister(num_qubits)
     circuit = QuantumCircuit(qreg, name='Pauli:{}'.format(label))
     for i, pauli in enumerate(reversed(label)):
         circuit.append(gates[pauli], [qreg[i]])
     return circuit.to_instruction()
예제 #8
0
    def test_pauli_error_1q_gate_from_string(self):
        """Test single-qubit pauli error as gate qobj from string label"""
        paulis = ['I', 'X', 'Y', 'Z']
        probs = [0.4, 0.3, 0.2, 0.1]
        actual = pauli_error(zip(paulis, probs))

        expected = QuantumError([(IGate(), 0.4), (XGate(), 0.3), (YGate(), 0.2), (ZGate(), 0.1)])
        for i in range(actual.size):
            circ, prob = actual.error_term(i)
            expected_circ, expected_prob = expected.error_term(i)
            self.assertEqual(circ, expected_circ, msg=f"Incorrect {i}-th circuit")
            self.assertAlmostEqual(prob, expected_prob, msg=f"Incorrect {i}-th probability")
예제 #9
0
    def test_depolarizing_error_1q_gate(self):
        """Test 1-qubit depolarizing error as gate qobj"""
        p_depol = 0.3
        actual = depolarizing_error(p_depol, 1)

        expected = QuantumError([
            (IGate(), 1 - p_depol*3/4),
            (XGate(), p_depol/4),
            (YGate(), p_depol/4),
            (ZGate(), p_depol/4)
        ])
        for i in range(actual.size):
            circ, prob = actual.error_term(i)
            expected_circ, expected_prob = expected.error_term(i)
            self.assertEqual(circ, expected_circ, msg=f"Incorrect {i}-th circuit")
            self.assertAlmostEqual(prob, expected_prob, msg=f"Incorrect {i}-th probability")
예제 #10
0
    def test_thermal_relaxation_error_gate(self):
        """Test qobj instructions return for t2 < t1"""
        t1, t2, time, p1 = (2, 1, 1, 0.3)
        actual = thermal_relaxation_error(t1, t2, time, p1)

        p_z = 0.5 * np.exp(-1 / t1) * (1 - np.exp(-(1 / t2 - 1 / t1) * time))
        p_reset0 = (1 - p1) * (1 - np.exp(-1 / t1))
        p_reset1 = p1 * (1 - np.exp(-1 / t1))
        expected = QuantumError([
            (IGate(), 1 - p_z - p_reset0 - p_reset1),
            (ZGate(), p_z),
            (Reset(), p_reset0),
            ([(Reset(), [0]), (XGate(), [0])], p_reset1),
        ])
        for i in range(actual.size):
            circ, prob = actual.error_term(i)
            expected_circ, expected_prob = expected.error_term(i)
            self.assertEqual(circ, expected_circ, msg=f"Incorrect {i}-th circuit")
            self.assertAlmostEqual(prob, expected_prob, msg=f"Incorrect {i}-th probability")
예제 #11
0
파일: lab3.py 프로젝트: vdcn1/comp-quantica
def oraculo_trivial(n, k):
    qc = qiskit.QuantumCircuit(n)
    list_qu = list(range(n))
    bin_k = ('{0:0' + str(n) + 'b}').format(k)
    print(bin_k)

    bin_k = bin_k[::-1]

    for qu in range(n):
        qc.h(qu)

    qc.append(ZGate("zgate").control(num_ctrl_qubits=n - 1), list_qu)

    for i in range(n):
        if bin_k[i] == '0':
            qc.x(i)

    backend = qiskit.Aer.get_backend('statevector_simulator')
    job = qiskit.execute(qc, backend)
    result = job.result()
    print('Estado gerado pelo circuito: ', result.get_statevector())

    print(qc.draw())
    return qc
예제 #12
0
        The ``string`` supports only 1- or 2-qubit errors and
        its possible values are ``'pauli'``, ``'reset'``, ``'clifford'``.
        The ``'clifford'`` does not support 2-qubit errors.
    """
    def approximate(noise):
        return approximate_quantum_error(noise,
                                         operator_string=operator_string,
                                         operator_dict=operator_dict,
                                         operator_list=operator_list)

    return transform_noise_model(model, approximate)


# pauli operators
_PAULIS_Q0 = [[(IGate(), [0])], [(XGate(), [0])], [(YGate(), [0])],
              [(ZGate(), [0])]]
_PAULIS_Q1 = [[(IGate(), [1])], [(XGate(), [1])], [(YGate(), [1])],
              [(ZGate(), [1])]]
_PAULIS_Q0Q1 = [op_q0 + op_q1 for op_q0 in _PAULIS_Q0 for op_q1 in _PAULIS_Q1]
# reset operators
_RESET_Q0_TO_0 = [(Reset(), [0])]
_RESET_Q0_TO_1 = [(Reset(), [0]), (XGate(), [0])]
_RESET_Q0 = [[(IGate(), [0])], _RESET_Q0_TO_0, _RESET_Q0_TO_1]
_RESET_Q1_TO_0 = [(Reset(), [1])]
_RESET_Q1_TO_1 = [(Reset(), [1]), (XGate(), [1])]
_RESET_Q1 = [[(IGate(), [1])], _RESET_Q1_TO_0, _RESET_Q1_TO_1]
_RESET_Q0Q1 = [op_q0 + op_q1 for op_q0 in _RESET_Q0 for op_q1 in _RESET_Q1]
# preset operator table
_PRESET_OPERATOR_TABLE = {
    "pauli": {
        1: _PAULIS_Q0[1:],
예제 #13
0
    def _gate_gradient_dict(
            gate: Gate) -> List[Tuple[List[complex], List[Instruction]]]:
        r"""Given a parameterized gate U(theta) with derivative
        dU(theta)/dtheta = sum_ia_iU(theta)V_i.
        This function returns a:=[a_0, ...] and V=[V_0, ...]
        Suppose U takes multiple parameters, i.e., U(theta^0, ... theta^k).
        The returned coefficients and gates are ordered accordingly.
        Only parameterized Qiskit gates are supported.

        Args:
            gate: The gate for which the derivative is being computed.

           Returns:
                The coefficients and the gates used for the metric computation for each parameter of
                the respective gates.
                [([a^0], [V^0]) ..., ([a^k], [V^k])]


        Raises:
            AquaError: If the input gate is controlled by another state but '|1>^{\otimes k}'
            TypeError: If the input gate is not a supported parametrized gate.
        """

        # pylint: disable=too-many-return-statements
        if isinstance(gate, PhaseGate):
            # theta
            return [([0.5j, -0.5j], [IGate(), CZGate()])]
        if isinstance(gate, UGate):
            # theta, lambda, phi
            return [([-0.5j], [CZGate()]), ([-0.5j], [CZGate()]),
                    ([-0.5j], [CZGate()])]
        if isinstance(gate, RXGate):
            # theta
            return [([-0.5j], [CXGate()])]
        if isinstance(gate, RYGate):
            # theta
            return [([-0.5j], [CYGate()])]
        if isinstance(gate, RZGate):
            # theta
            return [([-0.5j], [CZGate()])]
        if isinstance(gate, RXXGate):
            # theta
            cxx_circ = QuantumCircuit(3)
            cxx_circ.cx(0, 1)
            cxx_circ.cx(0, 2)
            cxx = cxx_circ.to_instruction()
            return [([-0.5j], [cxx])]
        if isinstance(gate, RYYGate):
            # theta
            cyy_circ = QuantumCircuit(3)
            cyy_circ.cy(0, 1)
            cyy_circ.cy(0, 2)
            cyy = cyy_circ.to_instruction()
            return [([-0.5j], [cyy])]
        if isinstance(gate, RZZGate):
            # theta
            czz_circ = QuantumCircuit(3)
            czz_circ.cz(0, 1)
            czz_circ.cz(0, 2)
            czz = czz_circ.to_instruction()
            return [([-0.5j], [czz])]
        if isinstance(gate, RZXGate):
            # theta
            czx_circ = QuantumCircuit(3)
            czx_circ.cx(0, 2)
            czx_circ.cz(0, 1)
            czx = czx_circ.to_instruction()
            return [([-0.5j], [czx])]
        if isinstance(gate, ControlledGate):
            # TODO support arbitrary control states
            if gate.ctrl_state != 2**gate.num_ctrl_qubits - 1:
                raise AquaError(
                    'Function only support controlled gates with control state `1` on all control '
                    'qubits.')

            base_coeffs_gates = LinComb._gate_gradient_dict(gate.base_gate)
            coeffs_gates = []
            # The projectors needed for the gradient of a controlled gate are integrated by a sum
            # of gates.
            # The following line generates the decomposition gates.

            proj_gates_controlled = [[
                (-1)**p.count(ZGate()), p
            ] for p in product([IGate(), ZGate()], repeat=gate.num_ctrl_qubits)
                                     ]
            for base_coeffs, base_gates in base_coeffs_gates:  # loop over parameters
                coeffs = []
                gates = []
                for phase, proj_gates in proj_gates_controlled:
                    coeffs.extend([
                        phase * c / (2**gate.num_ctrl_qubits)
                        for c in base_coeffs
                    ])
                    for base_gate in base_gates:
                        controlled_circ = QuantumCircuit(gate.num_ctrl_qubits +
                                                         gate.num_qubits)
                        for i, proj_gate in enumerate(proj_gates):
                            if isinstance(proj_gate, ZGate):
                                controlled_circ.cz(0, i + 1)
                        if not isinstance(base_gate, IGate):
                            controlled_circ.append(base_gate, [
                                0,
                                range(gate.num_ctrl_qubits + 1,
                                      gate.num_ctrl_qubits + gate.num_qubits)
                            ])
                        gates.append(controlled_circ.to_instruction())
                c_g = (coeffs, gates)
                coeffs_gates.append(c_g)
            return coeffs_gates

        raise TypeError('Unrecognized parametrized gate, {}'.format(gate))
예제 #14
0
def thermal_relaxation_error(t1, t2, time, excited_state_population=0):
    r"""
    Return a single-qubit thermal relaxation quantum error channel.

    Args:
        t1 (double): the :math:`T_1` relaxation time constant.
        t2 (double): the :math:`T_2` relaxation time constant.
        time (double): the gate time for relaxation error.
        excited_state_population (double): the population of :math:`|1\rangle`
                                           state at equilibrium (default: 0).

    Returns:
        QuantumError: a quantum error object for a noise model.

    Raises:
        NoiseError: If noise parameters are invalid.

    Additional information:
        * For parameters to be valid :math:`T_1` and :math:`T_2` must
          satisfy :math:`T_2 \le 2 T_1`.

        * If :math:`T_2 \le T_1` the error can be expressed as a mixed
          reset and unitary error channel.

        * If :math:`T_1 < T_2 \le 2 T_1` the error must be expressed as a
          general non-unitary Kraus error channel.
    """
    if excited_state_population < 0:
        raise NoiseError("Invalid excited state population "
                         "({} < 0).".format(excited_state_population))
    if excited_state_population > 1:
        raise NoiseError("Invalid excited state population "
                         "({} > 1).".format(excited_state_population))
    if time < 0:
        raise NoiseError("Invalid gate_time ({} < 0)".format(time))
    if t1 <= 0:
        raise NoiseError("Invalid T_1 relaxation time parameter: T_1 <= 0.")
    if t2 <= 0:
        raise NoiseError("Invalid T_2 relaxation time parameter: T_2 <= 0.")
    if t2 - 2 * t1 > 0:
        raise NoiseError(
            "Invalid T_2 relaxation time parameter: T_2 greater than 2 * T_1.")

    # T1 relaxation rate
    if t1 == np.inf:
        rate1 = 0
        p_reset = 0
    else:
        rate1 = 1 / t1
        p_reset = 1 - np.exp(-time * rate1)
    # T2 dephasing rate
    if t2 == np.inf:
        rate2 = 0
        exp_t2 = 1
    else:
        rate2 = 1 / t2
        exp_t2 = np.exp(-time * rate2)
    # Qubit state equilibrium probabilities
    p0 = 1 - excited_state_population
    p1 = excited_state_population

    if t2 > t1:
        # If T_2 > T_1 we must express this as a Kraus channel
        # We start with the Choi-matrix representation:
        chan = Choi(
            np.array([[1 - p1 * p_reset, 0, 0, exp_t2],
                      [0, p1 * p_reset, 0, 0], [0, 0, p0 * p_reset, 0],
                      [exp_t2, 0, 0, 1 - p0 * p_reset]]))
        return QuantumError(Kraus(chan))
    else:
        # If T_2 < T_1 we can express this channel as a probabilistic
        # mixture of reset operations and unitary errors:
        circuits = [[(IGate(), [0])], [(ZGate(), [0])], [(Reset(), [0])],
                    [(Reset(), [0]), (XGate(), [0])]]
        # Probability
        p_reset0 = p_reset * p0
        p_reset1 = p_reset * p1
        p_z = (1 - p_reset) * (1 - np.exp(-time * (rate2 - rate1))) / 2
        p_identity = 1 - p_z - p_reset0 - p_reset1
        probabilities = [p_identity, p_z, p_reset0, p_reset1]
        return QuantumError(zip(circuits, probabilities))
예제 #15
0
    def _gradient_states(
        self,
        state_op: StateFn,
        meas_op: Optional[OperatorBase] = None,
        target_params: Optional[Union[ParameterExpression, ParameterVector,
                                      List[ParameterExpression]]] = None
    ) -> ListOp:
        """Generate the gradient states.

        Args:
            state_op: The operator representing the quantum state for which we compute the gradient.
            meas_op: The operator representing the observable for which we compute the gradient.
            target_params: The parameters we are taking the gradient wrt: ω

        Returns:
            ListOp of StateFns as quantum circuits which are the states w.r.t. which we compute the
            gradient. If a parameter appears multiple times, one circuit is created per
            parameterized gates to compute the product rule.

        Raises:
            AquaError: If one of the circuits could not be constructed.
            TypeError: If the operators is of unsupported type.
        """
        state_qc = deepcopy(state_op.primitive)

        # Define the working qubit to realize the linear combination of unitaries
        qr_work = QuantumRegister(1, 'work_qubit_lin_comb_grad')
        work_q = qr_work[0]

        if not isinstance(target_params, (list, np.ndarray)):
            target_params = [target_params]

        if len(target_params) > 1:
            states = None

        additional_qubits: Tuple[List[Qubit], List[Qubit]] = ([work_q], [])

        for param in target_params:
            if param not in state_qc._parameter_table.get_keys():
                op = ~Zero @ One
            else:
                param_gates = state_qc._parameter_table[param]
                for m, param_occurence in enumerate(param_gates):
                    coeffs, gates = self._gate_gradient_dict(
                        param_occurence[0])[param_occurence[1]]

                    # construct the states
                    for k, gate_to_insert in enumerate(gates):
                        grad_state = QuantumCircuit(*state_qc.qregs, qr_work)
                        grad_state.compose(state_qc, inplace=True)

                        # apply Hadamard on work_q
                        self.insert_gate(grad_state,
                                         param_occurence[0],
                                         HGate(),
                                         qubits=[work_q])

                        # Fix work_q phase
                        coeff_i = coeffs[k]
                        sign = np.sign(coeff_i)
                        is_complex = np.iscomplex(coeff_i)
                        if sign == -1:
                            if is_complex:
                                self.insert_gate(grad_state,
                                                 param_occurence[0],
                                                 SdgGate(),
                                                 qubits=[work_q])
                            else:
                                self.insert_gate(grad_state,
                                                 param_occurence[0],
                                                 ZGate(),
                                                 qubits=[work_q])
                        else:
                            if is_complex:
                                self.insert_gate(grad_state,
                                                 param_occurence[0],
                                                 SGate(),
                                                 qubits=[work_q])

                        # Insert controlled, intercepting gate - controlled by |0>
                        if isinstance(param_occurence[0], UGate):
                            if param_occurence[1] == 0:
                                self.insert_gate(
                                    grad_state, param_occurence[0],
                                    RZGate(param_occurence[0].params[2]))
                                self.insert_gate(grad_state,
                                                 param_occurence[0],
                                                 RXGate(np.pi / 2))
                                self.insert_gate(
                                    grad_state,
                                    param_occurence[0],
                                    gate_to_insert,
                                    additional_qubits=additional_qubits)
                                self.insert_gate(grad_state,
                                                 param_occurence[0],
                                                 RXGate(-np.pi / 2))
                                self.insert_gate(
                                    grad_state, param_occurence[0],
                                    RZGate(-param_occurence[0].params[2]))

                            elif param_occurence[1] == 1:
                                self.insert_gate(
                                    grad_state,
                                    param_occurence[0],
                                    gate_to_insert,
                                    after=True,
                                    additional_qubits=additional_qubits)
                            else:
                                self.insert_gate(
                                    grad_state,
                                    param_occurence[0],
                                    gate_to_insert,
                                    additional_qubits=additional_qubits)
                        else:
                            self.insert_gate(
                                grad_state,
                                param_occurence[0],
                                gate_to_insert,
                                additional_qubits=additional_qubits)
                        grad_state.h(work_q)

                        state = np.sqrt(
                            np.abs(coeff_i)) * state_op.coeff * CircuitStateFn(
                                grad_state)
                        # Chain Rule parameter expressions
                        gate_param = param_occurence[0].params[
                            param_occurence[1]]
                        if meas_op:
                            if gate_param == param:
                                state = meas_op @ state
                            else:
                                if isinstance(gate_param, ParameterExpression):
                                    expr_grad = DerivativeBase.parameter_expression_grad(
                                        gate_param, param)
                                    state = (expr_grad * meas_op) @ state
                                else:
                                    state = ~Zero @ One
                        else:
                            if gate_param == param:
                                state = ListOp([state],
                                               combo_fn=partial(
                                                   self._grad_combo_fn,
                                                   state_op=state_op))
                            else:
                                if isinstance(gate_param, ParameterExpression):
                                    expr_grad = DerivativeBase.parameter_expression_grad(
                                        gate_param, param)
                                    state = expr_grad * ListOp(
                                        [state],
                                        combo_fn=partial(self._grad_combo_fn,
                                                         state_op=state_op))
                                else:
                                    state = ~Zero @ One

                        if m == 0 and k == 0:
                            op = state
                        else:
                            # Product Rule
                            op += state
                if len(target_params) > 1:
                    if not states:
                        states = [op]
                    else:
                        states += [op]
                else:
                    return op
        if len(target_params) > 1:
            return ListOp(states)
        else:
            return op
예제 #16
0
    def _hessian_states(
        self,
        state_op: StateFn,
        meas_op: Optional[OperatorBase] = None,
        target_params: Optional[Union[Tuple[ParameterExpression,
                                            ParameterExpression],
                                      List[Tuple[ParameterExpression,
                                                 ParameterExpression]]]] = None
    ) -> OperatorBase:
        """Generate the operator states whose evaluation returns the Hessian (items).

        Args:
            state_op: The operator representing the quantum state for which we compute the Hessian.
            meas_op: The operator representing the observable for which we compute the gradient.
            target_params: The parameters we are computing the Hessian wrt: ω

        Returns:
            Operators which give the Hessian. If a parameter appears multiple times, one circuit is
            created per parameterized gates to compute the product rule.

        Raises:
            AquaError: If one of the circuits could not be constructed.
            TypeError: If ``operator`` is of unsupported type.
        """
        state_qc = deepcopy(state_op.primitive)
        if isinstance(target_params, list) and isinstance(
                target_params[0], tuple):
            tuples_list = deepcopy(target_params)
            target_params = []
            for tuples in tuples_list:
                if all([
                        param in state_qc._parameter_table.get_keys()
                        for param in tuples
                ]):
                    for param in tuples:
                        if param not in target_params:
                            target_params.append(param)
        elif isinstance(target_params, tuple):
            tuples_list = deepcopy([target_params])
            target_params = []
            for tuples in tuples_list:
                if all([
                        param in state_qc._parameter_table.get_keys()
                        for param in tuples
                ]):
                    for param in tuples:
                        if param not in target_params:
                            target_params.append(param)
        else:
            raise TypeError(
                'Please define in the parameters for which the Hessian is evaluated either '
                'as parameter tuple or a list of parameter tuples')

        qr_add0 = QuantumRegister(1, 'work_qubit0')
        work_q0 = qr_add0[0]
        qr_add1 = QuantumRegister(1, 'work_qubit1')
        work_q1 = qr_add1[0]
        # create a copy of the original circuit with an additional working qubit register
        circuit = state_qc.copy()
        circuit.add_register(qr_add0, qr_add1)
        # Get the circuits needed to compute the Hessian
        hessian_ops = None
        for param_a, param_b in tuples_list:

            if param_a not in state_qc._parameter_table.get_keys() or param_b \
                    not in state_qc._parameter_table.get_keys():
                hessian_op = ~Zero @ One
            else:
                param_gates_a = state_qc._parameter_table[param_a]
                param_gates_b = state_qc._parameter_table[param_b]
                for i, param_occurence_a in enumerate(param_gates_a):
                    coeffs_a, gates_a = self._gate_gradient_dict(
                        param_occurence_a[0])[param_occurence_a[1]]
                    # apply Hadamard on working qubit
                    self.insert_gate(circuit,
                                     param_occurence_a[0],
                                     HGate(),
                                     qubits=[work_q0])
                    self.insert_gate(circuit,
                                     param_occurence_a[0],
                                     HGate(),
                                     qubits=[work_q1])
                    for j, gate_to_insert_a in enumerate(gates_a):

                        coeff_a = coeffs_a[j]
                        hessian_circuit_temp = QuantumCircuit(*circuit.qregs)
                        hessian_circuit_temp.data = circuit.data
                        # Fix working qubit 0 phase
                        sign = np.sign(coeff_a)
                        is_complex = np.iscomplex(coeff_a)
                        if sign == -1:
                            if is_complex:
                                self.insert_gate(hessian_circuit_temp,
                                                 param_occurence_a[0],
                                                 SdgGate(),
                                                 qubits=[work_q0])
                            else:
                                self.insert_gate(hessian_circuit_temp,
                                                 param_occurence_a[0],
                                                 ZGate(),
                                                 qubits=[work_q0])
                        else:
                            if is_complex:
                                self.insert_gate(hessian_circuit_temp,
                                                 param_occurence_a[0],
                                                 SGate(),
                                                 qubits=[work_q0])

                        # Insert controlled, intercepting gate - controlled by |1>
                        if isinstance(param_occurence_a[0], UGate):
                            if param_occurence_a[1] == 0:
                                self.insert_gate(
                                    hessian_circuit_temp, param_occurence_a[0],
                                    RZGate(param_occurence_a[0].params[2]))
                                self.insert_gate(hessian_circuit_temp,
                                                 param_occurence_a[0],
                                                 RXGate(np.pi / 2))
                                self.insert_gate(hessian_circuit_temp,
                                                 param_occurence_a[0],
                                                 gate_to_insert_a,
                                                 additional_qubits=([work_q0],
                                                                    []))
                                self.insert_gate(hessian_circuit_temp,
                                                 param_occurence_a[0],
                                                 RXGate(-np.pi / 2))
                                self.insert_gate(
                                    hessian_circuit_temp, param_occurence_a[0],
                                    RZGate(-param_occurence_a[0].params[2]))

                            elif param_occurence_a[1] == 1:
                                self.insert_gate(hessian_circuit_temp,
                                                 param_occurence_a[0],
                                                 gate_to_insert_a,
                                                 after=True,
                                                 additional_qubits=([work_q0],
                                                                    []))
                            else:
                                self.insert_gate(hessian_circuit_temp,
                                                 param_occurence_a[0],
                                                 gate_to_insert_a,
                                                 additional_qubits=([work_q0],
                                                                    []))
                        else:
                            self.insert_gate(hessian_circuit_temp,
                                             param_occurence_a[0],
                                             gate_to_insert_a,
                                             additional_qubits=([work_q0], []))

                        for m, param_occurence_b in enumerate(param_gates_b):
                            coeffs_b, gates_b = self._gate_gradient_dict(
                                param_occurence_b[0])[param_occurence_b[1]]
                            for n, gate_to_insert_b in enumerate(gates_b):
                                coeff_b = coeffs_b[n]
                                # create a copy of the original circuit with the same registers
                                hessian_circuit = QuantumCircuit(
                                    *hessian_circuit_temp.qregs)
                                hessian_circuit.data = hessian_circuit_temp.data

                                # Fix working qubit 1 phase
                                sign = np.sign(coeff_b)
                                is_complex = np.iscomplex(coeff_b)
                                if sign == -1:
                                    if is_complex:
                                        self.insert_gate(hessian_circuit,
                                                         param_occurence_b[0],
                                                         SdgGate(),
                                                         qubits=[work_q1])
                                    else:
                                        self.insert_gate(hessian_circuit,
                                                         param_occurence_b[0],
                                                         ZGate(),
                                                         qubits=[work_q1])
                                else:
                                    if is_complex:
                                        self.insert_gate(hessian_circuit,
                                                         param_occurence_b[0],
                                                         SGate(),
                                                         qubits=[work_q1])

                                # Insert controlled, intercepting gate - controlled by |1>

                                if isinstance(param_occurence_b[0], UGate):
                                    if param_occurence_b[1] == 0:
                                        self.insert_gate(
                                            hessian_circuit,
                                            param_occurence_b[0],
                                            RZGate(param_occurence_b[0].
                                                   params[2]))
                                        self.insert_gate(
                                            hessian_circuit,
                                            param_occurence_b[0],
                                            RXGate(np.pi / 2))
                                        self.insert_gate(
                                            hessian_circuit,
                                            param_occurence_b[0],
                                            gate_to_insert_b,
                                            additional_qubits=([work_q1], []))
                                        self.insert_gate(
                                            hessian_circuit,
                                            param_occurence_b[0],
                                            RXGate(-np.pi / 2))
                                        self.insert_gate(
                                            hessian_circuit,
                                            param_occurence_b[0],
                                            RZGate(-param_occurence_b[0].
                                                   params[2]))

                                    elif param_occurence_b[1] == 1:
                                        self.insert_gate(
                                            hessian_circuit,
                                            param_occurence_b[0],
                                            gate_to_insert_b,
                                            after=True,
                                            additional_qubits=([work_q1], []))
                                    else:
                                        self.insert_gate(
                                            hessian_circuit,
                                            param_occurence_b[0],
                                            gate_to_insert_b,
                                            additional_qubits=([work_q1], []))
                                else:
                                    self.insert_gate(
                                        hessian_circuit,
                                        param_occurence_b[0],
                                        gate_to_insert_b,
                                        additional_qubits=([work_q1], []))

                                hessian_circuit.h(work_q0)
                                hessian_circuit.cz(work_q1, work_q0)
                                hessian_circuit.h(work_q1)

                                term = state_op.coeff * np.sqrt(np.abs(coeff_a) * np.abs(coeff_b)) \
                                                      * CircuitStateFn(hessian_circuit)

                                # Chain Rule Parameter Expression
                                gate_param_a = param_occurence_a[0].params[
                                    param_occurence_a[1]]
                                gate_param_b = param_occurence_b[0].params[
                                    param_occurence_b[1]]

                                if meas_op:
                                    meas = deepcopy(meas_op)
                                    if isinstance(gate_param_a,
                                                  ParameterExpression):
                                        expr_grad = DerivativeBase.parameter_expression_grad(
                                            gate_param_a, param_a)
                                        meas *= expr_grad
                                    if isinstance(gate_param_b,
                                                  ParameterExpression):
                                        expr_grad = DerivativeBase.parameter_expression_grad(
                                            gate_param_a, param_a)
                                        meas *= expr_grad
                                    term = meas @ term
                                else:
                                    term = ListOp([term],
                                                  combo_fn=partial(
                                                      self._hess_combo_fn,
                                                      state_op=state_op))
                                    if isinstance(gate_param_a,
                                                  ParameterExpression):
                                        expr_grad = DerivativeBase.parameter_expression_grad(
                                            gate_param_a, param_a)
                                        term *= expr_grad
                                    if isinstance(gate_param_b,
                                                  ParameterExpression):
                                        expr_grad = DerivativeBase.parameter_expression_grad(
                                            gate_param_a, param_a)
                                        term *= expr_grad

                                if i == 0 and j == 0 and m == 0 and n == 0:
                                    hessian_op = term
                                else:
                                    # Product Rule
                                    hessian_op += term
            # Create a list of Hessian elements w.r.t. the given parameter tuples
            if len(tuples_list) == 1:
                return hessian_op
            else:
                if not hessian_ops:
                    hessian_ops = [hessian_op]
                else:
                    hessian_ops += [hessian_op]
        return ListOp(hessian_ops)
예제 #17
0
        ('z', 'h', 'z'),
        # u3 gates
        (
            'x', ),
        ('y', ),
        ('s', 'x'),
        ('sdg', 'x')
    ]
    return labels[j]


_CLIFFORD_GATES = [
    (IGate(), ),
    (SGate(), ),
    (SdgGate(), ),
    (ZGate(), ),
    # u2 gates
    (HGate(), ),
    (HGate(), ZGate()),
    (ZGate(), HGate()),
    (HGate(), SGate()),
    (SGate(), HGate()),
    (HGate(), SdgGate()),
    (SdgGate(), HGate()),
    (SGate(), HGate(), SGate()),
    (SdgGate(), HGate(), SGate()),
    (ZGate(), HGate(), SGate()),
    (SGate(), HGate(), SdgGate()),
    (SdgGate(), HGate(), SdgGate()),
    (ZGate(), HGate(), SdgGate()),
    (SGate(), HGate(), ZGate()),
예제 #18
0
파일: main.py 프로젝트: Talkal13/Quantum
#b = QuantumRegister(2)
#cq = QuantumRegister(4)
#anc = QuantumRegister(1)
c = ClassicalRegister(4)
qc = QuantumCircuit(a, c)

qc.h(a)

# qc.append(mult(2, 2), a[:] + b[:] + cq[:] + [anc])

# Oracle
oq = QuantumRegister(4)
O = QuantumCircuit(oq, name="Oracle")
O.x(oq[0])
O.x(oq[3])
O.append(ZGate().control(3), oq[:])
O.x(oq[0])
O.x(oq[3])

# Diffusor
d = QuantumRegister(4)
Dif = QuantumCircuit(d, name="Diffusor")
Dif.x(d)
Dif.h(d)
Dif.append(ZGate().control(3), d[:])
Dif.x(d)
Dif.h(d)

#oracle = CustomCircuitOracle(variable_register=oq, output_register=ancq, circuit=O)
g = Grover(4, O)
예제 #19
0
def _standard_gate_instruction(instruction, ignore_phase=True):
    """Temporary function to create Instruction objects from a json string,
    which is necessary for creating a new QuantumError object from deprecated
    json-based input. Note that the type of returned object is different from
    the deprecated standard_gate_instruction.
    TODO: to be removed after deprecation period.

    Args:
        instruction (dict): A qobj instruction.
        ignore_phase (bool): Ignore global phase on unitary matrix in
                             comparison to canonical unitary.

    Returns:
        list: a list of (instructions, qubits) equivalent to in input instruction.
    """
    gate = {
        "id": IGate(),
        "x": XGate(),
        "y": YGate(),
        "z": ZGate(),
        "h": HGate(),
        "s": SGate(),
        "sdg": SdgGate(),
        "t": TGate(),
        "tdg": TdgGate(),
        "cx": CXGate(),
        "cz": CZGate(),
        "swap": SwapGate()
    }

    name = instruction.get("name", None)
    qubits = instruction["qubits"]
    if name in gate:
        return [(gate[name], qubits)]

    if name not in ["mat", "unitary", "kraus"]:
        return [instruction]

    params = instruction["params"]
    with warnings.catch_warnings():
        warnings.filterwarnings("ignore",
                                category=DeprecationWarning,
                                module="qiskit.providers.aer.noise.errors.errorutils")

        # Check for single-qubit reset Kraus
        if name == "kraus":
            if len(qubits) == 1:
                superop = SuperOp(Kraus(params))
                # Check if reset to |0>
                reset0 = reset_superop(1)
                if superop == reset0:
                    return [(Reset(), [0])]
                # Check if reset to |1>
                reset1 = reset0.compose(Operator(standard_gate_unitary('x')))
                if superop == reset1:
                    return [(Reset(), [0]), (XGate(), [0])]
            return [instruction]

        # Check single qubit gates
        mat = params[0]
        if len(qubits) == 1:
            # Check clifford gates
            for j in range(24):
                if matrix_equal(
                        mat,
                        single_qubit_clifford_matrix(j),
                        ignore_phase=ignore_phase):
                    return [(gate, [0]) for gate in _CLIFFORD_GATES[j]]
            # Check t gates
            for name in ["t", "tdg"]:
                if matrix_equal(
                        mat,
                        standard_gate_unitary(name),
                        ignore_phase=ignore_phase):
                    return [(gate[name], qubits)]
            # TODO: u1,u2,u3 decomposition
        # Check two qubit gates
        if len(qubits) == 2:
            for name in ["cx", "cz", "swap"]:
                if matrix_equal(
                        mat,
                        standard_gate_unitary(name),
                        ignore_phase=ignore_phase):
                    return [(gate[name], qubits)]
            # Check reversed CX
            if matrix_equal(
                    mat,
                    standard_gate_unitary("cx_10"),
                    ignore_phase=ignore_phase):
                return [(CXGate(), [qubits[1], qubits[0]])]
            # Check 2-qubit Pauli's
            paulis = ["id", "x", "y", "z"]
            for pauli0 in paulis:
                for pauli1 in paulis:
                    pmat = np.kron(
                        standard_gate_unitary(pauli1),
                        standard_gate_unitary(pauli0))
                    if matrix_equal(mat, pmat, ignore_phase=ignore_phase):
                        if pauli0 == "id":
                            return [(gate[pauli1], [qubits[1]])]
                        elif pauli1 == "id":
                            return [(gate[pauli0], [qubits[0]])]
                        else:
                            return [(gate[pauli0], [qubits[0]]), (gate[pauli1], [qubits[1]])]
        # Check three qubit toffoli
        if len(qubits) == 3:
            if matrix_equal(
                    mat,
                    standard_gate_unitary("ccx_012"),
                    ignore_phase=ignore_phase):
                return [(CCXGate(), qubits)]
            if matrix_equal(
                    mat,
                    standard_gate_unitary("ccx_021"),
                    ignore_phase=ignore_phase):
                return [(CCXGate(), [qubits[0], qubits[2], qubits[1]])]
            if matrix_equal(
                    mat,
                    standard_gate_unitary("ccx_120"),
                    ignore_phase=ignore_phase):
                return [(CCXGate(), [qubits[1], qubits[2], qubits[0]])]

    # Else return input in
    return [instruction]
예제 #20
0
    def apply_grad_gate(circuit, gate, param_index, grad_gate, grad_coeff, qr_superpos,
                        open_ctrl=False, trim_after_grad_gate=False):
        """Util function to apply a gradient gate for the linear combination of unitaries method.

        Replaces the ``gate`` instance in ``circuit`` with ``grad_gate`` using ``qr_superpos`` as
        superposition qubit. Also adds the appropriate sign-fix gates on the superposition qubit.

        Args:
            circuit (QuantumCircuit): The circuit in which to do the replacements.
            gate (Gate): The gate instance to replace.
            param_index (int): The index of the parameter in ``gate``.
            grad_gate (Gate): A controlled gate encoding the gradient of ``gate``.
            grad_coeff (float): A coefficient to the gradient component. Might not be one if the
                gradient contains multiple summed terms.
            qr_superpos (QuantumRegister): A ``QuantumRegister`` of size 1 contained in ``circuit``
                that is used as control for ``grad_gate``.
            open_ctrl (bool): If True use an open control for ``grad_gate`` instead of closed.
            trim_after_grad_gate (bool): If True remove all gates after the ``grad_gate``. Can
                be used to reduce the circuit depth in e.g. computing an overlap of gradients.

        Returns:
            QuantumCircuit: A copy of the original circuit with the gradient gate added.

        Raises:
            RuntimeError: If ``gate`` is not in ``circuit``.
        """
        # copy the input circuit taking the gates by reference
        out = QuantumCircuit(*circuit.qregs)
        out._data = circuit._data.copy()
        out._parameter_table = ParameterTable({
            param: values.copy() for param, values in circuit._parameter_table.items()
        })

        # get the data index and qubits of the target gate  TODO use built-in
        gate_idx, gate_qubits = None, None
        for i, (op, qarg, _) in enumerate(out._data):
            if op is gate:
                gate_idx, gate_qubits = i, qarg
                break
        if gate_idx is None:
            raise RuntimeError('The specified gate could not be found in the circuit data.')

        # initialize replacement instructions
        replacement = []

        # insert the phase fix before the target gate better documentation
        sign = np.sign(grad_coeff)
        is_complex = np.iscomplex(grad_coeff)

        if sign < 0 and is_complex:
            replacement.append((SdgGate(), qr_superpos[:], []))
        elif sign < 0:
            replacement.append((ZGate(), qr_superpos[:], []))
        elif is_complex:
            replacement.append((SGate(), qr_superpos[:], []))
        # else no additional gate required

        # open control if specified
        if open_ctrl:
            replacement += [(XGate(), qr_superpos[:], [])]

        # compute the replacement
        if isinstance(gate, UGate) and param_index == 0:
            theta = gate.params[2]
            rz_plus, rz_minus = RZGate(theta), RZGate(-theta)
            replacement += [(rz_plus, [qubit], []) for qubit in gate_qubits]
            replacement += [(RXGate(np.pi / 2), [qubit], []) for qubit in gate_qubits]
            replacement.append((grad_gate, qr_superpos[:] + gate_qubits, []))
            replacement += [(RXGate(-np.pi / 2), [qubit], []) for qubit in gate_qubits]
            replacement += [(rz_minus, [qubit], []) for qubit in gate_qubits]

            # update parametertable if necessary
            if isinstance(theta, ParameterExpression):
                out._update_parameter_table(rz_plus)
                out._update_parameter_table(rz_minus)

            if open_ctrl:
                replacement += [(XGate(), qr_superpos[:], [])]

            if not trim_after_grad_gate:
                replacement.append((gate, gate_qubits, []))

        elif isinstance(gate, UGate) and param_index == 1:
            # gradient gate is applied after the original gate in this case
            replacement.append((gate, gate_qubits, []))
            replacement.append((grad_gate, qr_superpos[:] + gate_qubits, []))
            if open_ctrl:
                replacement += [(XGate(), qr_superpos[:], [])]

        else:
            replacement.append((grad_gate, qr_superpos[:] + gate_qubits, []))
            if open_ctrl:
                replacement += [(XGate(), qr_superpos[:], [])]
            if not trim_after_grad_gate:
                replacement.append((gate, gate_qubits, []))

        # replace the parameter we compute the derivative of with the replacement
        # TODO can this be done more efficiently?
        if trim_after_grad_gate:  # remove everything after the gradient gate
            out._data[gate_idx:] = replacement
            # reset parameter table
            table = ParameterTable()
            for op, _, _ in out._data:
                for idx, param_expression in enumerate(op.params):
                    if isinstance(param_expression, ParameterExpression):
                        for param in param_expression.parameters:
                            if param not in table.keys():
                                table[param] = [(op, idx)]
                            else:
                                table[param].append((op, idx))

            out._parameter_table = table

        else:
            out._data[gate_idx:gate_idx + 1] = replacement

        return out
def phase_oracle(list_values: list, circuit_type: str):
    n = len(list_values[0])  # Number of elements in one string.
    assert n >= 2, 'Length of input should be greater or equal to 2.'
    assert len(set(map(len, list_values))
               ) == 1, 'The values on your list should have the same length.'

    if (circuit_type == 'noancilla' or n == 2):
        q1 = QuantumRegister(n, "q")
        a1 = QuantumCircuit(q1)
        #a1.barrier()
        for element in list_values:
            ############ If an element in string equal 0 then apply X Gate on the left of the control dot.
            for i in range(n):
                if element[::-1][i] == '0':
                    a1.x(q1[i])
            ############
            # Apply n-1 qubits control Toffoli gate.
            gate = ZGate().control(n - 1)
            a1.append(gate, q1)
            ############ If an element in string equal 0 then apply X Gate on the right of the control dot.
            for i in range(n):
                if element[::-1][i] == '0':
                    a1.x(q1[i])
            ############
            #a1.barrier()

    elif circuit_type == 'ancilla':
        if n == 3:
            q1 = QuantumRegister(4, "q")
            a1 = QuantumCircuit(q1)
            for element in list_values:
                ############
                for i in range(n):
                    if element[::-1][i] == '0':
                        a1.x(q1[i])
                ############
                a1.ccx(0, 1, 3)
                a1.cz(3, 2)
                a1.ccx(0, 1, 3)
                ############
                for i in range(n):
                    if element[::-1][i] == '0':
                        a1.x(q1[i])
                ############
        else:
            pn, jn, kn = 2, 0, 1
            q1 = QuantumRegister(n + (n - 3), "q")
            a1 = QuantumCircuit(q1)
            #a1.barrier()
            for element in list_values:
                ############
                for i in range(n):
                    if element[::-1][i] == '0':
                        a1.x(q1[i])
                ############
                # Apply n-1 qubits control Toffoli gate using 2-qubits control Toffoli gates.
                a1.ccx(q1[0], q1[1], q1[n])
                for i in range(n - 4):
                    a1.ccx(q1[pn], q1[n + jn], q1[n + kn])
                    if i < n - 5:
                        pn += 1
                        jn += 1
                        kn += 1
                #a1.barrier()
                a1.h(q1[n - 1])
                a1.ccx(q1[(n - 2)], q1[n + (n - 4)], q1[n - 1])
                a1.h(q1[n - 1])
                #a1.barrier()

                for i in range(n - 4):
                    a1.ccx(q1[pn], q1[n + jn], q1[n + kn])
                    if i < n - 5:
                        pn += -1
                        jn += -1
                        kn += -1
                a1.ccx(q1[0], q1[1], q1[n])
                ############
                for i in range(n):
                    if element[::-1][i] == '0':
                        a1.x(q1[i])
                ############
                #a1.barrier()
    return a1
예제 #22
0
import qiskit
import numpy as np
from qiskit.circuit.library.standard_gates import ZGate

n = int(input("Digite o número do qubits: "))
k = int(input("Digite o target do qubits: "))
qc = qiskit.QuantumCircuit(n)
list_qu = list(range(n))
bin_k = ('{0:0' + str(n) + 'b}').format(k)
print(bin_k)

bin_k = bin_k[::-1]

for qu in range(n):
    qc.h(qu)

qc.append(ZGate("zgate").control(num_ctrl_qubits=n - 1), list_qu)

for i in range(n):
    if bin_k[i] == '0':
        qc.x(i)

backend = qiskit.Aer.get_backend('statevector_simulator')
job = qiskit.execute(qc, backend)
result = job.result()
print('Estado gerado pelo circuito: ', result.get_statevector())

print(qc.draw())
예제 #23
0
    def apply_grad_gate(
        circuit,
        gate,
        param_index,
        grad_gate,
        grad_coeff,
        qr_superpos,
        open_ctrl=False,
        trim_after_grad_gate=False,
    ):
        """Util function to apply a gradient gate for the linear combination of unitaries method.
        Replaces the ``gate`` instance in ``circuit`` with ``grad_gate`` using ``qr_superpos`` as
        superposition qubit. Also adds the appropriate sign-fix gates on the superposition qubit.

        Args:
            circuit (QuantumCircuit): The circuit in which to do the replacements.
            gate (Gate): The gate instance to replace.
            param_index (int): The index of the parameter in ``gate``.
            grad_gate (Gate): A controlled gate encoding the gradient of ``gate``.
            grad_coeff (float): A coefficient to the gradient component. Might not be one if the
                gradient contains multiple summed terms.
            qr_superpos (QuantumRegister): A ``QuantumRegister`` of size 1 contained in ``circuit``
                that is used as control for ``grad_gate``.
            open_ctrl (bool): If True use an open control for ``grad_gate`` instead of closed.
            trim_after_grad_gate (bool): If True remove all gates after the ``grad_gate``. Can
                be used to reduce the circuit depth in e.g. computing an overlap of gradients.

        Returns:
            QuantumCircuit: A copy of the original circuit with the gradient gate added.

        Raises:
            RuntimeError: If ``gate`` is not in ``circuit``.
        """
        qr_superpos_qubits = tuple(qr_superpos)
        # copy the input circuit taking the gates by reference
        out = QuantumCircuit(*circuit.qregs)
        out._data = circuit._data.copy()
        out._parameter_table = ParameterTable({
            param: values.copy()
            for param, values in circuit._parameter_table.items()
        })

        # get the data index and qubits of the target gate  TODO use built-in
        gate_idx, gate_qubits = None, None
        for i, instruction in enumerate(out._data):
            if instruction.operation is gate:
                gate_idx, gate_qubits = i, instruction.qubits
                break
        if gate_idx is None:
            raise RuntimeError(
                "The specified gate could not be found in the circuit data.")

        # initialize replacement instructions
        replacement = []

        # insert the phase fix before the target gate better documentation
        sign = np.sign(grad_coeff)
        is_complex = np.iscomplex(grad_coeff)

        if sign < 0 and is_complex:
            replacement.append(
                CircuitInstruction(SdgGate(), qr_superpos_qubits, ()))
        elif sign < 0:
            replacement.append(
                CircuitInstruction(ZGate(), qr_superpos_qubits, ()))
        elif is_complex:
            replacement.append(
                CircuitInstruction(SGate(), qr_superpos_qubits, ()))
        # else no additional gate required

        # open control if specified
        if open_ctrl:
            replacement += [
                CircuitInstruction(XGate(), qr_superpos_qubits, [])
            ]

        # compute the replacement
        if isinstance(gate, UGate) and param_index == 0:
            theta = gate.params[2]
            rz_plus, rz_minus = RZGate(theta), RZGate(-theta)
            replacement += [
                CircuitInstruction(rz_plus, (qubit, ), ())
                for qubit in gate_qubits
            ]
            replacement += [
                CircuitInstruction(RXGate(np.pi / 2), (qubit, ), ())
                for qubit in gate_qubits
            ]
            replacement.append(
                CircuitInstruction(grad_gate, qr_superpos_qubits + gate_qubits,
                                   []))
            replacement += [
                CircuitInstruction(RXGate(-np.pi / 2), (qubit, ), ())
                for qubit in gate_qubits
            ]
            replacement += [
                CircuitInstruction(rz_minus, (qubit, ), ())
                for qubit in gate_qubits
            ]

            # update parametertable if necessary
            if isinstance(theta, ParameterExpression):
                # This dangerously subverts ParameterTable by abusing the fact that binding will
                # mutate the exact instruction instance, and relies on all instances of `rz_plus`
                # that were added before being the same in memory, which QuantumCircuit usually
                # ensures is not the case.  I'm leaving this as close to its previous form as
                # possible, to avoid introducing further complications, but this whole method
                # accesses internal attributes of `QuantumCircuit` and needs rewriting.
                # - Jake Lishman, 2022-03-02.
                out._update_parameter_table(
                    CircuitInstruction(rz_plus, (gate_qubits[0], ), ()))
                out._update_parameter_table(
                    CircuitInstruction(rz_minus, (gate_qubits[0], ), ()))

            if open_ctrl:
                replacement.append(
                    CircuitInstruction(XGate(), qr_superpos_qubits, ()))

            if not trim_after_grad_gate:
                replacement.append(CircuitInstruction(gate, gate_qubits, ()))

        elif isinstance(gate, UGate) and param_index == 1:
            # gradient gate is applied after the original gate in this case
            replacement.append(CircuitInstruction(gate, gate_qubits, ()))
            replacement.append(
                CircuitInstruction(grad_gate, qr_superpos_qubits + gate_qubits,
                                   ()))
            if open_ctrl:
                replacement.append(
                    CircuitInstruction(XGate(), qr_superpos_qubits, ()))

        else:
            replacement.append(
                CircuitInstruction(grad_gate, qr_superpos_qubits + gate_qubits,
                                   ()))
            if open_ctrl:
                replacement.append(
                    CircuitInstruction(XGate(), qr_superpos_qubits, ()))
            if not trim_after_grad_gate:
                replacement.append(CircuitInstruction(gate, gate_qubits, ()))

        # replace the parameter we compute the derivative of with the replacement
        # TODO can this be done more efficiently?
        if trim_after_grad_gate:  # remove everything after the gradient gate
            out._data[gate_idx:] = replacement
            # reset parameter table
            table = ParameterTable()
            for instruction in out._data:
                for idx, param_expression in enumerate(
                        instruction.operation.params):
                    if isinstance(param_expression, ParameterExpression):
                        for param in param_expression.parameters:
                            if param not in table.keys():
                                table[param] = ParameterReferences(
                                    ((instruction.operation, idx), ))
                            else:
                                table[param].add((instruction.operation, idx))

            out._parameter_table = table

        else:
            out._data[gate_idx:gate_idx + 1] = replacement

        return out
예제 #24
0
def depolarizing_error(param, num_qubits, standard_gates=None):
    r"""
    Return a depolarizing quantum error channel.

    The depolarizing channel is defined as:

    .. math::

        E(ρ) = (1 - λ) ρ + λ \text{Tr}[ρ] \frac{I}{2^n}

    with :math:`0 \le λ \le 4^n / (4^n - 1)`

    where :math:`λ` is the depolarizing error param and :math`n` is the
    number of qubits.

    * If :math:`λ = 0` this is the identity channel :math:`E(ρ) = ρ`
    * If :math:`λ = 1` this is a completely depolarizing channel
      :math:`E(ρ) = I / 2^n`
    * If :math:`λ = 4^n / (4^n - 1)` this is a uniform Pauli
      error channel: :math:`E(ρ) = \sum_j P_j ρ P_j / (4^n - 1)` for
      all :math:`P_j != I`.

    Args:
        param (double): depolarizing error parameter.
        num_qubits (int): the number of qubits for the error channel.
        standard_gates (bool): DEPRECATED, if True return the operators as
                               Pauli gates. If false return as unitary gates.
                               (Default: None)

    Returns:
        QuantumError: The quantum error object.

    Raises:
        NoiseError: If noise parameters are invalid.
    """
    if not isinstance(num_qubits, int) or num_qubits < 1:
        raise NoiseError("num_qubits must be a positive integer.")
    # Check that the depolarizing parameter gives a valid CPTP
    num_terms = 4**num_qubits
    max_param = num_terms / (num_terms - 1)
    if param < 0 or param > max_param:
        raise NoiseError("Depolarizing parameter must be in between 0 "
                         "and {}.".format(max_param))

    # Rescale completely depolarizing channel error probs
    # with the identity component removed
    prob_iden = 1 - param / max_param
    prob_pauli = param / num_terms
    probs = [prob_iden] + (num_terms - 1) * [prob_pauli]

    if standard_gates is not None:
        warnings.warn(
            '"standard_gates" option has been deprecated as of qiskit-aer 0.10.0'
            ' and will be removed no earlier than 3 months from that release date.',
            DeprecationWarning,
            stacklevel=2)
        circs = []
        for pauli_list in it.product(
            [IGate(), XGate(), YGate(), ZGate()], repeat=num_qubits):
            qc = QuantumCircuit(num_qubits)
            for q, pauli in enumerate(pauli_list):
                if not standard_gates:
                    pauli = UnitaryGate(pauli.to_matrix())
                qc.append(pauli, qargs=[q])
            circs.append(qc)
        return QuantumError(zip(circs, probs))

    # Generate pauli strings. The order doesn't matter as long
    # as the all identity string is first.
    paulis = [
        Pauli("".join(tup))
        for tup in it.product(['I', 'X', 'Y', 'Z'], repeat=num_qubits)
    ]
    return QuantumError(zip(paulis, probs))
from qiskit.circuit.library.standard_gates import ZGate, HGate

# import basic plot tools
from qiskit.visualization import plot_histogram
n = 4

grover_circuit = QuantumCircuit(n)

for qubit in range(n):
    grover_circuit.h(qubit)

grover_circuit.barrier()
grover_circuit.x(1)
grover_circuit.x(3)

c3z_gate = ZGate().control(3)

grover_circuit.append(c3z_gate, [3, 2, 1, 0])

grover_circuit.x(1)
grover_circuit.x(3)
grover_circuit.barrier()
for qubit in range(n):
    grover_circuit.h(qubit)

grover_circuit.draw(
    'mpl', 1,
    'C:/Users/Familie/Documents/QuantumComputers/grover_circuit_4qubits_oracle_0101.png'
)
plt.show(grover_circuit)