コード例 #1
0
    def test_log_i(self):
        """ MatrixOp.log_i() test """
        op = (-1.052373245772859 * I ^ I) + \
             (0.39793742484318045 * I ^ Z) + \
             (0.18093119978423156 * X ^ X) + \
             (-0.39793742484318045 * Z ^ I) + \
             (-0.01128010425623538 * Z ^ Z) * np.pi/2
        # Test with CircuitOp
        log_exp_op = op.to_matrix_op().exp_i().log_i().to_pauli_op()
        np.testing.assert_array_almost_equal(op.to_matrix(), log_exp_op.to_matrix())

        # Test with MatrixOp
        log_exp_op = op.to_matrix_op().exp_i().to_matrix_op().log_i().to_pauli_op()
        np.testing.assert_array_almost_equal(op.to_matrix(), log_exp_op.to_matrix())

        # Test with PauliOp
        log_exp_op = op.to_matrix_op().exp_i().to_pauli_op().log_i().to_pauli_op()
        np.testing.assert_array_almost_equal(op.to_matrix(), log_exp_op.to_matrix())

        # Test with EvolvedOp
        log_exp_op = op.exp_i().to_pauli_op().log_i().to_pauli_op()
        np.testing.assert_array_almost_equal(op.to_matrix(), log_exp_op.to_matrix())

        # Test with proper ListOp
        op = ListOp([(0.39793742484318045 * I ^ Z),
                     (0.18093119978423156 * X ^ X),
                     (-0.39793742484318045 * Z ^ I),
                     (-0.01128010425623538 * Z ^ Z) * np.pi / 2])
        log_exp_op = op.to_matrix_op().exp_i().to_matrix_op().log_i().to_pauli_op()
        np.testing.assert_array_almost_equal(op.to_matrix(), log_exp_op.to_matrix())
コード例 #2
0
    def test_not_to_matrix_called(self):
        """45 qubit calculation - literally will not work if to_matrix is
        somehow called (in addition to massive=False throwing an error)"""

        qs = 45
        states_op = ListOp([Zero ^ qs, One ^ qs, (Zero ^ qs) + (One ^ qs)])
        paulis_op = ListOp([Z ^ qs, (I ^ Z ^ I) ^ int(qs / 3)])

        converted_meas = self.expect.convert(~StateFn(paulis_op) @ states_op)
        np.testing.assert_array_almost_equal(converted_meas.eval(), [[1, -1, 0], [1, -1, 0]])
コード例 #3
0
    def test_list_op_eval_coeff_with_nonlinear_combofn(self):
        """Test evaluating a ListOp with non-linear combo function works with coefficients."""
        state = One
        op = ListOp(5 * [I], coeff=2, combo_fn=numpy.prod)
        expr1 = ~StateFn(op) @ state

        expr2 = ListOp(5 * [~state @ I @ state], coeff=2, combo_fn=numpy.prod)

        self.assertEqual(expr1.eval(), 2)  # if the coeff is propagated too far the result is 4
        self.assertEqual(expr2.eval(), 2)
コード例 #4
0
    def test_pauli_expect_op_vector_state_vector(self):
        """pauli expect op vector state vector test"""
        paulis_op = ListOp([X, Y, Z, I])
        states_op = ListOp([One, Zero, Plus, Minus])

        valids = [[+0, 0, 1, -1], [+0, 0, 0, 0], [-1, 1, 0, -0], [+1, 1, 1, 1]]
        converted_meas = self.expect.convert(~StateFn(paulis_op) @ states_op)
        np.testing.assert_array_almost_equal(converted_meas.eval(), valids, decimal=1)

        sampled = self.sampler.convert(converted_meas)
        np.testing.assert_array_almost_equal(sampled.eval(), valids, decimal=1)
コード例 #5
0
ファイル: vqe.py プロジェクト: fmozafari/qiskit-terra
    def _eval_aux_ops(
        self,
        parameters: np.ndarray,
        aux_operators: ListOrDict[OperatorBase],
        expectation: ExpectationBase,
        threshold: float = 1e-12,
    ) -> ListOrDict[Tuple[complex, complex]]:
        # Create new CircuitSampler to avoid breaking existing one's caches.
        sampler = CircuitSampler(self.quantum_instance)

        if isinstance(aux_operators, dict):
            list_op = ListOp(list(aux_operators.values()))
        else:
            list_op = ListOp(aux_operators)

        aux_op_meas = expectation.convert(StateFn(list_op,
                                                  is_measurement=True))
        aux_op_expect = aux_op_meas.compose(
            CircuitStateFn(self.ansatz.bind_parameters(parameters)))
        aux_op_expect_sampled = sampler.convert(aux_op_expect)

        # compute means
        values = np.real(aux_op_expect_sampled.eval())

        # compute standard deviations
        variances = np.real(
            expectation.compute_variance(aux_op_expect_sampled))
        if not isinstance(variances, np.ndarray) and variances == 0.0:
            # when `variances` is a single value equal to 0., our expectation value is exact and we
            # manually ensure the variances to be a list of the correct length
            variances = np.zeros(len(aux_operators), dtype=float)
        std_devs = np.sqrt(variances / self.quantum_instance.run_config.shots)

        # Discard values below threshold
        aux_op_means = values * (np.abs(values) > threshold)
        # zip means and standard deviations into tuples
        aux_op_results = zip(aux_op_means, std_devs)

        # Return None eigenvalues for None operators if aux_operators is a list.
        # None operators are already dropped in compute_minimum_eigenvalue if aux_operators is a dict.
        if isinstance(aux_operators, list):
            aux_operator_eigenvalues = [None] * len(aux_operators)
            key_value_iterator = enumerate(aux_op_results)
        else:
            aux_operator_eigenvalues = {}
            key_value_iterator = zip(aux_operators.keys(), aux_op_results)

        for key, value in key_value_iterator:
            if aux_operators[key] is not None:
                aux_operator_eigenvalues[key] = value

        return aux_operator_eigenvalues
コード例 #6
0
    def test_listop_num_qubits(self):
        """Test that ListOp.num_qubits checks that all operators have the same number of qubits."""
        op = ListOp([X ^ Y, Y ^ Z])
        with self.subTest("All operators have the same numbers of qubits"):
            self.assertEqual(op.num_qubits, 2)

        op = ListOp([X ^ Y, Y])
        with self.subTest("Operators have different numbers of qubits"):
            with self.assertRaises(ValueError):
                op.num_qubits  # pylint: disable=pointless-statement

            with self.assertRaises(ValueError):
                X @ op  # pylint: disable=pointless-statement
コード例 #7
0
    def test_ibmq_grouped_pauli_expectation(self):
        """pauli expect op vector state vector test"""
        from qiskit import IBMQ

        p = IBMQ.load_account()
        backend = p.get_backend("ibmq_qasm_simulator")
        q_instance = QuantumInstance(backend, seed_simulator=self.seed, seed_transpiler=self.seed)

        paulis_op = ListOp([X, Y, Z, I])
        states_op = ListOp([One, Zero, Plus, Minus])

        valids = [[+0, 0, 1, -1], [+0, 0, 0, 0], [-1, 1, 0, -0], [+1, 1, 1, 1]]
        converted_meas = self.expect.convert(~StateFn(paulis_op) @ states_op)
        sampled = CircuitSampler(q_instance).convert(converted_meas)
        np.testing.assert_array_almost_equal(sampled.eval(), valids, decimal=1)
コード例 #8
0
 def test_summedop_equals(self):
     """Test SummedOp.equals"""
     ops = [Z, CircuitOp(ZGate()), MatrixOp([[1, 0], [0, -1]]), Zero, Minus]
     sum_op = sum(ops + [ListOp(ops)])
     self.assertEqual(sum_op, sum_op)
     self.assertEqual(sum_op + sum_op, 2 * sum_op)
     self.assertEqual(sum_op + sum_op + sum_op, 3 * sum_op)
     ops2 = [Z, CircuitOp(ZGate()), MatrixOp([[1, 0], [0, 1]]), Zero, Minus]
     sum_op2 = sum(ops2 + [ListOp(ops)])
     self.assertNotEqual(sum_op, sum_op2)
     self.assertEqual(sum_op2, sum_op2)
     sum_op3 = sum(ops)
     self.assertNotEqual(sum_op, sum_op3)
     self.assertNotEqual(sum_op2, sum_op3)
     self.assertEqual(sum_op3, sum_op3)
コード例 #9
0
    def test_list_op_parameters(self):
        """Test that Parameters are stored correctly in a List Operator"""
        lam = Parameter('λ')
        phi = Parameter('φ')
        omega = Parameter('ω')

        mat_op = PrimitiveOp([[0, 1],
                              [1, 0]],
                             coeff=omega)

        qc = QuantumCircuit(1)
        qc.rx(phi, 0)
        qc_op = PrimitiveOp(qc)

        op1 = SummedOp([mat_op, qc_op])

        params = [phi, omega]
        self.assertEqual(op1.parameters, set(params))

        # check list nesting case
        op2 = PrimitiveOp([[1, 0],
                           [0, -1]],
                          coeff=lam)

        list_op = ListOp([op1, op2])

        params.append(lam)
        self.assertEqual(list_op.parameters, set(params))
コード例 #10
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))
コード例 #11
0
    def test_pauli_expect_op_vector(self):
        """pauli expect op vector test"""
        paulis_op = ListOp([X, Y, Z, I])
        converted_meas = self.expect.convert(~StateFn(paulis_op))

        plus_mean = converted_meas @ Plus
        sampled_plus = self.sampler.convert(plus_mean)
        np.testing.assert_array_almost_equal(sampled_plus.eval(), [1, 0, 0, 1],
                                             decimal=1)

        minus_mean = converted_meas @ Minus
        sampled_minus = self.sampler.convert(minus_mean)
        np.testing.assert_array_almost_equal(sampled_minus.eval(),
                                             [-1, 0, 0, 1],
                                             decimal=1)

        zero_mean = converted_meas @ Zero
        sampled_zero = self.sampler.convert(zero_mean)
        np.testing.assert_array_almost_equal(sampled_zero.eval(), [0, 0, 1, 1],
                                             decimal=1)

        sum_zero = (Plus + Minus) * (0.5**0.5)
        sum_zero_mean = converted_meas @ sum_zero
        sampled_zero_mean = self.sampler.convert(sum_zero_mean)
        # !!NOTE!!: Depolarizing channel (Sampling) means interference
        # does not happen between circuits in sum, so expectation does
        # not equal expectation for Zero!!
        np.testing.assert_array_almost_equal(sampled_zero_mean.eval(),
                                             [0, 0, 0, 1])
コード例 #12
0
ファイル: vqe.py プロジェクト: paulineollitrault/qiskit-terra
    def _eval_aux_ops(
        self,
        parameters: np.ndarray,
        aux_operators: List[OperatorBase],
        expectation: ExpectationBase,
        threshold: float = 1e-12,
    ) -> np.ndarray:
        # Create new CircuitSampler to avoid breaking existing one's caches.
        sampler = CircuitSampler(self.quantum_instance)

        aux_op_meas = expectation.convert(
            StateFn(ListOp(aux_operators), is_measurement=True))
        aux_op_expect = aux_op_meas.compose(
            CircuitStateFn(self.ansatz.bind_parameters(parameters)))
        values = np.real(sampler.convert(aux_op_expect).eval())

        # Discard values below threshold
        aux_op_results = values * (np.abs(values) > threshold)
        # Deal with the aux_op behavior where there can be Nones or Zero qubit Paulis in the list
        _aux_op_nones = [op is None for op in aux_operators]
        aux_operator_eigenvalues = [
            None if is_none else [result]
            for (is_none, result) in zip(_aux_op_nones, aux_op_results)
        ]
        # As this has mixed types, since it can included None, it needs to explicitly pass object
        # data type to avoid numpy 1.19 warning message about implicit conversion being deprecated
        aux_operator_eigenvalues = np.array([aux_operator_eigenvalues],
                                            dtype=object)
        return aux_operator_eigenvalues
コード例 #13
0
ファイル: utils.py プロジェクト: merav-aharoni/qiskit-terra
def _get_observable_evaluator(
    ansatz: QuantumCircuit,
    observables: Union[OperatorBase, List[OperatorBase]],
    expectation: ExpectationBase,
    sampler: CircuitSampler,
) -> Callable[[np.ndarray], Union[float, List[float]]]:
    """Get a callable to evaluate a (list of) observable(s) for given circuit parameters."""

    if isinstance(observables, list):
        observables = ListOp(observables)

    expectation_value = StateFn(observables,
                                is_measurement=True) @ StateFn(ansatz)
    converted = expectation.convert(expectation_value)

    ansatz_parameters = ansatz.parameters

    def evaluate_observables(theta: np.ndarray) -> Union[float, List[float]]:
        """Evaluate the observables for the ansatz parameters ``theta``.

        Args:
            theta: The ansatz parameters.

        Returns:
            The observables evaluated at the ansatz parameters.
        """
        value_dict = dict(zip(ansatz_parameters, theta))
        sampled = sampler.convert(converted, params=value_dict)
        return sampled.eval()

    return evaluate_observables
コード例 #14
0
    def test_grad_combo_fn_chain_rule_nat_grad(self):
        """Test the chain rule for a custom gradient combo function."""
        np.random.seed(2)

        def combo_fn(x):
            amplitudes = x[0].primitive.data
            pdf = np.multiply(amplitudes, np.conj(amplitudes))
            return np.sum(np.log(pdf)) / (-len(amplitudes))

        def grad_combo_fn(x):
            amplitudes = x[0].primitive.data
            pdf = np.multiply(amplitudes, np.conj(amplitudes))
            grad = []
            for prob in pdf:
                grad += [-1 / prob]
            return grad

        try:
            qc = RealAmplitudes(2, reps=1)
            grad_op = ListOp([StateFn(qc)], combo_fn=combo_fn, grad_combo_fn=grad_combo_fn)
            grad = NaturalGradient(grad_method='lin_comb', regularization='ridge'
                                   ).convert(grad_op, qc.ordered_parameters)
            value_dict = dict(
                zip(qc.ordered_parameters, np.random.rand(len(qc.ordered_parameters))))
            correct_values = [[0.20777236], [-18.92560338], [-15.89005475], [-10.44002031]]
            np.testing.assert_array_almost_equal(grad.assign_parameters(value_dict).eval(),
                                                 correct_values, decimal=3)
        except MissingOptionalLibraryError as ex:
            self.skipTest(str(ex))
コード例 #15
0
    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)
コード例 #16
0
    def test_grad_combo_fn_chain_rule(self, method):
        """Test the chain rule for a custom gradient combo function."""
        np.random.seed(2)

        def combo_fn(x):
            amplitudes = x[0].primitive.data
            pdf = np.multiply(amplitudes, np.conj(amplitudes))
            return np.sum(np.log(pdf)) / (-len(amplitudes))

        def grad_combo_fn(x):
            amplitudes = x[0].primitive.data
            pdf = np.multiply(amplitudes, np.conj(amplitudes))
            grad = []
            for prob in pdf:
                grad += [-1 / prob]
            return grad

        qc = RealAmplitudes(2, reps=1)
        grad_op = ListOp([StateFn(qc.decompose())],
                         combo_fn=combo_fn,
                         grad_combo_fn=grad_combo_fn)
        grad = Gradient(grad_method=method).convert(grad_op)
        value_dict = dict(
            zip(qc.ordered_parameters,
                np.random.rand(len(qc.ordered_parameters))))
        correct_values = [
            [(-0.16666259133549044 + 0j)],
            [(-7.244949702732864 + 0j)],
            [(-2.979791752749964 + 0j)],
            [(-5.310186078432614 + 0j)],
        ]
        np.testing.assert_array_almost_equal(
            grad.assign_parameters(value_dict).eval(), correct_values)
コード例 #17
0
def _prepare_list_op(
    quantum_state: Union[Statevector, QuantumCircuit, OperatorBase, ],
    observables: ListOrDict[OperatorBase],
) -> ListOp:
    """
    Accepts a list or a dictionary of operators and converts them to a ``ListOp``.

    Args:
        quantum_state: An unparametrized quantum circuit representing a quantum state that
            expectation values are computed against.
        observables: A list or a dictionary of operators.

    Returns:
        A ``ListOp`` that includes all provided observables.
    """
    if isinstance(observables, dict):
        observables = list(observables.values())

    if not isinstance(quantum_state, StateFn):
        quantum_state = StateFn(quantum_state)

    return ListOp([
        StateFn(obs, is_measurement=True).compose(quantum_state)
        for obs in observables
    ])
コード例 #18
0
 def test_list_pauli_sum_op(self):
     """Test PauliExpectation for List[PauliSumOp]"""
     test_op = ListOp([~StateFn(PauliSumOp.from_list([("XX", 1), ("ZI", 3), ("ZZ", 5)]))])
     observable = self.expect.convert(test_op)
     self.assertIsInstance(observable, ListOp)
     self.assertIsInstance(observable[0][0][0].primitive, PauliSumOp)
     self.assertIsInstance(observable[0][1][0].primitive, PauliSumOp)
コード例 #19
0
 def test_list_pauli_sum(self):
     """Test AerPauliExpectation for ListOp[PauliSumOp]"""
     test_op = ListOp([PauliSumOp.from_list([("XX", 1), ("ZI", 3), ("ZZ", 5)])])
     observable = AerPauliExpectation().convert(~StateFn(test_op))
     self.assertIsInstance(observable, ListOp)
     self.assertIsInstance(observable[0], CircuitStateFn)
     self.assertTrue(observable[0].is_measurement)
コード例 #20
0
    def test_jax_chain_rule(self, method: str, autograd: bool):
        """Test the chain rule functionality using Jax

        d<H>/d<X> = 2<X>
        d<H>/d<Z> = - sin(<Z>)
        <Z> = Tr(|psi><psi|Z) = sin(a)sin(b)
        <X> = Tr(|psi><psi|X) = cos(a)
        d<H>/da = d<H>/d<X> d<X>/da + d<H>/d<Z> d<Z>/da = - 2 cos(a)sin(a)
                    - sin(sin(a)sin(b)) * cos(a)sin(b)
        d<H>/db = d<H>/d<X> d<X>/db + d<H>/d<Z> d<Z>/db = - sin(sin(a)sin(b)) * sin(a)cos(b)
        """

        a = Parameter("a")
        b = Parameter("b")
        params = [a, b]

        q = QuantumRegister(1)
        qc = QuantumCircuit(q)
        qc.h(q)
        qc.rz(params[0], q[0])
        qc.rx(params[1], q[0])

        def combo_fn(x):
            return jnp.power(x[0], 2) + jnp.cos(x[1])

        def grad_combo_fn(x):
            return np.array([2 * x[0], -np.sin(x[1])])

        op = ListOp(
            [
                ~StateFn(X) @ CircuitStateFn(primitive=qc, coeff=1.0),
                ~StateFn(Z) @ CircuitStateFn(primitive=qc, coeff=1.0),
            ],
            combo_fn=combo_fn,
            grad_combo_fn=None if autograd else grad_combo_fn,
        )

        state_grad = Gradient(grad_method=method).convert(operator=op,
                                                          params=params)
        values_dict = [
            {
                a: np.pi / 4,
                b: np.pi
            },
            {
                params[0]: np.pi / 4,
                params[1]: np.pi / 4
            },
            {
                params[0]: np.pi / 2,
                params[1]: np.pi / 4
            },
        ]
        correct_values = [[-1.0, 0.0], [-1.2397, -0.2397], [0, -0.45936]]
        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)
コード例 #21
0
    def test_opflow_qnn_2_2(self, q_i):
        """Test Torch Connector + Opflow QNN with input/output dimension 2/2."""
        from torch import Tensor

        if q_i == "sv":
            quantum_instance = self._sv_quantum_instance
        else:
            quantum_instance = self._qasm_quantum_instance

        # construct parametrized circuit
        params_1 = [Parameter("input1"), Parameter("weight1")]
        qc_1 = QuantumCircuit(1)
        qc_1.h(0)
        qc_1.ry(params_1[0], 0)
        qc_1.rx(params_1[1], 0)
        qc_sfn_1 = StateFn(qc_1)

        # construct cost operator
        h_1 = StateFn(PauliSumOp.from_list([("Z", 1.0), ("X", 1.0)]))

        # combine operator and circuit to objective function
        op_1 = ~h_1 @ qc_sfn_1

        # construct parametrized circuit
        params_2 = [Parameter("input2"), Parameter("weight2")]
        qc_2 = QuantumCircuit(1)
        qc_2.h(0)
        qc_2.ry(params_2[0], 0)
        qc_2.rx(params_2[1], 0)
        qc_sfn_2 = StateFn(qc_2)

        # construct cost operator
        h_2 = StateFn(PauliSumOp.from_list([("Z", 1.0), ("X", 1.0)]))

        # combine operator and circuit to objective function
        op_2 = ~h_2 @ qc_sfn_2

        op = ListOp([op_1, op_2])

        qnn = OpflowQNN(
            op,
            [params_1[0], params_2[0]],
            [params_1[1], params_2[1]],
            quantum_instance=quantum_instance,
            input_gradients=True,
        )
        model = TorchConnector(qnn)

        test_data = [
            Tensor([1]),
            Tensor([1, 2]),
            Tensor([[1], [2]]),
            Tensor([[1, 2], [3, 4]]),
        ]

        # test model
        self._validate_output_shape(model, test_data)
        if q_i == "sv":
            self._validate_backward_pass(model)
コード例 #22
0
    def test_opflow_qnn_2_2(self, config):
        """Test Opflow QNN with input/output dimension 2/2."""
        q_i, input_grad_required = config

        if q_i == STATEVECTOR:
            quantum_instance = self.sv_quantum_instance
        elif q_i == QASM:
            quantum_instance = self.qasm_quantum_instance
        else:
            quantum_instance = None

        # construct parametrized circuit
        params_1 = [Parameter("input1"), Parameter("weight1")]
        qc_1 = QuantumCircuit(1)
        qc_1.h(0)
        qc_1.ry(params_1[0], 0)
        qc_1.rx(params_1[1], 0)
        qc_sfn_1 = StateFn(qc_1)

        # construct cost operator
        h_1 = StateFn(PauliSumOp.from_list([("Z", 1.0), ("X", 1.0)]))

        # combine operator and circuit to objective function
        op_1 = ~h_1 @ qc_sfn_1

        # construct parametrized circuit
        params_2 = [Parameter("input2"), Parameter("weight2")]
        qc_2 = QuantumCircuit(1)
        qc_2.h(0)
        qc_2.ry(params_2[0], 0)
        qc_2.rx(params_2[1], 0)
        qc_sfn_2 = StateFn(qc_2)

        # construct cost operator
        h_2 = StateFn(PauliSumOp.from_list([("Z", 1.0), ("X", 1.0)]))

        # combine operator and circuit to objective function
        op_2 = ~h_2 @ qc_sfn_2

        op = ListOp([op_1, op_2])

        qnn = OpflowQNN(
            op,
            [params_1[0], params_2[0]],
            [params_1[1], params_2[1]],
            quantum_instance=quantum_instance,
        )
        qnn.input_gradients = input_grad_required

        test_data = [np.array([1, 2]), np.array([[1, 2], [3, 4]])]

        # test model
        self.validate_output_shape(qnn, test_data)

        # test the qnn after we set a quantum instance
        if quantum_instance is None:
            qnn.quantum_instance = self.qasm_quantum_instance
            self.validate_output_shape(qnn, test_data)
コード例 #23
0
    def test_opflow_qnn_2_2(self, q_i):
        """ Test Torch Connector + Opflow QNN with input/output dimension 2/2."""

        if q_i == 'sv':
            quantum_instance = self.sv_quantum_instance
        else:
            quantum_instance = self.qasm_quantum_instance

        # construct parametrized circuit
        params_1 = [Parameter('input1'), Parameter('weight1')]
        qc_1 = QuantumCircuit(1)
        qc_1.h(0)
        qc_1.ry(params_1[0], 0)
        qc_1.rx(params_1[1], 0)
        qc_sfn_1 = StateFn(qc_1)

        # construct cost operator
        h_1 = StateFn(PauliSumOp.from_list([('Z', 1.0), ('X', 1.0)]))

        # combine operator and circuit to objective function
        op_1 = ~h_1 @ qc_sfn_1

        # construct parametrized circuit
        params_2 = [Parameter('input2'), Parameter('weight2')]
        qc_2 = QuantumCircuit(1)
        qc_2.h(0)
        qc_2.ry(params_2[0], 0)
        qc_2.rx(params_2[1], 0)
        qc_sfn_2 = StateFn(qc_2)

        # construct cost operator
        h_2 = StateFn(PauliSumOp.from_list([('Z', 1.0), ('X', 1.0)]))

        # combine operator and circuit to objective function
        op_2 = ~h_2 @ qc_sfn_2

        op = ListOp([op_1, op_2])

        qnn = OpflowQNN(op, [params_1[0], params_2[0]],
                        [params_1[1], params_2[1]],
                        quantum_instance=quantum_instance)
        try:
            model = TorchConnector(qnn)

            test_data = [
                Tensor(1),
                Tensor([1, 2]),
                Tensor([[1], [2]]),
                Tensor([[1, 2], [3, 4]])
            ]

            # test model
            self.validate_output_shape(model, test_data)
            if q_i == 'sv':
                self.validate_backward_pass(model)
        except MissingOptionalLibraryError as ex:
            self.skipTest(str(ex))
コード例 #24
0
    def test_state_hessian_custom_combo_fn(self, method):
        """Test the state Hessian with on an operator which includes
            a user-defined combo_fn.

        Tr(|psi><psi|Z) = sin(a)sin(b)
        Tr(|psi><psi|X) = cos(a)
        d^2<H>/da^2 = - 0.5 cos(a) + 1 sin(a)sin(b)
        d^2<H>/dbda = - 1 cos(a)cos(b)
        d^2<H>/dbda = - 1 cos(a)cos(b)
        d^2<H>/db^2 = + 1 sin(a)sin(b)
        """

        ham = 0.5 * X - 1 * Z
        a = Parameter("a")
        b = Parameter("b")
        params = [(a, a), (a, b), (b, b)]

        q = QuantumRegister(1)
        qc = QuantumCircuit(q)
        qc.h(q)
        qc.rz(a, q[0])
        qc.rx(b, q[0])

        op = ListOp(
            [~StateFn(ham) @ CircuitStateFn(primitive=qc, coeff=1.0)],
            combo_fn=lambda x: x[0]**3 + 4 * x[0],
        )
        state_hess = Hessian(hess_method=method).convert(operator=op,
                                                         params=params)

        values_dict = [
            {
                a: np.pi / 4,
                b: np.pi
            },
            {
                a: np.pi / 4,
                b: np.pi / 4
            },
            {
                a: np.pi / 2,
                b: np.pi / 4
            },
        ]

        correct_values = [
            [-1.28163104, 2.56326208, 1.06066017],
            [-0.04495626, -2.40716991, 1.8125],
            [2.82842712, -1.5, 1.76776695],
        ]

        for i, value_dict in enumerate(values_dict):
            np.testing.assert_array_almost_equal(
                state_hess.assign_parameters(value_dict).eval(),
                correct_values[i],
                decimal=1)
コード例 #25
0
    def test_multi_representation_ops(self):
        """Test observables with mixed representations"""
        mixed_ops = ListOp([X.to_matrix_op(), H, H + I, X])
        converted_meas = self.expect.convert(~StateFn(mixed_ops))

        plus_mean = converted_meas @ Plus
        sampled_plus = self.sampler.convert(plus_mean)
        np.testing.assert_array_almost_equal(sampled_plus.eval(),
                                             [1, 0.5**0.5, (1 + 0.5**0.5), 1],
                                             decimal=1)
コード例 #26
0
    def test_pauli_expect_op_vector(self):
        """ pauli expect op vector test """
        paulis_op = ListOp([X, Y, Z, I])
        converted_meas = self.expect.convert(~StateFn(paulis_op))

        plus_mean = (converted_meas @ Plus)
        np.testing.assert_array_almost_equal(plus_mean.eval(), [1, 0, 0, 1],
                                             decimal=1)
        sampled_plus = self.sampler.convert(plus_mean)
        np.testing.assert_array_almost_equal(sampled_plus.eval(), [1, 0, 0, 1],
                                             decimal=1)

        minus_mean = (converted_meas @ Minus)
        np.testing.assert_array_almost_equal(minus_mean.eval(), [-1, 0, 0, 1],
                                             decimal=1)
        sampled_minus = self.sampler.convert(minus_mean)
        np.testing.assert_array_almost_equal(sampled_minus.eval(),
                                             [-1, 0, 0, 1],
                                             decimal=1)

        zero_mean = (converted_meas @ Zero)
        np.testing.assert_array_almost_equal(zero_mean.eval(), [0, 0, 1, 1],
                                             decimal=1)
        sampled_zero = self.sampler.convert(zero_mean)
        np.testing.assert_array_almost_equal(sampled_zero.eval(), [0, 0, 1, 1],
                                             decimal=1)

        sum_zero = (Plus + Minus) * (.5**.5)
        sum_zero_mean = (converted_meas @ sum_zero)
        np.testing.assert_array_almost_equal(sum_zero_mean.eval(),
                                             [0, 0, 1, 1],
                                             decimal=1)
        sampled_zero_mean = self.sampler.convert(sum_zero_mean)
        # !!NOTE!!: Depolarizing channel (Sampling) means interference
        # does not happen between circuits in sum, so expectation does
        # not equal expectation for Zero!!
        np.testing.assert_array_almost_equal(sampled_zero_mean.eval(),
                                             [0, 0, 0, 1],
                                             decimal=1)

        for i, op in enumerate(paulis_op.oplist):
            mat_op = op.to_matrix()
            np.testing.assert_array_almost_equal(
                zero_mean.eval()[i],
                Zero.adjoint().to_matrix() @ mat_op @ Zero.to_matrix(),
                decimal=1)
            np.testing.assert_array_almost_equal(
                plus_mean.eval()[i],
                Plus.adjoint().to_matrix() @ mat_op @ Plus.to_matrix(),
                decimal=1)
            np.testing.assert_array_almost_equal(
                minus_mean.eval()[i],
                Minus.adjoint().to_matrix() @ mat_op @ Minus.to_matrix(),
                decimal=1)
コード例 #27
0
    def test_pauli_expect_op_vector(self):
        """pauli expect op vector test"""
        paulis_op = ListOp([X, Y, Z, I])
        converted_meas = self.expect.convert(~StateFn(paulis_op))

        plus_mean = converted_meas @ Plus
        np.testing.assert_array_almost_equal(plus_mean.eval(), [1, 0, 0, 1],
                                             decimal=1)
        sampled_plus = self.sampler.convert(plus_mean)
        np.testing.assert_array_almost_equal(sampled_plus.eval(), [1, 0, 0, 1],
                                             decimal=1)

        minus_mean = converted_meas @ Minus
        np.testing.assert_array_almost_equal(minus_mean.eval(), [-1, 0, 0, 1],
                                             decimal=1)
        sampled_minus = self.sampler.convert(minus_mean)
        np.testing.assert_array_almost_equal(sampled_minus.eval(),
                                             [-1, 0, 0, 1],
                                             decimal=1)

        zero_mean = converted_meas @ Zero
        np.testing.assert_array_almost_equal(zero_mean.eval(), [0, 0, 1, 1],
                                             decimal=1)
        sampled_zero = self.sampler.convert(zero_mean)
        np.testing.assert_array_almost_equal(sampled_zero.eval(), [0, 0, 1, 1],
                                             decimal=1)

        sum_zero = (Plus + Minus) * (0.5**0.5)
        sum_zero_mean = converted_meas @ sum_zero
        np.testing.assert_array_almost_equal(sum_zero_mean.eval(),
                                             [0, 0, 1, 1],
                                             decimal=1)
        sampled_zero = self.sampler.convert(sum_zero)
        np.testing.assert_array_almost_equal(
            (converted_meas @ sampled_zero).eval(), [0, 0, 1, 1], decimal=1)

        for i, op in enumerate(paulis_op.oplist):
            mat_op = op.to_matrix()
            np.testing.assert_array_almost_equal(
                zero_mean.eval()[i],
                Zero.adjoint().to_matrix() @ mat_op @ Zero.to_matrix(),
                decimal=1,
            )
            np.testing.assert_array_almost_equal(
                plus_mean.eval()[i],
                Plus.adjoint().to_matrix() @ mat_op @ Plus.to_matrix(),
                decimal=1,
            )
            np.testing.assert_array_almost_equal(
                minus_mean.eval()[i],
                Minus.adjoint().to_matrix() @ mat_op @ Minus.to_matrix(),
                decimal=1,
            )
コード例 #28
0
    def test_pauli_expect_non_hermitian_pauliop(self):
        """pauli expect state vector with non hermitian operator test"""
        states_op = ListOp([One, Zero, Plus, Minus])

        op = 1j * X

        converted_meas = self.expect.convert(
            StateFn(op, is_measurement=True) @ states_op)
        sampled = self.sampler.convert(converted_meas)

        np.testing.assert_array_almost_equal(sampled.eval(), [0, 0, 1j, -1j],
                                             decimal=1)
コード例 #29
0
    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)
コード例 #30
0
    def test_pauli_expect_state_vector(self):
        """pauli expect state vector test"""
        states_op = ListOp([One, Zero, Plus, Minus])

        paulis_op = X
        converted_meas = self.expect.convert(~StateFn(paulis_op) @ states_op)
        sampled = self.sampler.convert(converted_meas)

        # Small test to see if execution results are accessible
        for composed_op in sampled:
            self.assertIn("counts", composed_op[0].execution_results)

        np.testing.assert_array_almost_equal(sampled.eval(), [0, 0, 1, -1], decimal=1)