def test_unsupported_operations(self):
        """Assert unsupported operations raise an error."""
        cvar = CVaRMeasurement(Z)

        attrs = [
            'to_matrix', 'to_matrix_op', 'to_density_matrix', 'to_circuit_op',
            'sample'
        ]
        for attr in attrs:
            with self.subTest(attr):
                with self.assertRaises(NotImplementedError):
                    _ = getattr(cvar, attr)()

        with self.subTest('adjoint'):
            with self.assertRaises(OpflowError):
                cvar.adjoint()
    def test_cvar_simple_with_coeff(self):
        """Test a simple case with a non-unity coefficient"""
        theta = 2.2
        qc = QuantumCircuit(1)
        qc.ry(theta, 0)
        statefn = StateFn(qc)

        alpha = 0.2
        cvar = ((-1 * CVaRMeasurement(Z, alpha)) @ statefn).eval()
        ref = self.expected_cvar(statefn.to_matrix(), Z, alpha)
        self.assertAlmostEqual(cvar, -1 * ref)
예제 #3
0
    def test_cvar_on_paulisumop(self):
        """Test a large PauliSumOp is checked for diagonality efficiently.

        Regression test for Qiskit/qiskit-terra#7573.
        """
        op = PauliSumOp.from_list([("Z" * 30, 1)])
        # assert global algorithm settings do not have massive calculations turned on
        # -- which is the default, but better to be sure in the test!
        # also add a cleanup so we're sure to reset to the original value after the test, even if
        # the test would fail
        self.addCleanup(self.cleanup_algorithm_globals,
                        algorithm_globals.massive)
        algorithm_globals.massive = False

        cvar = CVaRMeasurement(op, alpha=0.1)
        fake_probabilities = [0.2, 0.8]
        fake_energies = [1, 2]

        expectation = cvar.compute_cvar(fake_energies, fake_probabilities)
        self.assertEqual(expectation, 1)
    def test_cvar_simple(self):
        """Test a simple case with a single Pauli."""
        theta = 1.2
        qc = QuantumCircuit(1)
        qc.ry(theta, 0)
        statefn = StateFn(qc)

        for alpha in [0.2, 0.4, 1]:
            with self.subTest(alpha=alpha):
                cvar = (CVaRMeasurement(Z, alpha) @ statefn).eval()
                ref = self.expected_cvar(statefn.to_matrix(), Z, alpha)
                self.assertAlmostEqual(cvar, ref)
    def invalid_input(self):
        """Test invalid input raises an error."""
        op = Z

        with self.subTest('alpha < 0'):
            with self.assertRaises(ValueError):
                _ = CVaRMeasurement(op, alpha=-0.2)

        with self.subTest('alpha > 1'):
            with self.assertRaises(ValueError):
                _ = CVaRMeasurement(op, alpha=12.3)

        with self.subTest('Single pauli operator not diagonal'):
            op = Y
            with self.assertRaises(OpflowError):
                _ = CVaRMeasurement(op)

        with self.subTest('Summed pauli operator not diagonal'):
            op = X ^ Z + Z ^ I
            with self.assertRaises(OpflowError):
                _ = CVaRMeasurement(op)

        with self.subTest('List operator not diagonal'):
            op = ListOp([X ^ Z, Z ^ I])
            with self.assertRaises(OpflowError):
                _ = CVaRMeasurement(op)

        with self.subTest('Matrix operator not diagonal'):
            op = MatrixOp([[1, 1], [0, 1]])
            with self.assertRaises(OpflowError):
                _ = CVaRMeasurement(op)
    def test_construction(self):
        """Test the correct operator expression is constructed."""

        alpha = 0.5
        base_expecation = PauliExpectation()
        cvar_expecation = CVaRExpectation(alpha=alpha,
                                          expectation=base_expecation)

        with self.subTest('single operator'):
            op = ~StateFn(Z) @ Plus
            expected = CVaRMeasurement(Z, alpha) @ Plus
            cvar = cvar_expecation.convert(op)
            self.assertEqual(cvar, expected)

        with self.subTest('list operator'):
            op = ~StateFn(ListOp([Z ^ Z, I ^ Z])) @ (Plus ^ Plus)
            expected = ListOp([
                CVaRMeasurement((Z ^ Z), alpha) @ (Plus ^ Plus),
                CVaRMeasurement((I ^ Z), alpha) @ (Plus ^ Plus)
            ])
            cvar = cvar_expecation.convert(op)
            self.assertEqual(cvar, expected)
예제 #7
0
    def test_coder_operators(self):
        """Test runtime encoder and decoder for operators."""
        x = Parameter("x")
        y = x + 1
        qc = QuantumCircuit(1)
        qc.h(0)
        coeffs = np.array([1, 2, 3, 4, 5, 6])
        table = PauliTable.from_labels(
            ["III", "IXI", "IYY", "YIZ", "XYZ", "III"])
        op = (2.0 * I ^ I)
        z2_symmetries = Z2Symmetries(
            [Pauli("IIZI"), Pauli("ZIII")],
            [Pauli("IIXI"), Pauli("XIII")], [1, 3], [-1, 1])
        isqrt2 = 1 / np.sqrt(2)
        sparse = scipy.sparse.csr_matrix([[0, isqrt2, 0, isqrt2]])

        subtests = (
            PauliSumOp(SparsePauliOp(Pauli("XYZX"), coeffs=[2]), coeff=3),
            PauliSumOp(SparsePauliOp(Pauli("XYZX"), coeffs=[1]), coeff=y),
            PauliSumOp(SparsePauliOp(Pauli("XYZX"), coeffs=[1 + 2j]),
                       coeff=3 - 2j),
            PauliSumOp.from_list([("II", -1.052373245772859),
                                  ("IZ", 0.39793742484318045)]),
            PauliSumOp(SparsePauliOp(table, coeffs), coeff=10),
            MatrixOp(primitive=np.array([[0, -1j], [1j, 0]]), coeff=x),
            PauliOp(primitive=Pauli("Y"), coeff=x),
            CircuitOp(qc, coeff=x),
            EvolvedOp(op, coeff=x),
            TaperedPauliSumOp(SparsePauliOp(Pauli("XYZX"), coeffs=[2]),
                              z2_symmetries),
            StateFn(qc, coeff=x),
            CircuitStateFn(qc, is_measurement=True),
            DictStateFn("1" * 3, is_measurement=True),
            VectorStateFn(np.ones(2**3, dtype=complex)),
            OperatorStateFn(CircuitOp(QuantumCircuit(1))),
            SparseVectorStateFn(sparse),
            Statevector([1, 0]),
            CVaRMeasurement(Z, 0.2),
            ComposedOp([(X ^ Y ^ Z), (Z ^ X ^ Y ^ Z).to_matrix_op()]),
            SummedOp([X ^ X * 2, Y ^ Y], 2),
            TensoredOp([(X ^ Y), (Z ^ I)]),
            (Z ^ Z) ^ (I ^ 2),
        )
        for op in subtests:
            with self.subTest(op=op):
                encoded = json.dumps(op, cls=RuntimeEncoder)
                self.assertIsInstance(encoded, str)
                decoded = json.loads(encoded, cls=RuntimeDecoder)
                self.assertEqual(op, decoded)
    def test_add(self):
        """Test addition."""
        theta = 2.2
        qc = QuantumCircuit(1)
        qc.ry(theta, 0)
        statefn = StateFn(qc)

        alpha = 0.2
        cvar = -1 * CVaRMeasurement(Z, alpha)
        ref = self.expected_cvar(statefn.to_matrix(), Z, alpha)

        other = ~StateFn(I)

        # test add in both directions
        res1 = ((cvar + other) @ statefn).eval()
        res2 = ((other + other) @ statefn).eval()

        self.assertAlmostEqual(res1, 1 - ref)
        self.assertAlmostEqual(res2, 1 - ref)