コード例 #1
0
    def test_random_pauli(self):
        """Test the Random Pauli circuit."""
        circuit = PauliTwoDesign(4, seed=12, reps=1)

        qr = QuantumRegister(4, "q")
        params = circuit.ordered_parameters

        # expected circuit for the random seed 12
        expected = QuantumCircuit(qr)

        # initial RYs
        expected.ry(np.pi / 4, qr)

        # first random Pauli layer
        expected.ry(params[0], 0)
        expected.rx(params[1], 1)
        expected.rz(params[2], 2)
        expected.rz(params[3], 3)

        # entanglement
        expected.cz(0, 1)
        expected.cz(2, 3)
        expected.cz(1, 2)

        # second random Pauli layer
        expected.rx(params[4], 0)
        expected.rx(params[5], 1)
        expected.rx(params[6], 2)
        expected.rx(params[7], 3)

        self.assertEqual(circuit.decompose(), expected)
コード例 #2
0
    def test_assign_keeps_one_initial_layer(self):
        """Test assigning parameters does not add an additional initial layer."""
        circuit = PauliTwoDesign(2)
        values = list(range(circuit.num_parameters))

        bound0 = circuit.assign_parameters(values)
        bound1 = circuit.assign_parameters(values)
        bound2 = circuit.assign_parameters(values)

        self.assertEqual(bound0, bound1)
        self.assertEqual(bound0, bound2)
コード例 #3
0
    def test_resize(self):
        """Test resizing the Random Pauli circuit preserves the gates."""
        circuit = PauliTwoDesign(1)
        top_gates = [op.name for op, _, _ in circuit.data]

        circuit.num_qubits = 3
        with self.subTest('assert existing gates remain'):
            new_top_gates = []
            for op, qargs, _ in circuit:
                if qargs == [circuit.qubits[0]]:  # if top qubit
                    new_top_gates.append(op.name)

            self.assertEqual(top_gates, new_top_gates)
コード例 #4
0
    def test_pauli_two_design(self):
        """Test standard gradient descent on the Pauli two-design example."""
        circuit = PauliTwoDesign(3, reps=3, seed=2)
        parameters = list(circuit.parameters)
        obs = Z ^ Z ^ I
        expr = ~StateFn(obs) @ StateFn(circuit)

        initial_point = np.array([
            0.1822308,
            -0.27254251,
            0.83684425,
            0.86153976,
            -0.7111668,
            0.82766631,
            0.97867993,
            0.46136964,
            2.27079901,
            0.13382699,
            0.29589915,
            0.64883193,
        ])

        def objective(x):
            return expr.bind_parameters(dict(zip(parameters, x))).eval().real

        optimizer = GradientDescent(maxiter=100,
                                    learning_rate=0.1,
                                    perturbation=0.1)

        result = optimizer.optimize(circuit.num_parameters,
                                    objective,
                                    initial_point=initial_point)

        self.assertLess(result[1], -0.95)  # final loss
        self.assertEqual(result[2], 100)  # function evaluations
コード例 #5
0
    def test_resize(self):
        """Test resizing the Random Pauli circuit preserves the gates."""
        circuit = PauliTwoDesign(1)
        top_gates = [
            instruction.operation.name
            for instruction in circuit.decompose().data
        ]

        circuit.num_qubits = 3
        decomposed = circuit.decompose()
        with self.subTest("assert existing gates remain"):
            new_top_gates = []
            for instruction in decomposed:
                if instruction.qubits == (
                        decomposed.qubits[0], ):  # if top qubit
                    new_top_gates.append(instruction.operation.name)

            self.assertEqual(top_gates, new_top_gates)
コード例 #6
0
    def test_random_pauli(self):
        """Test the Random Pauli circuit."""
        circuit = PauliTwoDesign(4, seed=12, reps=1)

        qr = QuantumRegister(4, "q")
        params = circuit.ordered_parameters

        # expected circuit for the random seed 12
        #
        #      ┌─────────┐┌──────────┐   ┌──────────┐
        # q_0: ┤ Ry(π/4) ├┤ Ry(θ[0]) ├─■─┤ Rx(θ[4]) ├────────────
        #      ├─────────┤├──────────┤ │ └──────────┘┌──────────┐
        # q_1: ┤ Ry(π/4) ├┤ Rx(θ[1]) ├─■──────■──────┤ Rx(θ[5]) ├
        #      ├─────────┤├──────────┤        │      ├──────────┤
        # q_2: ┤ Ry(π/4) ├┤ Rz(θ[2]) ├─■──────■──────┤ Rx(θ[6]) ├
        #      ├─────────┤├──────────┤ │ ┌──────────┐└──────────┘
        # q_3: ┤ Ry(π/4) ├┤ Rz(θ[3]) ├─■─┤ Rx(θ[7]) ├────────────
        #      └─────────┘└──────────┘   └──────────┘
        expected = QuantumCircuit(qr)

        # initial RYs
        expected.ry(np.pi / 4, qr)

        # first random Pauli layer
        expected.ry(params[0], 0)
        expected.rx(params[1], 1)
        expected.rz(params[2], 2)
        expected.rz(params[3], 3)

        # entanglement
        expected.cz(0, 1)
        expected.cz(2, 3)
        expected.cz(1, 2)

        # second random Pauli layer
        expected.rx(params[4], 0)
        expected.rx(params[5], 1)
        expected.rx(params[6], 2)
        expected.rx(params[7], 3)

        self.assertEqual(circuit.decompose(), expected)
コード例 #7
0
    def test_pauli_two_design(self, method):
        """Test SPSA on the Pauli two-design example."""
        circuit = PauliTwoDesign(3, reps=1, seed=1)
        parameters = list(circuit.parameters)
        obs = Z ^ Z ^ I
        expr = ~StateFn(obs) @ StateFn(circuit)

        initial_point = np.array([
            0.82311034, 0.02611798, 0.21077064, 0.61842177, 0.09828447,
            0.62013131
        ])

        def objective(x):
            return expr.bind_parameters(dict(zip(parameters, x))).eval().real

        settings = {"maxiter": 100, "blocking": True, "allowed_increase": 0}

        if method == "2spsa":
            settings["second_order"] = True
            settings["regularization"] = 0.01
            expected_nfev = settings["maxiter"] * 5 + 1
        elif method == "qnspsa":
            settings["fidelity"] = QNSPSA.get_fidelity(circuit)
            settings["regularization"] = 0.001
            settings["learning_rate"] = 0.05
            settings["perturbation"] = 0.05

            expected_nfev = settings["maxiter"] * 7 + 1
        else:
            expected_nfev = settings["maxiter"] * 3 + 1

        if method == "qnspsa":
            spsa = QNSPSA(**settings)
        else:
            spsa = SPSA(**settings)

        with self.assertWarns(DeprecationWarning):
            result = spsa.optimize(circuit.num_parameters,
                                   objective,
                                   initial_point=initial_point)

        with self.subTest("check final accuracy"):
            self.assertLess(result[1], -0.95)  # final loss

        with self.subTest("check number of function calls"):
            self.assertEqual(result[2], expected_nfev)  # function evaluations