from qiskit.circuit import QuantumCircuit
from qiskit.compiler import transpile, assemble
from qiskit.providers.ibmq import least_busy
from qiskit.tools.monitor import job_monitor

try:
    IBMQ.load_accounts()
except:
    print("""WARNING: There's no connection with the API for remote backends.
             Have you initialized a file with your personal token?
             For now, there's only access to local simulator backends...""")

try:

    # Making first circuit: bell state
    qc1 = QuantumCircuit(2, 2, name="bell")
    qc1.h(0)
    qc1.cx(0, 1)
    qc1.measure([0, 1], [0, 1])

    # Making another circuit: superpositions
    qc2 = QuantumCircuit(2, 2, name="superposition")
    qc2.h([0, 1])
    qc2.measure([0, 1], [0, 1])

    # Setting up the backend
    print("(Aer Backends)")
    for backend in BasicAer.backends():
        print(backend.status())
    qasm_simulator = BasicAer.get_backend('qasm_simulator')
Exemplo n.º 2
0
    def test_paper_example(self):
        """Test synthesis of a diagonal operator from the paper.

        The diagonal operator in Example 4.2
            U|x> = e^(2.pi.i.f(x))|x>,
        where
            f(x) = 1/8*(x1^x2 + x0 + x0^x3 + x0^x1^x2 + x0^x1^x3 + x0^x1)

        The algorithm should take the following matrix as an input:
        S = [[0, 1, 1, 1, 1, 1],
             [1, 0, 0, 1, 1, 1],
             [1, 0, 0, 1, 0, 0],
             [0, 0, 1, 0, 1, 0]]

        and only T gates as phase rotations,

        And should return the following circuit (or an equivalent one):
                ┌───┐┌───┐     ┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐     ┌───┐
        q_0: |0>┤ T ├┤ X ├─────┤ T ├┤ X ├┤ X ├┤ T ├┤ X ├┤ T ├┤ X ├┤ T ├┤ X ├─────┤ X ├
                ├───┤└─┬─┘┌───┐└───┘└─┬─┘└─┬─┘└───┘└─┬─┘└───┘└─┬─┘└───┘└─┬─┘┌───┐└─┬─┘
        q_1: |0>┤ X ├──┼──┤ T ├───────■────┼─────────┼─────────┼─────────■──┤ X ├──┼──
                └─┬─┘  │  └───┘            │         │         │            └─┬─┘  │
        q_2: |0>──■────┼───────────────────┼─────────■─────────┼──────────────■────┼──
                       │                   │                   │                   │
        q_3: |0>───────■───────────────────■───────────────────■───────────────────■──
        """
        cnots = [[0, 1, 1, 1, 1, 1], [1, 0, 0, 1, 1, 1], [1, 0, 0, 1, 0, 0],
                 [0, 0, 1, 0, 1, 0]]
        angles = ['t'] * 6
        c_gray = graysynth(cnots, angles)
        unitary_gray = UnitaryGate(Operator(c_gray))

        # Create the circuit displayed above:
        q = QuantumRegister(4, 'q')
        c_compare = QuantumCircuit(q)
        c_compare.t(q[0])
        c_compare.cx(q[2], q[1])
        c_compare.cx(q[3], q[0])
        c_compare.t(q[0])
        c_compare.t(q[1])
        c_compare.cx(q[1], q[0])
        c_compare.cx(q[3], q[0])
        c_compare.t(q[0])
        c_compare.cx(q[2], q[0])
        c_compare.t(q[0])
        c_compare.cx(q[3], q[0])
        c_compare.t(q[0])
        c_compare.cx(q[1], q[0])
        c_compare.cx(q[2], q[1])
        c_compare.cx(q[3], q[0])
        unitary_compare = UnitaryGate(Operator(c_compare))

        # Check if the two circuits are equivalent
        self.assertEqual(unitary_gray, unitary_compare)
Exemplo n.º 3
0
    def test_parameter_binding_on_listop(self):
        """Test passing a ListOp with differing parameters works with the circuit sampler."""
        try:
            from qiskit.providers.aer import Aer
        except Exception as ex:  # pylint: disable=broad-except
            self.skipTest(
                "Aer doesn't appear to be installed. Error: '{}'".format(
                    str(ex)))
            return
        x, y = Parameter('x'), Parameter('y')

        circuit1 = QuantumCircuit(1)
        circuit1.p(0.2, 0)
        circuit2 = QuantumCircuit(1)
        circuit2.p(x, 0)
        circuit3 = QuantumCircuit(1)
        circuit3.p(y, 0)

        bindings = {x: -0.4, y: 0.4}
        listop = ListOp(
            [StateFn(circuit) for circuit in [circuit1, circuit2, circuit3]])

        sampler = CircuitSampler(Aer.get_backend('qasm_simulator'))
        sampled = sampler.convert(listop, params=bindings)

        self.assertTrue(all(len(op.parameters) == 0 for op in sampled.oplist))
Exemplo n.º 4
0
 def __init__(self):
     """Initialize Pauli preparation basis"""
     # |0> Zp rotation
     prep_zp = QuantumCircuit(1, name="PauliPrepZp")
     # |1> Zm rotation
     prep_zm = QuantumCircuit(1, name="PauliPrepZm")
     prep_zm.append(XGate(), [0])
     # |+> Xp rotation
     prep_xp = QuantumCircuit(1, name="PauliPrepXp")
     prep_xp.append(HGate(), [0])
     # |+i> Yp rotation
     prep_yp = QuantumCircuit(1, name="PauliPrepYp")
     prep_yp.append(HGate(), [0])
     prep_yp.append(SGate(), [0])
     super().__init__("PauliPreparationBasis",
                      [prep_zp, prep_zm, prep_xp, prep_yp])
Exemplo n.º 5
0
    def test_patel_markov_hayes(self):
        """Test synthesis of a small linear circuit
        (example from paper, Figure 3).

        The algorithm should take the following matrix as an input:
        S = [[1, 1, 0, 0, 0, 0],
             [1, 0, 0, 1, 1, 0],
             [0, 1, 0, 0, 1, 0],
             [1, 1, 1, 1, 1, 1],
             [1, 1, 0, 1, 1, 1],
             [0, 0, 1, 1, 1, 0]]

        And should return the following circuit (or an equivalent one):
                          ┌───┐
        q_0: |0>──────────┤ X ├──────────────────────────────────────────■────■────■──
                          └─┬─┘┌───┐                                   ┌─┴─┐  │    │
        q_1: |0>────────────■──┤ X ├────────────────────────────────■──┤ X ├──┼────┼──
                     ┌───┐     └─┬─┘┌───┐          ┌───┐          ┌─┴─┐└───┘  │    │
        q_2: |0>─────┤ X ├───────┼──┤ X ├───────■──┤ X ├───────■──┤ X ├───────┼────┼──
                ┌───┐└─┬─┘       │  └─┬─┘┌───┐┌─┴─┐└─┬─┘       │  └───┘       │  ┌─┴─┐
        q_3: |0>┤ X ├──┼─────────■────┼──┤ X ├┤ X ├──■────■────┼──────────────┼──┤ X ├
                └─┬─┘  │              │  └─┬─┘├───┤       │  ┌─┴─┐          ┌─┴─┐└───┘
        q_4: |0>──■────┼──────────────■────■──┤ X ├───────┼──┤ X ├──────────┤ X ├─────
                       │                      └─┬─┘     ┌─┴─┐└───┘          └───┘
        q_5: |0>───────■────────────────────────■───────┤ X ├─────────────────────────
                                                        └───┘
        """
        state = [[1, 1, 0, 0, 0, 0], [1, 0, 0, 1, 1, 0], [0, 1, 0, 0, 1, 0],
                 [1, 1, 1, 1, 1, 1], [1, 1, 0, 1, 1, 1], [0, 0, 1, 1, 1, 0]]
        c_patel = cnot_synth(state)

        # Create the circuit displayed above:
        q = QuantumRegister(6, 'q')
        c_compare = QuantumCircuit(q)
        c_compare.cx(q[4], q[3])
        c_compare.cx(q[5], q[2])
        c_compare.cx(q[1], q[0])
        c_compare.cx(q[3], q[1])
        c_compare.cx(q[4], q[2])
        c_compare.cx(q[4], q[3])
        c_compare.cx(q[5], q[4])
        c_compare.cx(q[2], q[3])
        c_compare.cx(q[3], q[2])
        c_compare.cx(q[3], q[5])
        c_compare.cx(q[2], q[4])
        c_compare.cx(q[1], q[2])
        c_compare.cx(q[0], q[1])
        c_compare.cx(q[0], q[4])
        c_compare.cx(q[0], q[3])

        # Check if the two circuits are equivalent
        self.assertEqual(c_patel, c_compare)
 def test_apply_cx_to_non_register(self):
     """test applying ccx to non-register raises"""
     qr = QuantumRegister(10)
     cr = ClassicalRegister(10)
     qc = QuantumCircuit(qr, cr)
     self.assertRaises(CircuitError, qc.cx, qc[0:2], qc[2:4])
Exemplo n.º 7
0
 def __init__(self):
     # |0> Zp rotation
     prep_zp = QuantumCircuit(1, name="PauliPrepZp")
     # |1> Zm rotation
     prep_zm = QuantumCircuit(1, name="PauliPrepZm")
     prep_zm.append(XGate(), [0])
     # |+> Xp rotation
     prep_xp = QuantumCircuit(1, name="PauliPrepXp")
     prep_xp.append(HGate(), [0])
     # |-> Xm rotation
     prep_xm = QuantumCircuit(1, name="PauliPrepXm")
     prep_xm.append(HGate(), [0])
     prep_xm.append(ZGate(), [0])
     # |+i> Yp rotation
     prep_yp = QuantumCircuit(1, name="PauliPrepYp")
     prep_yp.append(HGate(), [0])
     prep_yp.append(SGate(), [0])
     # |-i> Ym rotation
     prep_ym = QuantumCircuit(1, name="PauliPrepYm")
     prep_ym.append(HGate(), [0])
     prep_ym.append(SdgGate(), [0])
     super().__init__(
         "Pauli6PreparationBasis",
         [
             prep_zp,
             prep_zm,
             prep_xp,
             prep_xm,
             prep_yp,
             prep_ym,
         ],
     )
Exemplo n.º 8
0
 def test_dag_depth2(self):
     """Test barrier increases DAG depth
     """
     q = QuantumRegister(5, 'q')
     c = ClassicalRegister(1, 'c')
     qc = QuantumCircuit(q, c)
     qc.h(q[0])
     qc.cx(q[0], q[4])
     qc.x(q[2])
     qc.x(q[2])
     qc.x(q[2])
     qc.x(q[4])
     qc.cx(q[4], q[1])
     qc.barrier(q)
     qc.measure(q[1], c[0])
     dag = circuit_to_dag(qc)
     self.assertEqual(dag.depth(), 6)
Exemplo n.º 9
0
 def test_dag_depth3(self):
     """Test DAG depth for silly circuit.
     """
     q = QuantumRegister(6, 'q')
     c = ClassicalRegister(1, 'c')
     qc = QuantumCircuit(q, c)
     qc.h(q[0])
     qc.cx(q[0], q[1])
     qc.cx(q[1], q[2])
     qc.cx(q[2], q[3])
     qc.cx(q[3], q[4])
     qc.cx(q[4], q[5])
     qc.barrier(q[0])
     qc.barrier(q[0])
     qc.measure(q[0], c[0])
     dag = circuit_to_dag(qc)
     self.assertEqual(dag.depth(), 6)
Exemplo n.º 10
0
    def test_nested_parameters_are_recognised(self):
        """Verify that parameters added inside a control-flow operator get added to the outer
        circuit table."""
        x, y = Parameter("x"), Parameter("y")

        with self.subTest("if/else"):
            body1 = QuantumCircuit(1, 1)
            body1.rx(x, 0)
            body2 = QuantumCircuit(1, 1)
            body2.rx(y, 0)

            main = QuantumCircuit(1, 1)
            main.if_else((main.clbits[0], 0), body1, body2, [0], [0])
            self.assertEqual({x, y}, set(main.parameters))

        with self.subTest("while"):
            body = QuantumCircuit(1, 1)
            body.rx(x, 0)

            main = QuantumCircuit(1, 1)
            main.while_loop((main.clbits[0], 0), body, [0], [0])
            self.assertEqual({x}, set(main.parameters))

        with self.subTest("for"):
            body = QuantumCircuit(1, 1)
            body.rx(x, 0)

            main = QuantumCircuit(1, 1)
            main.for_loop(range(1), None, body, [0], [0])
            self.assertEqual({x}, set(main.parameters))
Exemplo n.º 11
0
    def test_nested_parameters_can_be_assigned(self):
        """Verify that parameters added inside a control-flow operator can be assigned by calls to
        the outer circuit."""
        x, y = Parameter("x"), Parameter("y")

        with self.subTest("if/else"):
            body1 = QuantumCircuit(1, 1)
            body1.rx(x, 0)
            body2 = QuantumCircuit(1, 1)
            body2.rx(y, 0)

            test = QuantumCircuit(1, 1)
            test.if_else((test.clbits[0], 0), body1, body2, [0], [0])
            self.assertEqual({x, y}, set(test.parameters))
            assigned = test.assign_parameters({x: math.pi, y: 0.5 * math.pi})
            self.assertEqual(set(), set(assigned.parameters))

            expected = QuantumCircuit(1, 1)
            expected.if_else(
                (expected.clbits[0], 0),
                body1.assign_parameters({x: math.pi}),
                body2.assign_parameters({y: 0.5 * math.pi}),
                [0],
                [0],
            )

            self.assertEqual(assigned, expected)

        with self.subTest("while"):
            body = QuantumCircuit(1, 1)
            body.rx(x, 0)

            test = QuantumCircuit(1, 1)
            test.while_loop((test.clbits[0], 0), body, [0], [0])
            self.assertEqual({x}, set(test.parameters))
            assigned = test.assign_parameters({x: math.pi})
            self.assertEqual(set(), set(assigned.parameters))

            expected = QuantumCircuit(1, 1)
            expected.while_loop(
                (expected.clbits[0], 0),
                body.assign_parameters({x: math.pi}),
                [0],
                [0],
            )

            self.assertEqual(assigned, expected)

        with self.subTest("for"):
            body = QuantumCircuit(1, 1)
            body.rx(x, 0)

            test = QuantumCircuit(1, 1)
            test.for_loop(range(1), None, body, [0], [0])
            self.assertEqual({x}, set(test.parameters))
            assigned = test.assign_parameters({x: math.pi})
            self.assertEqual(set(), set(assigned.parameters))

            expected = QuantumCircuit(1, 1)
            expected.for_loop(
                range(1),
                None,
                body.assign_parameters({x: math.pi}),
                [0],
                [0],
            )

            self.assertEqual(assigned, expected)
    def _build(self):
        # do not build the circuit if _data is already populated
        if self._data is not None:
            return

        self._data = []

        # check whether the configuration is valid
        self._check_configuration()

        circuit = QuantumCircuit(*self.qregs, name=self.name)
        qr_state = circuit.qubits[:self.num_state_qubits]
        qr_target = circuit.qubits[self.num_state_qubits]

        rotation_coeffs = self._get_rotation_coefficients()

        if self.basis == "x":
            circuit.rx(self.coeffs[0], qr_target)
        elif self.basis == "y":
            circuit.ry(self.coeffs[0], qr_target)
        else:
            circuit.rz(self.coeffs[0], qr_target)

        for c in rotation_coeffs:
            qr_control = []
            if self.reverse:
                for i, _ in enumerate(c):
                    if c[i] > 0:
                        qr_control.append(qr_state[qr_state.size - i - 1])
            else:
                for i, _ in enumerate(c):
                    if c[i] > 0:
                        qr_control.append(qr_state[i])

            # apply controlled rotations
            if len(qr_control) > 1:
                if self.basis == "x":
                    circuit.mcrx(rotation_coeffs[c], qr_control, qr_target)
                elif self.basis == "y":
                    circuit.mcry(rotation_coeffs[c], qr_control, qr_target)
                else:
                    circuit.mcrz(rotation_coeffs[c], qr_control, qr_target)

            elif len(qr_control) == 1:
                if self.basis == "x":
                    circuit.crx(rotation_coeffs[c], qr_control[0], qr_target)
                elif self.basis == "y":
                    circuit.cry(rotation_coeffs[c], qr_control[0], qr_target)
                else:
                    circuit.crz(rotation_coeffs[c], qr_control[0], qr_target)

        self.append(circuit.to_gate(), self.qubits)
Exemplo n.º 13
0
    def convert(
        self,
        operator: CircuitStateFn,
        params: Union[ParameterExpression, ParameterVector,
                      List[ParameterExpression]],
    ) -> ListOp:
        r"""
        Args:
            operator: The operator corresponding to the quantum state :math:`|\psi(\omega)\rangle`
                for which we compute the QFI.
            params: The parameters :math:`\omega` with respect to which we are computing the QFI.
        Returns:
            A ``ListOp[ListOp]`` where the operator at position ``[k][l]`` corresponds to the matrix
            element :math:`k, l` of the QFI.

        Raises:
            TypeError: If ``operator`` is an unsupported type.
        """
        # QFI & phase fix observable
        qfi_observable = StateFn(4 * self._aux_meas_op ^
                                 (I ^ operator.num_qubits),
                                 is_measurement=True)

        # Check if the given operator corresponds to a quantum state given as a circuit.
        if not isinstance(operator, CircuitStateFn):
            raise TypeError(
                "LinCombFull is only compatible with states that are given as "
                f"CircuitStateFn, not {type(operator)}")

        # If a single parameter is given wrap it into a list.
        if isinstance(params, ParameterExpression):
            params = [params]
        elif isinstance(params, ParameterVector):
            params = params[:]  # unroll to list

        if self._phase_fix:
            # First, the operators are computed which can compensate for a potential phase-mismatch
            # between target and trained state, i.e.〈ψ|∂lψ〉
            phase_fix_observable = I ^ operator.num_qubits
            gradient_states = LinComb(
                aux_meas_op=(Z - 1j * Y))._gradient_states(
                    operator,
                    meas_op=phase_fix_observable,
                    target_params=params,
                    open_ctrl=False,
                    trim_after_grad_gate=True,
                )

            # pylint: disable=unidiomatic-typecheck
            if type(gradient_states) == ListOp:
                phase_fix_states = gradient_states.oplist
            else:
                phase_fix_states = [gradient_states]

        # Get  4 * Re[〈∂kψ|∂lψ]
        qfi_operators = []
        # Add a working qubit
        qr_work = QuantumRegister(1, "work_qubit")
        state_qc = QuantumCircuit(*operator.primitive.qregs, qr_work)
        state_qc.h(qr_work)
        # unroll separately from the H gate since we need the H gate to be the first
        # operation in the data attributes of the circuit
        unrolled = LinComb._transpile_to_supported_operations(
            operator.primitive, LinComb.SUPPORTED_GATES)
        state_qc.compose(unrolled, inplace=True)

        # Get the circuits needed to compute〈∂iψ|∂jψ〉
        for i, param_i in enumerate(params):  # loop over parameters
            qfi_ops = []
            for j, param_j in enumerate(params[i:], i):
                # Get the gates of the quantum state which are parameterized by param_i
                qfi_op = []
                param_gates_i = state_qc._parameter_table[param_i]
                for gate_i, idx_i in param_gates_i:
                    grad_coeffs_i, grad_gates_i = LinComb._gate_gradient_dict(
                        gate_i)[idx_i]

                    # get the location of gate_i, used for trimming
                    location_i = None
                    for idx, (op, _, _) in enumerate(state_qc._data):
                        if op is gate_i:
                            location_i = idx
                            break

                    for grad_coeff_i, grad_gate_i in zip(
                            grad_coeffs_i, grad_gates_i):

                        # Get the gates of the quantum state which are parameterized by param_j
                        param_gates_j = state_qc._parameter_table[param_j]
                        for gate_j, idx_j in param_gates_j:
                            grad_coeffs_j, grad_gates_j = LinComb._gate_gradient_dict(
                                gate_j)[idx_j]

                            # get the location of gate_j, used for trimming
                            location_j = None
                            for idx, (op, _, _) in enumerate(state_qc._data):
                                if op is gate_j:
                                    location_j = idx
                                    break

                            for grad_coeff_j, grad_gate_j in zip(
                                    grad_coeffs_j, grad_gates_j):

                                grad_coeff_ij = np.conj(
                                    grad_coeff_i) * grad_coeff_j
                                qfi_circuit = LinComb.apply_grad_gate(
                                    state_qc,
                                    gate_i,
                                    idx_i,
                                    grad_gate_i,
                                    grad_coeff_ij,
                                    qr_work,
                                    open_ctrl=True,
                                    trim_after_grad_gate=(location_j <
                                                          location_i),
                                )

                                # create a copy of the original circuit with the same registers
                                qfi_circuit = LinComb.apply_grad_gate(
                                    qfi_circuit,
                                    gate_j,
                                    idx_j,
                                    grad_gate_j,
                                    1,
                                    qr_work,
                                    open_ctrl=False,
                                    trim_after_grad_gate=(location_j >=
                                                          location_i),
                                )

                                qfi_circuit.h(qr_work)
                                # Convert the quantum circuit into a CircuitStateFn and add the
                                # coefficients i, j and the original operator coefficient
                                coeff = operator.coeff
                                coeff *= np.sqrt(
                                    np.abs(grad_coeff_i) *
                                    np.abs(grad_coeff_j))
                                state = CircuitStateFn(qfi_circuit,
                                                       coeff=coeff)

                                param_grad = 1
                                for gate, idx, param in zip(
                                    [gate_i, gate_j], [idx_i, idx_j],
                                    [param_i, param_j]):
                                    param_expression = gate.params[idx]
                                    param_grad *= param_expression.gradient(
                                        param)
                                meas = param_grad * qfi_observable

                                term = meas @ state

                                qfi_op.append(term)

                # Compute −4 * Re(〈∂kψ|ψ〉〈ψ|∂lψ〉)
                def phase_fix_combo_fn(x):
                    return -4 * np.real(x[0] * np.conjugate(x[1]))

                if self._phase_fix:
                    phase_fix_op = ListOp(
                        [phase_fix_states[i], phase_fix_states[j]],
                        combo_fn=phase_fix_combo_fn)
                    # Add the phase fix quantities to the entries of the QFI
                    # Get 4 * Re[〈∂kψ|∂lψ〉−〈∂kψ|ψ〉〈ψ|∂lψ〉]
                    qfi_ops += [SummedOp(qfi_op) + phase_fix_op]
                else:
                    qfi_ops += [SummedOp(qfi_op)]

            qfi_operators.append(ListOp(qfi_ops))

        # Return estimate of the full QFI -- A QFI is by definition positive semi-definite.
        return ListOp(qfi_operators, combo_fn=triu_to_dense)
Exemplo n.º 14
0
    def test_compose_works(self):
        """Test that the circuit is constructed when compose is called."""
        qc = QuantumCircuit(3)
        qc.x([0, 1, 2])
        circuit = MockBlueprint(3)
        circuit.compose(qc, inplace=True)

        reference = QuantumCircuit(3)
        reference.rx(list(circuit.parameters)[0], 0)
        reference.h([0, 1, 2])
        reference.x([0, 1, 2])

        self.assertEqual(reference, circuit)
 def test_apply_ccx_to_slice(self):
     """test applying ccx to register slice"""
     qcontrol = QuantumRegister(10)
     qcontrol2 = QuantumRegister(10)
     qtarget = QuantumRegister(5)
     qtarget2 = QuantumRegister(10)
     qc = QuantumCircuit(qcontrol, qtarget)
     # test slice with skip and full register target
     qc.ccx(qcontrol[1::2], qcontrol[0::2], qtarget)
     self.assertEqual(len(qc.data), 5)
     for i, ictl, (gate, qargs, _) in zip(range(len(qc.data)), range(0, 10, 2), qc.data):
         self.assertEqual(gate.name, 'ccx')
         self.assertEqual(len(qargs), 3)
         self.assertIn(qargs[0].index, [ictl, ictl + 1])
         self.assertIn(qargs[1].index, [ictl, ictl + 1])
         self.assertEqual(qargs[2].index, i)
     # test decrementing slice
     qc = QuantumCircuit(qcontrol, qtarget)
     qc.ccx(qcontrol[2:0:-1], qcontrol[4:6], qtarget[0:2])
     self.assertEqual(len(qc.data), 2)
     for (gate, qargs, _), ictl1, ictl2, itgt in zip(qc.data, range(2, 0, -1),
                                                     range(4, 6), range(0, 2)):
         self.assertEqual(gate.name, 'ccx')
         self.assertEqual(len(qargs), 3)
         self.assertEqual(qargs[0].index, ictl1)
         self.assertEqual(qargs[1].index, ictl2)
         self.assertEqual(qargs[2].index, itgt)
     # test register expansion in ccx
     qc = QuantumCircuit(qcontrol, qcontrol2, qtarget2)
     qc.ccx(qcontrol, qcontrol2, qtarget2)
     for i, (gate, qargs, _) in enumerate(qc.data):
         self.assertEqual(gate.name, 'ccx')
         self.assertEqual(len(qargs), 3)
         self.assertEqual(qargs[0].index, i)
         self.assertEqual(qargs[1].index, i)
         self.assertEqual(qargs[2].index, i)
Exemplo n.º 16
0
    def setUp(self):
        qr1 = QuantumRegister(4)
        qr2 = QuantumRegister(2)
        circ = QuantumCircuit(qr1, qr2)
        circ.h(qr1[0])
        circ.cx(qr1[2], qr1[3])
        circ.h(qr1[2])
        circ.t(qr1[2])
        circ.ch(qr1[2], qr1[1])
        circ.u2(0.1, 0.2, qr1[3])
        circ.ccx(qr2[0], qr2[1], qr1[0])

        self.dag = circuit_to_dag(circ)
 def test_apply_ccx_to_empty_slice(self):
     """test applying ccx to non-register raises"""
     qr = QuantumRegister(10)
     cr = ClassicalRegister(10)
     qc = QuantumCircuit(qr, cr)
     self.assertRaises(CircuitError, qc.ccx, qr[2:0], qr[4:2], qr[7:5])
Exemplo n.º 18
0
 def setUp(self):
     self.qr1 = QuantumRegister(4, 'qr1')
     self.qr2 = QuantumRegister(2, 'qr2')
     circ1 = QuantumCircuit(self.qr2, self.qr1)
     circ1.h(self.qr1[0])
     circ1.cx(self.qr1[2], self.qr1[3])
     circ1.h(self.qr1[2])
     circ1.t(self.qr1[2])
     circ1.ch(self.qr1[2], self.qr1[1])
     circ1.u2(0.1, 0.2, self.qr1[3])
     circ1.ccx(self.qr2[0], self.qr2[1], self.qr1[0])
     self.dag1 = circuit_to_dag(circ1)
 def test_measure_slice(self):
     """test measure slice"""
     qr = QuantumRegister(10)
     cr = ClassicalRegister(10)
     cr2 = ClassicalRegister(5)
     qc = QuantumCircuit(qr, cr)
     qc.measure(qr[0:2], cr[2:4])
     for (gate, qargs, cargs), ictrl, itgt in zip(qc.data, range(0, 2), range(2, 4)):
         self.assertEqual(gate.name, 'measure')
         self.assertEqual(len(qargs), 1)
         self.assertEqual(len(cargs), 1)
         self.assertEqual(qargs[0].index, ictrl)
         self.assertEqual(cargs[0].index, itgt)
     # test single element slice
     qc = QuantumCircuit(qr, cr)
     qc.measure(qr[0:1], cr[2:3])
     for (gate, qargs, cargs), ictrl, itgt in zip(qc.data, range(0, 1), range(2, 3)):
         self.assertEqual(gate.name, 'measure')
         self.assertEqual(len(qargs), 1)
         self.assertEqual(len(cargs), 1)
         self.assertEqual(qargs[0].index, ictrl)
         self.assertEqual(cargs[0].index, itgt)
     # test tuple
     qc = QuantumCircuit(qr, cr)
     qc.measure(qr[0], cr[2])
     self.assertEqual(len(qc.data), 1)
     op, qargs, cargs = qc.data[0]
     self.assertEqual(op.name, 'measure')
     self.assertEqual(len(qargs), 1)
     self.assertEqual(len(cargs), 1)
     self.assertTrue(isinstance(qargs[0], Qubit))
     self.assertTrue(isinstance(cargs[0], Clbit))
     self.assertEqual(qargs[0].index, 0)
     self.assertEqual(cargs[0].index, 2)
     # test full register
     qc = QuantumCircuit(qr, cr)
     qc.measure(qr, cr)
     for (gate, qargs, cargs), ictrl, itgt in zip(qc.data, range(len(qr)), range(len(cr))):
         self.assertEqual(gate.name, 'measure')
         self.assertEqual(len(qargs), 1)
         self.assertEqual(len(cargs), 1)
         self.assertEqual(qargs[0].index, ictrl)
         self.assertEqual(cargs[0].index, itgt)
     # test mix slice full register
     qc = QuantumCircuit(qr, cr2)
     qc.measure(qr[::2], cr2)
     for (gate, qargs, cargs), ictrl, itgt in zip(qc.data, range(0, 10, 2), range(len(cr2))):
         self.assertEqual(gate.name, 'measure')
         self.assertEqual(len(qargs), 1)
         self.assertEqual(len(cargs), 1)
         self.assertEqual(qargs[0].index, ictrl)
         self.assertEqual(cargs[0].index, itgt)
Exemplo n.º 20
0
    def test_dag_eq(self):
        """DAG equivalence check: True."""
        circ2 = QuantumCircuit(self.qr1, self.qr2)
        circ2.cx(self.qr1[2], self.qr1[3])
        circ2.u2(0.1, 0.2, self.qr1[3])
        circ2.h(self.qr1[0])
        circ2.h(self.qr1[2])
        circ2.t(self.qr1[2])
        circ2.ch(self.qr1[2], self.qr1[1])
        circ2.ccx(self.qr2[0], self.qr2[1], self.qr1[0])
        dag2 = circuit_to_dag(circ2)

        self.assertEqual(self.dag1, dag2)
Exemplo n.º 21
0
 def __init__(self):
     """Initialize Pauli measurement basis"""
     # Z-meas rotation
     meas_z = QuantumCircuit(1, name="PauliMeasZ")
     # X-meas rotation
     meas_x = QuantumCircuit(1, name="PauliMeasX")
     meas_x.append(HGate(), [0])
     # Y-meas rotation
     meas_y = QuantumCircuit(1, name="PauliMeasY")
     meas_y.append(SdgGate(), [0])
     meas_y.append(HGate(), [0])
     super().__init__("PauliMeasurementBasis", [meas_z, meas_x, meas_y])
Exemplo n.º 22
0
    def test_dag_neq_same_topology(self):
        """DAG equivalence check: False. Same topology."""
        circ2 = QuantumCircuit(self.qr1, self.qr2)
        circ2.cx(self.qr1[2], self.qr1[3])
        circ2.u2(0.1, 0.2, self.qr1[3])
        circ2.h(self.qr1[0])
        circ2.h(self.qr1[2])
        circ2.t(self.qr1[2])
        circ2.cx(self.qr1[2], self.qr1[1])  # <--- The difference: ch(qr1[2], qr1[1])
        circ2.ccx(self.qr2[0], self.qr2[1], self.qr1[0])
        dag2 = circuit_to_dag(circ2)

        self.assertNotEqual(self.dag1, dag2)
Exemplo n.º 23
0
    def test_node_middle_of_blocks(self):
        """Test that a node surrounded by blocks stays in the same place

        This is a larger test to ensure multiple blocks can all be collected
        and added back in the correct order.

        blocks = [['cx', 'id'], ['cx', 'id'], ['id', 'cx'], ['id', 'cx']]

        q_0: |0>──■───────────────────■──
                ┌─┴─┐┌────┐   ┌────┐┌─┴─┐
        q_1: |0>┤ X ├┤ Id ├─X─┤ Id ├┤ X ├
                ├───┤├────┤ │ ├────┤├───┤
        q_2: |0>┤ X ├┤ Id ├─X─┤ Id ├┤ X ├
                └─┬─┘└────┘   └────┘└─┬─┘
        q_3: |0>──■───────────────────■──

        """
        qc = QuantumCircuit(4)
        qc.cx(0, 1)
        qc.cx(3, 2)
        qc.i(1)
        qc.i(2)

        qc.swap(1, 2)

        qc.i(1)
        qc.i(2)
        qc.cx(0, 1)
        qc.cx(3, 2)

        pass_manager = PassManager()
        pass_manager.append(Collect2qBlocks())
        pass_manager.append(ConsolidateBlocks())
        qc1 = pass_manager.run(qc)

        self.assertEqual(qc, qc1)
Exemplo n.º 24
0
 def test_dag_depth1(self):
     """Test DAG depth #1
     """
     qr1 = QuantumRegister(3, 'q1')
     qr2 = QuantumRegister(2, 'q2')
     c = ClassicalRegister(5, 'c')
     qc = QuantumCircuit(qr1, qr2, c)
     qc.h(qr1[0])
     qc.h(qr1[1])
     qc.h(qr1[2])
     qc.h(qr2[0])
     qc.h(qr2[1])
     qc.ccx(qr2[1], qr1[0], qr2[0])
     qc.cx(qr1[0], qr1[1])
     qc.cx(qr1[1], qr2[1])
     qc.cx(qr2[1], qr1[2])
     qc.cx(qr1[2], qr2[0])
     dag = circuit_to_dag(qc)
     self.assertEqual(dag.depth(), 6)
Exemplo n.º 25
0
    def test_gray_synth(self):
        """Test synthesis of a small parity network via gray_synth.

        The algorithm should take the following matrix as an input:
        S =
        [[0, 1, 1, 0, 1, 1],
         [0, 1, 1, 0, 1, 0],
         [0, 0, 0, 1, 1, 0],
         [1, 0, 0, 1, 1, 1],
         [0, 1, 0, 0, 1, 0],
         [0, 1, 0, 0, 1, 0]]

        Along with some rotation angles:
        ['s', 't', 'z', 's', 't', 't'])

        which together specify the Fourier expansion in the sum-over-paths representation
        of a quantum circuit.

        And should return the following circuit (or an equivalent one):
                          ┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐
        q_0: |0>──────────┤ X ├┤ X ├┤ T ├┤ X ├┤ X ├┤ X ├┤ X ├┤ T ├┤ X ├┤ T ├┤ X ├┤ X ├┤ Z ├┤ X ├
                          └─┬─┘└─┬─┘└───┘└─┬─┘└─┬─┘└─┬─┘└─┬─┘└───┘└─┬─┘└───┘└─┬─┘└─┬─┘└───┘└─┬─┘
        q_1: |0>────────────┼────┼─────────■────┼────┼────┼─────────┼─────────┼────┼─────────■──
                            │    │              │    │    │         │         │    │
        q_2: |0>───────■────■────┼──────────────■────┼────┼─────────┼────■────┼────┼────────────
                ┌───┐┌─┴─┐┌───┐  │                   │    │         │  ┌─┴─┐  │    │
        q_3: |0>┤ S ├┤ X ├┤ S ├──■───────────────────┼────┼─────────■──┤ X ├──┼────┼────────────
                └───┘└───┘└───┘                      │    │            └───┘  │    │
        q_4: |0>─────────────────────────────────────■────┼───────────────────■────┼────────────
                                                          │                        │
        q_5: |0>──────────────────────────────────────────■────────────────────────■────────────

        """
        cnots = [[0, 1, 1, 0, 1, 1], [0, 1, 1, 0, 1, 0], [0, 0, 0, 1, 1, 0],
                 [1, 0, 0, 1, 1, 1], [0, 1, 0, 0, 1, 0], [0, 1, 0, 0, 1, 0]]
        angles = ['s', 't', 'z', 's', 't', 't']
        c_gray = graysynth(cnots, angles)
        unitary_gray = UnitaryGate(Operator(c_gray))

        # Create the circuit displayed above:
        q = QuantumRegister(6, 'q')
        c_compare = QuantumCircuit(q)
        c_compare.s(q[3])
        c_compare.cx(q[2], q[3])
        c_compare.s(q[3])
        c_compare.cx(q[2], q[0])
        c_compare.cx(q[3], q[0])
        c_compare.t(q[0])
        c_compare.cx(q[1], q[0])
        c_compare.cx(q[2], q[0])
        c_compare.cx(q[4], q[0])
        c_compare.cx(q[5], q[0])
        c_compare.t(q[0])
        c_compare.cx(q[3], q[0])
        c_compare.t(q[0])
        c_compare.cx(q[2], q[3])
        c_compare.cx(q[4], q[0])
        c_compare.cx(q[5], q[0])
        c_compare.z(q[0])
        c_compare.cx(q[1], q[0])
        unitary_compare = UnitaryGate(Operator(c_compare))

        # Check if the two circuits are equivalent
        self.assertEqual(unitary_gray, unitary_compare)
Exemplo n.º 26
0
 def _dec_ucrot(self):
     """
     finds a decomposition of a UC rotation gate into elementary gates
     (C-NOTs and single-qubit rotations).
     """
     q = QuantumRegister(self.num_qubits)
     circuit = QuantumCircuit(q)
     q_target = q[0]
     q_controls = q[1:]
     if not q_controls:  # equivalent to: if len(q_controls) == 0
         if self.rot_axes == "X":
             if np.abs(self.params[0]) > _EPS:
                 circuit.rx(self.params[0], q_target)
         if self.rot_axes == "Y":
             if np.abs(self.params[0]) > _EPS:
                 circuit.ry(self.params[0], q_target)
         if self.rot_axes == "Z":
             if np.abs(self.params[0]) > _EPS:
                 circuit.rz(self.params[0], q_target)
     else:
         # First, we find the rotation angles of the single-qubit rotations acting
         #  on the target qubit
         angles = self.params.copy()
         UCRot._dec_uc_rotations(angles, 0, len(angles), False)
         # Now, it is easy to place the C-NOT gates to get back the full decomposition.s
         for (i, angle) in enumerate(angles):
             if self.rot_axes == "X":
                 if np.abs(angle) > _EPS:
                     circuit.rx(angle, q_target)
             if self.rot_axes == "Y":
                 if np.abs(angle) > _EPS:
                     circuit.ry(angle, q_target)
             if self.rot_axes == "Z":
                 if np.abs(angle) > _EPS:
                     circuit.rz(angle, q_target)
             # Determine the index of the qubit we want to control the C-NOT gate.
             # Note that it corresponds
             # to the number of trailing zeros in the binary representaiton of i+1
             if not i == len(angles) - 1:
                 binary_rep = np.binary_repr(i + 1)
                 q_contr_index = len(binary_rep) - len(
                     binary_rep.rstrip('0'))
             else:
                 # Handle special case:
                 q_contr_index = len(q_controls) - 1
             # For X rotations, we have to additionally place some Ry gates around the
             # C-NOT gates. They change the basis of the NOT operation, such that the
             # decomposition of for uniformly controlled X rotations works correctly by symmetry
             # with the decomposition of uniformly controlled Z or Y rotations
             if self.rot_axes == "X":
                 circuit.ry(np.pi / 2, q_target)
             circuit.cx(q_controls[q_contr_index], q_target)
             if self.rot_axes == "X":
                 circuit.ry(-np.pi / 2, q_target)
     return circuit
Exemplo n.º 27
0
def rzx_xz(theta: float = None):
    """Template for CX - RXGate - CX."""
    if theta is None:
        theta = Parameter('ϴ')

    qc = QuantumCircuit(2)
    qc.cx(1, 0)
    qc.rx(theta, 1)
    qc.cx(1, 0)

    qc.rz(np.pi / 2, 0)
    qc.rx(np.pi / 2, 0)
    qc.rz(np.pi / 2, 0)
    qc.rzx(-1 * theta, 0, 1)
    qc.rz(np.pi / 2, 0)
    qc.rx(np.pi / 2, 0)
    qc.rz(np.pi / 2, 0)
    return qc
Exemplo n.º 28
0
    def _multiplex(self, target_gate, list_of_angles, last_cnot=True):
        """
        Return a recursive implementation of a multiplexor circuit,
        where each instruction itself has a decomposition based on
        smaller multiplexors.

        The LSB is the multiplexor "data" and the other bits are multiplexor "select".

        Args:
            target_gate (Gate): Ry or Rz gate to apply to target qubit, multiplexed
                over all other "select" qubits
            list_of_angles (list[float]): list of rotation angles to apply Ry and Rz
            last_cnot (bool): add the last cnot if last_cnot = True

        Returns:
            DAGCircuit: the circuit implementing the multiplexor's action
        """
        list_len = len(list_of_angles)
        local_num_qubits = int(math.log2(list_len)) + 1

        q = QuantumRegister(local_num_qubits)
        circuit = QuantumCircuit(q, name="multiplex" + local_num_qubits.__str__())

        lsb = q[0]
        msb = q[local_num_qubits - 1]

        # case of no multiplexing: base case for recursion
        if local_num_qubits == 1:
            circuit.append(target_gate(list_of_angles[0]), [q[0]])
            return circuit

        # calc angle weights, assuming recursion (that is the lower-level
        # requested angles have been correctly implemented by recursion
        angle_weight = np.kron([[0.5, 0.5], [0.5, -0.5]],
                               np.identity(2 ** (local_num_qubits - 2)))

        # calc the combo angles
        list_of_angles = angle_weight.dot(np.array(list_of_angles)).tolist()

        # recursive step on half the angles fulfilling the above assumption
        multiplex_1 = self._multiplex(target_gate, list_of_angles[0:(list_len // 2)], False)
        circuit.append(multiplex_1.to_instruction(), q[0:-1])

        # attach CNOT as follows, thereby flipping the LSB qubit
        circuit.append(CXGate(), [msb, lsb])

        # implement extra efficiency from the paper of cancelling adjacent
        # CNOTs (by leaving out last CNOT and reversing (NOT inverting) the
        # second lower-level multiplex)
        multiplex_2 = self._multiplex(target_gate, list_of_angles[(list_len // 2):], False)
        if list_len > 1:
            circuit.append(multiplex_2.to_instruction().reverse_ops(), q[0:-1])
        else:
            circuit.append(multiplex_2.to_instruction(), q[0:-1])

        # attach a final CNOT
        if last_cnot:
            circuit.append(CXGate(), [msb, lsb])

        return circuit
Exemplo n.º 29
0
    def test_multiple_conditionals_multiple_registers(self):
        """Verify disassemble handles multiple conditionals and registers."""
        qr = QuantumRegister(3)
        cr1 = ClassicalRegister(3)
        cr2 = ClassicalRegister(5)
        cr3 = ClassicalRegister(6)
        cr4 = ClassicalRegister(1)

        qc = QuantumCircuit(qr, cr1, cr2, cr3, cr4)
        qc.x(qr[1])
        qc.h(qr)
        qc.cx(qr[1], qr[0]).c_if(cr3, 14)
        qc.ccx(qr[0], qr[2], qr[1]).c_if(cr4, 1)
        qc.h(qr).c_if(cr1, 3)
        qobj = assemble(qc)
        circuits, run_config_out, header = disassemble(qobj)
        run_config_out = RunConfig(**run_config_out)
        self.assertEqual(run_config_out.n_qubits, 3)
        self.assertEqual(run_config_out.memory_slots, 15)
        self.assertEqual(len(circuits), 1)
        self.assertEqual(circuits[0], qc)
        self.assertEqual({}, header)
Exemplo n.º 30
0
    def test_setting_data_is_validated(self):
        """Verify setting circuit.data is broadcast and validated."""
        qr = QuantumRegister(2)
        qc = QuantumCircuit(qr)

        qc.data = [(HGate(), [qr[0]], []), (CnotGate(), [0, 1], []),
                   (HGate(), [(qr, 1)], [])]

        expected_qc = QuantumCircuit(qr)

        expected_qc.h(0)
        expected_qc.cx(0, 1)
        expected_qc.h(1)

        self.assertEqual(qc, expected_qc)

        with self.assertRaises(CircuitError):
            qc.data = [(HGate(), [qr[0], qr[1]], [])]
        with self.assertRaises(CircuitError):
            qc.data = [(HGate(), [], [qr[0]])]