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
Example #2
0
    def test_expressions_division_by_zero(self):
        """Verify divding a Parameter by 0, or binding 0 as a denominator raises."""

        x = Parameter('x')

        with self.assertRaises(ZeroDivisionError):
            _ = x / 0

        with self.assertRaises(ZeroDivisionError):
            _ = x / 0.0

        expr = 2 / x

        with self.assertRaises(ZeroDivisionError):
            _ = expr.bind({x: 0})

        with self.assertRaises(ZeroDivisionError):
            _ = expr.bind({x: 0.0})
    def __init__(
        self,
        basis_gates: Optional[List[str]] = None,
        default_values: Optional[Dict] = None,
        use_drag: bool = True,
        link_parameters: bool = True,
    ):
        """Setup the schedules.

        Args:
            basis_gates: The basis gates to generate.
            default_values: Default values for the parameters this dictionary can contain
                the following keys: "duration", "amp", "β", and "σ". If "σ" is not provided
                this library will take one fourth of the pulse duration as default value.
            use_drag: If set to False then Gaussian pulses will be used instead of DRAG
                pulses.
            link_parameters: if set to True then the amplitude and DRAG parameters of the
                X and Y gates will be linked as well as those of the SX and SY gates.
        """
        super().__init__(basis_gates, default_values)
        self._link_parameters = link_parameters

        dur = Parameter("duration")
        sigma = Parameter("σ")

        # Generate the pulse parameters
        def _beta(use_drag):
            return Parameter("β") if use_drag else None

        x_amp, x_beta = Parameter("amp"), _beta(use_drag)

        if self._link_parameters:
            y_amp, y_beta = 1.0j * x_amp, x_beta
        else:
            y_amp, y_beta = Parameter("amp"), _beta(use_drag)

        sx_amp, sx_beta = Parameter("amp"), _beta(use_drag)

        if self._link_parameters:
            sy_amp, sy_beta = 1.0j * sx_amp, sx_beta
        else:
            sy_amp, sy_beta = Parameter("amp"), _beta(use_drag)

        # Create the schedules for the gates
        sched_x = self._single_qubit_schedule("x", dur, x_amp, sigma, x_beta)
        sched_y = self._single_qubit_schedule("y", dur, y_amp, sigma, y_beta)
        sched_sx = self._single_qubit_schedule("sx", dur, sx_amp, sigma, sx_beta)
        sched_sy = self._single_qubit_schedule("sy", dur, sy_amp, sigma, sy_beta)

        for sched in [sched_x, sched_y, sched_sx, sched_sy]:
            if sched.name in self._basis_gates:
                self._schedules[sched.name] = sched
    def test_appending_for_loop_op(self):
        """Verify we can append a ForLoopOp to a QuantumCircuit."""
        body = QuantumCircuit(3, 1)
        loop_parameter = Parameter("foo")
        indexset = range(0, 10, 2)

        body.rx(loop_parameter, [0, 1, 2])

        op = ForLoopOp(indexset, loop_parameter, body)

        qc = QuantumCircuit(5, 2)
        qc.append(op, [1, 2, 3], [1])

        self.assertEqual(qc.data[0].operation.name, "for_loop")
        self.assertEqual(qc.data[0].operation.params,
                         [indexset, loop_parameter, body])
        self.assertEqual(qc.data[0].qubits, tuple(qc.qubits[1:4]))
        self.assertEqual(qc.data[0].clbits, (qc.clbits[1], ))
Example #5
0
 def test_qobj_with_hamiltonian(self):
     """test qobj output with hamiltonian"""
     qr = QuantumRegister(4)
     qc = QuantumCircuit(qr)
     qc.rx(np.pi / 4, qr[0])
     matrix = Operator.from_label('XIZ')
     theta = Parameter('theta')
     uni = HamiltonianGate(matrix, theta, label='XIZ')
     qc.append(uni, [qr[0], qr[1], qr[3]])
     qc.cx(qr[3], qr[2])
     qc = qc.bind_parameters({theta: np.pi / 2})
     qobj = qiskit.compiler.assemble(qc)
     instr = qobj.experiments[0].instructions[1]
     self.assertEqual(instr.name, 'hamiltonian')
     # Also test label
     self.assertEqual(instr.label, 'XIZ')
     np.testing.assert_array_almost_equal(
         np.array(instr.params[0]).astype(np.complex64), matrix.data)
Example #6
0
def get_ghz_mqc_para(n, extent='full'):
    '''
    This function creates an MQC circuit with n qubits,
    where the middle phase rotation around the z axis is by delta
    '''
    q = QuantumRegister(n, 'q')
    circ = get_ghz_simple(n, obs=False)
    delta = Parameter('t')
    circinv = circ.inverse()
    circ.barrier()
    circ.u1(delta, q)
    circ.x(q)
    circ.barrier()
    circ += circinv
    meas = get_ghz_measurement(n, extent)
    circ = circ + meas
    circ.draw()
    return circ, delta
Example #7
0
 def test_run_path_with_expressions_multiple_params_per_instruction(self):
     """Test parameterized circuit path via backed.run()"""
     shots = 1000
     backend = AerSimulator()
     circuit = QuantumCircuit(2)
     theta = Parameter('theta')
     theta_squared = theta * theta
     circuit.rx(theta, 0)
     circuit.cx(0, 1)
     circuit.rz(theta_squared, 1)
     circuit.u(theta, theta_squared, theta, 1)
     circuit.measure_all()
     parameter_binds = [{theta: [0, pi, 2 * pi]}]
     res = backend.run(circuit,
                       shots=shots,
                       parameter_binds=parameter_binds).result()
     counts = res.get_counts()
     self.assertEqual(counts, [{'00': shots}, {'01': shots}, {'00': shots}])
    def test_parameterized_calibrations_transpile(self):
        """Check that gates can be matched to their calibrations before and after parameter
        assignment."""
        tau = Parameter('tau')
        circ = QuantumCircuit(3, 3)
        circ.append(Gate('rxt', 1, [2*3.14*tau]), [0])

        def q0_rxt(tau):
            with pulse.build() as q0_rxt:
                pulse.play(pulse.library.Gaussian(20, 0.4*tau, 3.0), pulse.DriveChannel(0))
            return q0_rxt
        circ.add_calibration('rxt', [0], q0_rxt(tau), [2*3.14*tau])

        transpiled_circ = transpile(circ, FakeAlmaden())
        self.assertEqual(set(transpiled_circ.count_ops().keys()), {'rxt'})
        circ = circ.assign_parameters({tau: 1})
        transpiled_circ = transpile(circ, FakeAlmaden())
        self.assertEqual(set(transpiled_circ.count_ops().keys()), {'rxt'})
Example #9
0
    def test_quantum_circuit_with_bound_parameters(self, recorder):
        """Tests loading a quantum circuit that already had bound parameters."""

        theta = Parameter('θ')

        qc = QuantumCircuit(3, 1)
        qc.rz(theta, [0])
        qc_1 = qc.bind_parameters({theta: 0.5})

        quantum_circuit = load(qc_1)

        with recorder:
            quantum_circuit()

        assert len(recorder.queue) == 1
        assert recorder.queue[0].name == 'RZ'
        assert recorder.queue[0].params == [0.5]
        assert recorder.queue[0].wires == [0]
Example #10
0
    def test_parameter_expression_circuit_for_device(self):
        """Verify that a circuit including expressions of parameters can be
        transpiled for a device backend."""
        qr = QuantumRegister(2, name='qr')
        qc = QuantumCircuit(qr)

        theta = Parameter('theta')
        square = theta * theta
        qc.rz(square, qr[0])

        transpiled_qc = transpile(qc, backend=FakeMelbourne(),
                                  initial_layout=Layout.generate_trivial_layout(qr))

        qr = QuantumRegister(14, 'q')
        expected_qc = QuantumCircuit(qr)
        expected_qc.u1(square, qr[0])

        self.assertEqual(expected_qc, transpiled_qc)
    def test_single_parameter_binds(self):
        """Test passing parameter binds as a dictionary to the circuit sampler."""
        try:
            from qiskit.providers.aer import Aer
        except Exception as ex:  # pylint: disable=broad-except
            self.skipTest(f"Aer doesn't appear to be installed. Error: '{str(ex)}'")
            return

        x = Parameter("x")
        circuit = QuantumCircuit(1)
        circuit.ry(x, 0)
        expr = ~StateFn(H) @ StateFn(circuit)

        sampler = CircuitSampler(Aer.get_backend("aer_simulator_statevector"))

        res = sampler.convert(expr, params={x: 0}).eval()

        self.assertIsInstance(res, complex)
    def test_for_loop_iterable_instantiation(self):
        """Verify creation and properties of a ForLoopOp using an iterable indexset."""
        body = QuantumCircuit(3, 1)
        loop_parameter = Parameter("foo")
        indexset = iter(range(0, 10, 2))

        body.rx(loop_parameter, 0)

        op = ForLoopOp(indexset, loop_parameter, body)

        self.assertIsInstance(op, ControlFlowOp)
        self.assertIsInstance(op, Instruction)
        self.assertEqual(op.name, "for_loop")
        self.assertEqual(op.num_qubits, 3)
        self.assertEqual(op.num_clbits, 1)
        self.assertEqual(op.params,
                         [tuple(range(0, 10, 2)), loop_parameter, body])
        self.assertEqual(op.blocks, (body, ))
Example #13
0
    def test_circuit_generation(self):
        """Test creating a series of circuits parametrically"""
        theta = Parameter('θ')
        qr = QuantumRegister(1)
        qc = QuantumCircuit(qr)
        qc.rx(theta, qr)
        backend = BasicAer.get_backend('qasm_simulator')
        qc_aer = transpile(qc, backend)

        # generate list of circuits
        circs = []
        theta_list = numpy.linspace(0, numpy.pi, 20)
        for theta_i in theta_list:
            circs.append(qc_aer.bind_parameters({theta: theta_i}))
        qobj = assemble(circs)
        for index, theta_i in enumerate(theta_list):
            self.assertEqual(float(qobj.experiments[index].instructions[0].params[0]),
                             theta_i)
Example #14
0
    def test_parameterized_circuit_for_device(self):
        """Verify that a parameterized circuit can be transpiled for a device backend."""
        qr = QuantumRegister(2, name='qr')
        qc = QuantumCircuit(qr)

        theta = Parameter('theta')
        qc.rz(theta, qr[0])

        transpiled_qc = transpile(
            qc,
            backend=FakeMelbourne(),
            initial_layout=Layout.generate_trivial_layout(qr))

        qr = QuantumRegister(14, 'q')
        expected_qc = QuantumCircuit(qr)
        expected_qc.append(U1Gate(theta), [qr[0]])

        self.assertEqual(expected_qc, transpiled_qc)
    def _build(self):
        if self._data is not None:
            return

        self._check_configuration()
        self._data = []

        # get the evolved operators as circuits
        coeff = Parameter('c')
        evolved_ops = [
            self.evolution.convert((coeff * op).exp_i())
            for op in self.operators
        ]
        circuits = [
            evolved_op.reduce().to_circuit() for evolved_op in evolved_ops
        ]

        # set the registers
        num_qubits = circuits[0].num_qubits
        try:
            qr = QuantumRegister(num_qubits, 'q')
            self.add_register(qr)
        except CircuitError:
            # the register already exists, probably because of a previous composition
            pass

        # build the circuit
        times = ParameterVector('t', self.reps * len(self.operators))
        times_it = iter(times)

        first = True
        for _ in range(self.reps):
            for circuit in circuits:
                if first:
                    first = False
                else:
                    if self._insert_barriers:
                        self.barrier()
                self.compose(circuit.assign_parameters({coeff:
                                                        next(times_it)}),
                             inplace=True)

        if self._initial_state:
            self.compose(self._initial_state, front=True, inplace=True)
    def _single_qubit_schedule(
        name: str,
        dur: Parameter,
        amp: Parameter,
        sigma: Parameter,
        beta: Optional[Parameter] = None,
    ) -> ScheduleBlock:
        """Build a single qubit pulse."""

        chan = pulse.DriveChannel(Parameter("ch0"))

        if beta is not None:
            with pulse.build(name=name) as sched:
                pulse.play(pulse.Drag(duration=dur, amp=amp, sigma=sigma, beta=beta), chan)
        else:
            with pulse.build(name=name) as sched:
                pulse.play(pulse.Gaussian(duration=dur, amp=amp, sigma=sigma), chan)

        return sched
Example #17
0
    def test_single_parameterized_circuit(self):
        """Parameters should be treated as opaque gates."""
        qr = QuantumRegister(1)
        qc = QuantumCircuit(qr)
        theta = Parameter("theta")

        qc.append(U1Gate(0.3), [qr])
        qc.append(U1Gate(0.4), [qr])
        qc.append(U1Gate(theta), [qr])
        qc.append(U1Gate(0.1), [qr])
        qc.append(U1Gate(0.2), [qr])
        dag = circuit_to_dag(qc)

        expected = QuantumCircuit(qr)
        expected.append(U1Gate(theta + 1.0), [qr])

        after = Optimize1qGates().run(dag)

        self.assertEqual(circuit_to_dag(expected), after)
    def test_matrix_op_parameterized_evolution(self):
        """ parameterized MatrixOp evolution test """
        theta = Parameter('θ')
        op = (-1.052373245772859 * I ^ I) + \
             (0.39793742484318045 * I ^ Z) + \
             (0.18093119978423156 * X ^ X) + \
             (-0.39793742484318045 * Z ^ I) + \
             (-0.01128010425623538 * Z ^ Z)
        op = op * theta
        wf = (op.to_matrix_op().exp_i()) @ CX @ (H ^ I) @ Zero
        self.assertIn(theta, wf.to_circuit().parameters)

        op = op.assign_parameters({theta: 1})
        exp_mat = op.to_matrix_op().exp_i().to_matrix()
        ref_mat = scipy.linalg.expm(-1j * op.to_matrix())
        np.testing.assert_array_almost_equal(ref_mat, exp_mat)

        wf = wf.assign_parameters({theta: 3})
        self.assertNotIn(theta, wf.to_circuit().parameters)
    def test_repeated_gates_to_dag_and_back(self):
        """Verify circuits with repeated parameterized gates can be converted
        to DAG and back, maintaining consistency of circuit._parameter_table."""

        from qiskit.converters import circuit_to_dag, dag_to_circuit

        qr = QuantumRegister(1)
        qc = QuantumCircuit(qr)
        theta = Parameter('theta')

        qc.u1(theta, qr[0])

        double_qc = qc + qc
        test_qc = dag_to_circuit(circuit_to_dag(double_qc))

        for assign_fun in ['bind_parameters', 'assign_parameters']:
            with self.subTest(assign_fun=assign_fun):
                bound_test_qc = getattr(test_qc, assign_fun)({theta: 1})
                self.assertEqual(len(bound_test_qc.parameters), 0)
Example #20
0
    def test_gradient_rzx(self, method):
        """Test the state gradient for ZX rotation
        """
        ham = Z ^ Z
        a = Parameter('a')

        q = QuantumRegister(2)
        qc = QuantumCircuit(q)
        qc.h(q)
        qc.rzx(a, q[0], q[1])

        op = ~StateFn(ham) @ CircuitStateFn(primitive=qc, coeff=1.)
        params = [a]
        state_grad = Gradient(grad_method=method).convert(operator=op, params=params)
        values_dict = [{a: np.pi / 8}, {a: np.pi / 2}]
        correct_values = [[0.], [0.]]
        for i, value_dict in enumerate(values_dict):
            np.testing.assert_array_almost_equal(state_grad.assign_parameters(value_dict).eval(),
                                                 correct_values[i], decimal=1)
Example #21
0
    def test_quantum_circuit_by_passing_parameters(self, recorder):
        """Tests the load method for a QuantumCircuit initialized by passing the number
        of registers required."""

        theta = Parameter("θ")
        angle = 0.5

        qc = QuantumCircuit(3, 1)
        qc.rz(theta, [0])

        quantum_circuit = load(qc)

        with recorder:
            quantum_circuit(params={theta: angle})

        assert len(recorder.queue) == 1
        assert recorder.queue[0].name == "RZ"
        assert recorder.queue[0].parameters == [angle]
        assert recorder.queue[0].wires == Wires([0])
    def test_simple_unroll_parameterized_without_expressions(self):
        """Verify unrolling parameterized gates without expressions."""
        qr = QuantumRegister(1)
        qc = QuantumCircuit(qr)

        theta = Parameter('theta')

        qc.rz(theta, qr[0])
        dag = circuit_to_dag(qc)

        pass_ = UnrollCustomDefinitions(std_eqlib, ['u1', 'cx'])
        dag = pass_.run(dag)

        unrolled_dag = BasisTranslator(std_eqlib, ['u1', 'cx']).run(dag)

        expected = QuantumCircuit(qr, global_phase=-theta / 2)
        expected.append(U1Gate(theta), [qr[0]])

        self.assertEqual(circuit_to_dag(expected), unrolled_dag)
    def test_single_parameterized_circuit(self, basis):
        """Parameters should be treated as opaque gates."""
        qr = QuantumRegister(1)
        qc = QuantumCircuit(qr)
        theta = Parameter("theta")

        qc.p(0.3, qr)
        qc.p(0.4, qr)
        qc.p(theta, qr)
        qc.p(0.1, qr)
        qc.p(0.2, qr)

        passmanager = PassManager()
        passmanager.append(BasisTranslator(sel, basis))
        passmanager.append(Optimize1qGatesDecomposition(basis))
        result = passmanager.run(qc)

        self.assertTrue(
            Operator(qc.bind_parameters({theta: 3.14})).equiv(
                Operator(result.bind_parameters({theta: 3.14}))))
    def test_qfi_overlap_works_with_bound_parameters(self):
        """Test all QFI methods work if the circuit contains a gate with bound parameters."""

        x = Parameter("x")
        circuit = QuantumCircuit(1)
        circuit.ry(np.pi / 4, 0)
        circuit.rx(x, 0)
        state = StateFn(circuit)

        methods = ["lin_comb_full", "overlap_diag", "overlap_block_diag"]
        reference = 0.5

        for method in methods:
            with self.subTest(method):
                qfi = QFI(method)
                value = np.real(
                    qfi.convert(state, [x]).bind_parameters({
                        x: 0.12
                    }).eval())
                self.assertAlmostEqual(value[0][0], reference)
    def test_assign_parameter_to_subroutine(self):
        """Test that assign parameter objects to subroutines."""
        param1 = Parameter('amp')
        waveform = pulse.library.Constant(duration=100, amp=param1)

        program_layer0 = pulse.Schedule()
        program_layer0 += pulse.Play(waveform, DriveChannel(0))
        reference = deepcopy(program_layer0).assign_parameters({param1: 0.1})

        # to call instruction
        program_layer1 = pulse.Schedule()
        program_layer1 += pulse.instructions.Call(program_layer0)
        target = deepcopy(program_layer1).assign_parameters({param1: 0.1})
        self.assertEqual(inline_subroutines(target), reference)

        # to nested call instruction
        program_layer2 = pulse.Schedule()
        program_layer2 += pulse.instructions.Call(program_layer1)
        target = deepcopy(program_layer2).assign_parameters({param1: 0.1})
        self.assertEqual(inline_subroutines(target), reference)
    def test_schedule_block_in_instmap(self):
        """Test schedule block in instmap can be scheduled."""
        duration = Parameter("duration")

        with build() as pulse_prog:
            play(Gaussian(duration, 0.1, 10), DriveChannel(0))

        instmap = InstructionScheduleMap()
        instmap.add("block_gate", (0, ), pulse_prog, ["duration"])

        qc = QuantumCircuit(1)
        qc.append(Gate("block_gate", 1, [duration]), [0])
        qc.assign_parameters({duration: 100}, inplace=True)

        sched = schedule(qc, self.backend, inst_map=instmap)

        ref_sched = Schedule()
        ref_sched += Play(Gaussian(100, 0.1, 10), DriveChannel(0))

        self.assertEqual(sched, ref_sched)
Example #27
0
    def test_gradient_rzz(self, method):
        # pylint: disable=wrong-spelling-in-comment
        """Test the state gradient for ZZ rotation
        """
        ham = Z ^ X
        a = Parameter('a')

        q = QuantumRegister(2)
        qc = QuantumCircuit(q)
        qc.h(q[0])
        qc.rzz(a, q[0], q[1])

        op = ~StateFn(ham) @ CircuitStateFn(primitive=qc, coeff=1.)
        params = [a]
        state_grad = Gradient(grad_method=method).convert(operator=op, params=params)
        values_dict = [{a: np.pi / 4}, {a: np.pi / 2}]
        correct_values = [[-0.707], [-1.]]
        for i, value_dict in enumerate(values_dict):
            np.testing.assert_array_almost_equal(state_grad.assign_parameters(value_dict).eval(),
                                                 correct_values[i], decimal=1)
Example #28
0
    def test_1q_hamiltonian(self):
        """test 1 qubit hamiltonian"""
        qr = QuantumRegister(1, 'q0')
        cr = ClassicalRegister(1, 'c0')
        qc = QuantumCircuit(qr, cr)
        matrix = np.zeros((2, 2))
        qc.x(qr[0])
        theta = Parameter('theta')
        qc.append(HamiltonianGate(matrix, theta), [qr[0]])
        qc = qc.bind_parameters({theta: 1})

        # test of text drawer
        self.log.info(qc)
        dag = circuit_to_dag(qc)
        dag_nodes = dag.named_nodes('hamiltonian')
        self.assertTrue(len(dag_nodes) == 1)
        dnode = dag_nodes[0]
        self.assertIsInstance(dnode.op, HamiltonianGate)
        self.assertListEqual(dnode.qargs, qc.qubits)
        assert_allclose(dnode.op.to_matrix(), np.eye(2))
Example #29
0
    def test_qaoa_qc_mixer_many_parameters(self):
        """QAOA test with a mixer as a parameterized circuit with the num of parameters > 1."""
        optimizer = COBYLA()
        qubit_op, _ = self._get_operator(W1)

        num_qubits = qubit_op.num_qubits
        mixer = QuantumCircuit(num_qubits)
        for i in range(num_qubits):
            theta = Parameter("θ" + str(i))
            mixer.rx(theta, range(num_qubits))

        qaoa = QAOA(optimizer,
                    reps=2,
                    mixer=mixer,
                    quantum_instance=self.statevector_simulator)
        result = qaoa.compute_minimum_eigenvalue(operator=qubit_op)
        x = self._sample_most_likely(result.eigenstate)
        self.log.debug(x)
        graph_solution = self._get_graph_solution(x)
        self.assertIn(graph_solution, S1)
 def test_3q_hamiltonian(self):
     """test 3 qubit hamiltonian on non-consecutive bits"""
     qr = QuantumRegister(4)
     qc = QuantumCircuit(qr)
     qc.x(qr[0])
     matrix = Operator.from_label("XZY")
     theta = Parameter("theta")
     uni3q = HamiltonianGate(matrix, theta)
     qc.append(uni3q, [qr[0], qr[1], qr[3]])
     qc.cx(qr[3], qr[2])
     # test of text drawer
     self.log.info(qc)
     qc = qc.bind_parameters({theta: -np.pi / 2})
     dag = circuit_to_dag(qc)
     nodes = dag.multi_qubit_ops()
     self.assertEqual(len(nodes), 1)
     dnode = nodes[0]
     self.assertIsInstance(dnode.op, HamiltonianGate)
     self.assertEqual(dnode.qargs, [qr[0], qr[1], qr[3]])
     np.testing.assert_almost_equal(dnode.op.to_matrix(), 1j * matrix.data)