def setUp(self) -> None: super().setUp() self.seed = 97 backend = BasicAer.get_backend('qasm_simulator') q_instance = QuantumInstance(backend, seed_simulator=self.seed, seed_transpiler=self.seed) self.sampler = CircuitSampler(q_instance, attach_results=True) self.expect = PauliExpectation()
def _set_quantum_instance( self, quantum_instance: Optional[Union[QuantumInstance, Backend]]) -> None: """ Internal method to set a quantum instance and compute/initialize a sampler. Args: quantum_instance: A quantum instance to set. Returns: None. """ if isinstance(quantum_instance, Backend): quantum_instance = QuantumInstance(quantum_instance) self._quantum_instance = quantum_instance if quantum_instance is not None: self._circuit_sampler = CircuitSampler( self._quantum_instance, param_qobj=is_aer_provider(self._quantum_instance.backend), caching="all", ) else: self._circuit_sampler = None
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))
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
def test_grouped_pauli_expectation(self): """grouped pauli expectation test""" two_qubit_H2 = ((-1.052373245772859 * I ^ I) + (0.39793742484318045 * I ^ Z) + (-0.39793742484318045 * Z ^ I) + (-0.01128010425623538 * Z ^ Z) + (0.18093119978423156 * X ^ X)) wf = CX @ (H ^ I) @ Zero expect_op = PauliExpectation(group_paulis=False).convert( ~StateFn(two_qubit_H2) @ wf) self.sampler._extract_circuitstatefns(expect_op) num_circuits_ungrouped = len(self.sampler._circuit_ops_cache) self.assertEqual(num_circuits_ungrouped, 5) expect_op_grouped = PauliExpectation(group_paulis=True).convert( ~StateFn(two_qubit_H2) @ wf) q_instance = QuantumInstance( BasicAer.get_backend("statevector_simulator"), seed_simulator=self.seed, seed_transpiler=self.seed, ) sampler = CircuitSampler(q_instance) sampler._extract_circuitstatefns(expect_op_grouped) num_circuits_grouped = len(sampler._circuit_ops_cache) self.assertEqual(num_circuits_grouped, 2)
def test_circuit_sampler2(self, method): """Test the probability gradient with the circuit sampler dp0/da = cos(a)sin(b) / 2 dp1/da = - cos(a)sin(b) / 2 dp0/db = sin(a)cos(b) / 2 dp1/db = - sin(a)cos(b) / 2 """ 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]) op = CircuitStateFn(primitive=qc, coeff=1.) shots = 8000 if method == 'fin_diff': np.random.seed(8) prob_grad = Gradient(grad_method=method, epsilon=shots**(-1 / 6.)).convert( operator=op, params=params) else: prob_grad = Gradient(grad_method=method).convert(operator=op, params=params) values_dict = [{ a: [np.pi / 4], b: [0] }, { params[0]: [np.pi / 4], params[1]: [np.pi / 4] }, { params[0]: [np.pi / 2], params[1]: [np.pi] }] correct_values = [[[0, 0], [1 / (2 * np.sqrt(2)), -1 / (2 * np.sqrt(2))]], [[1 / 4, -1 / 4], [1 / 4, -1 / 4]], [[0, 0], [-1 / 2, 1 / 2]]] backend = BasicAer.get_backend('qasm_simulator') q_instance = QuantumInstance(backend=backend, shots=shots) for i, value_dict in enumerate(values_dict): sampler = CircuitSampler(backend=q_instance).convert( prob_grad, params=value_dict) result = sampler.eval()[0] self.assertTrue( np.allclose(result[0].toarray(), correct_values[i][0], atol=0.1)) self.assertTrue( np.allclose(result[1].toarray(), correct_values[i][1], atol=0.1))
def _eval_op(self, state, op, quantum_instance, expectation): # if the operator is empty we simply return 0 if op == 0: # Note, that for some reason the individual results need to be wrapped in lists. # See also: VQE._eval_aux_ops() return [0.0j] exp = ~StateFn(op) @ state # <state|op|state> if quantum_instance is not None: try: sampler = CircuitSampler(quantum_instance) if expectation is not None: exp = expectation.convert(exp) result = sampler.convert(exp).eval() except ValueError: # TODO make this cleaner. The reason for it being here is that some quantum # instances can lead to non-positive statevectors which the Qiskit circuit # Initializer is unable to handle. result = exp.eval() else: result = exp.eval() # Note, that for some reason the individual results need to be wrapped in lists. # See also: VQE._eval_aux_ops() return [result]
def test_circuit_sampler_caching(self, caching): """Test caching all operators works.""" 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 = Parameter('x') circuit = QuantumCircuit(1) circuit.ry(x, 0) expr1 = ~StateFn(H) @ StateFn(circuit) expr2 = ~StateFn(X) @ StateFn(circuit) sampler = CircuitSampler(Aer.get_backend('statevector_simulator'), caching=caching) res1 = sampler.convert(expr1, params={x: 0}).eval() res2 = sampler.convert(expr2, params={x: 0}).eval() res3 = sampler.convert(expr1, params={x: 0}).eval() res4 = sampler.convert(expr2, params={x: 0}).eval() self.assertEqual(res1, res3) self.assertEqual(res2, res4) if caching == 'last': self.assertEqual(len(sampler._cached_ops.keys()), 1) else: self.assertEqual(len(sampler._cached_ops.keys()), 2)
def test_circuit_sampler(self, method): """Test the gradient with circuit sampler Tr(|psi><psi|Z) = sin(a)sin(b) Tr(|psi><psi|X) = cos(a) d<H>/da = - 0.5 sin(a) - 1 cos(a)sin(b) d<H>/db = - 1 sin(a)cos(b) """ ham = 0.5 * X - 1 * Z 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]) op = ~StateFn(ham) @ CircuitStateFn(primitive=qc, coeff=1.0) shots = 8000 if method == "fin_diff": np.random.seed(8) state_grad = Gradient(grad_method=method, epsilon=shots**(-1 / 6.0)).convert(operator=op) else: state_grad = Gradient(grad_method=method).convert(operator=op) 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 = [ [-0.5 / np.sqrt(2), 1 / np.sqrt(2)], [-0.5 / np.sqrt(2) - 0.5, -1 / 2.0], [-0.5, -1 / np.sqrt(2)], ] backend = BasicAer.get_backend("qasm_simulator") q_instance = QuantumInstance(backend=backend, shots=shots) for i, value_dict in enumerate(values_dict): sampler = CircuitSampler(backend=q_instance).convert( state_grad, params={k: [v] for k, v in value_dict.items()}) np.testing.assert_array_almost_equal(sampler.eval()[0], correct_values[i], decimal=1)
def quantum_instance(self, quantum_instance: Optional[Union[Backend, QuantumInstance]]) -> None: """Set the quantum instance and circuit sampler.""" if quantum_instance is not None: if not isinstance(quantum_instance, QuantumInstance): quantum_instance = QuantumInstance(quantum_instance) self._sampler = CircuitSampler(quantum_instance) self._quantum_instance = quantum_instance
def quantum_instance(self, quantum_instance: Union[QuantumInstance, BaseBackend, Backend]) -> None: """ set quantum_instance """ super(VQE, self.__class__).quantum_instance.__set__(self, quantum_instance) self._circuit_sampler = CircuitSampler( self._quantum_instance, param_qobj=is_aer_provider(self._quantum_instance.backend))
def quantum_instance( self, quantum_instance: Union[QuantumInstance, BaseBackend, Backend]) -> None: """set quantum_instance""" if not isinstance(quantum_instance, QuantumInstance): quantum_instance = QuantumInstance(quantum_instance) self._quantum_instance = quantum_instance self._circuit_sampler = CircuitSampler(quantum_instance, param_qobj=is_aer_provider( quantum_instance.backend))
def test_quantum_instance_with_backend_shots(self): """Test sampling a circuit where the backend has shots attached.""" try: from qiskit.providers.aer import AerSimulator except Exception as ex: # pylint: disable=broad-except self.skipTest("Aer doesn't appear to be installed. Error: '{}'".format(str(ex))) backend = AerSimulator(shots=10) sampler = CircuitSampler(backend) res = sampler.convert(~Plus @ Plus).eval() self.assertAlmostEqual(res, 1 + 0j, places=2)
def quantum_instance(self, quantum_instance: Union[QuantumInstance, BaseBackend, Backend]) -> None: """ set quantum_instance """ super(VQE, self.__class__).quantum_instance.__set__(self, quantum_instance) self._circuit_sampler = CircuitSampler( self._quantum_instance, param_qobj=is_aer_provider(self._quantum_instance.backend)) # Expectation was not passed by user, try to create one if not self._user_valid_expectation: self._try_set_expectation_value_from_factory()
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
def __init__(self, operator: OperatorBase, input_params: Optional[List[Parameter]] = None, weight_params: Optional[List[Parameter]] = None, exp_val: Optional[ExpectationBase] = None, gradient: Optional[Gradient] = None, quantum_instance: Optional[Union[QuantumInstance, BaseBackend, Backend]] = None): """Initializes the Opflow Quantum Neural Network. Args: operator: The parametrized operator that represents the neural network. input_params: The operator parameters that correspond to the input of the network. weight_params: The operator parameters that correspond to the trainable weights. exp_val: The Expected Value converter to be used for the operator. gradient: The Gradient converter to be used for the operator's backward pass. quantum_instance: The quantum instance to evaluate the network. """ self._input_params = list(input_params) or [] self._weight_params = list(weight_params) or [] if isinstance(quantum_instance, (BaseBackend, Backend)): quantum_instance = QuantumInstance(quantum_instance) if quantum_instance: self._quantum_instance = quantum_instance self._circuit_sampler = CircuitSampler( self._quantum_instance, param_qobj=is_aer_provider(self._quantum_instance.backend), caching="all") else: self._quantum_instance = None self._circuit_sampler = None self._operator = operator self._forward_operator = exp_val.convert( operator) if exp_val else operator self._gradient_operator: OperatorBase = None try: gradient = gradient or Gradient() self._gradient_operator = gradient.convert( operator, self._input_params + self._weight_params) except (ValueError, TypeError, OpflowError, QiskitError): logger.warning( 'Cannot compute gradient operator! Continuing without gradients!' ) output_shape = self._get_output_shape_from_op(operator) super().__init__(len(self._input_params), len(self._weight_params), sparse=False, output_shape=output_shape)
def quantum_instance( self, quantum_instance: Optional[Union[QuantumInstance, BaseBackend, Backend]] ) -> None: """Set quantum instance. Args: quantum_instance: The quantum instance used to run this algorithm. If None, a Statevector calculation is done. """ if quantum_instance is not None: self._sampler = CircuitSampler(quantum_instance) else: self._sampler = None
def test_pauli_expectation_param_qobj(self): """Test PauliExpectation with param_qobj""" q_instance = QuantumInstance( self.backend, seed_simulator=self.seed, seed_transpiler=self.seed, shots=10000 ) qubit_op = (0.1 * I ^ I) + (0.2 * I ^ Z) + (0.3 * Z ^ I) + (0.4 * Z ^ Z) + (0.5 * X ^ X) ansatz = RealAmplitudes(qubit_op.num_qubits) ansatz_circuit_op = CircuitStateFn(ansatz) observable = PauliExpectation().convert(~StateFn(qubit_op)) expect_op = observable.compose(ansatz_circuit_op).reduce() params1 = {} params2 = {} for param in ansatz.parameters: params1[param] = [0] params2[param] = [0, 0] sampler1 = CircuitSampler(backend=q_instance, param_qobj=False) samples1 = sampler1.convert(expect_op, params=params1) val1 = np.real(samples1.eval())[0] samples2 = sampler1.convert(expect_op, params=params2) val2 = np.real(samples2.eval()) sampler2 = CircuitSampler(backend=q_instance, param_qobj=True) samples3 = sampler2.convert(expect_op, params=params1) val3 = np.real(samples3.eval()) samples4 = sampler2.convert(expect_op, params=params2) val4 = np.real(samples4.eval()) np.testing.assert_array_almost_equal([val1] * 2, val2, decimal=2) np.testing.assert_array_almost_equal(val1, val3, decimal=2) np.testing.assert_array_almost_equal([val1] * 2, val4, decimal=2)
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)
def setUp(self) -> None: super().setUp() try: from qiskit import Aer self.seed = 97 self.backend = Aer.get_backend("aer_simulator") q_instance = QuantumInstance( self.backend, seed_simulator=self.seed, seed_transpiler=self.seed ) self.sampler = CircuitSampler(q_instance, attach_results=True) self.expect = AerPauliExpectation() except Exception as ex: # pylint: disable=broad-except self.skipTest("Aer doesn't appear to be installed. Error: '{}'".format(str(ex))) return
def _eval_aux_ops(self, threshold=1e-12): # Create new CircuitSampler to avoid breaking existing one's caches. sampler = CircuitSampler(self.quantum_instance) aux_op_meas = self.expectation.convert(StateFn(ListOp(self.aux_operators), is_measurement=True)) aux_op_expect = aux_op_meas.compose(CircuitStateFn(self.get_optimal_circuit())) 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 self._ret['aux_ops'] = [None if is_none else [result] for (is_none, result) in zip(self._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 self._ret['aux_ops'] = np.array([self._ret['aux_ops']], dtype=object)
def _set_quantum_instance( self, quantum_instance: Optional[Union[QuantumInstance, Backend]], output_shape: Union[int, Tuple[int, ...]], interpret: Optional[Callable[[int], Union[int, Tuple[int, ...]]]], ) -> None: """ Internal method to set a quantum instance and compute/initialize internal properties such as an interpret function, output shape and a sampler. Args: quantum_instance: A quantum instance to set. output_shape: An output shape of the custom interpretation. interpret: A callable that maps the measured integer to another unsigned integer or tuple of unsigned integers. """ if isinstance(quantum_instance, Backend): quantum_instance = QuantumInstance(quantum_instance) self._quantum_instance = quantum_instance if self._quantum_instance is not None: # add measurements in case none are given if self._quantum_instance.is_statevector: if len(self._circuit.clbits) > 0: self._circuit.remove_final_measurements() elif len(self._circuit.clbits) == 0: self._circuit.measure_all() # set interpret and compute output shape self.set_interpret(interpret, output_shape) # prepare sampler self._sampler = CircuitSampler(self._quantum_instance, param_qobj=False, caching="all") # transpile the QNN circuit try: self._circuit = self._quantum_instance.transpile( self._circuit, pass_manager=self._quantum_instance.unbound_pass_manager )[0] self._circuit_transpiled = True except QiskitError: # likely it is caused by RawFeatureVector, we just ignore this error and # transpile circuits when it is required. self._circuit_transpiled = False else: self._output_shape = output_shape
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("Aer doesn't appear to be installed. Error: '{}'".format(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 get_fidelity( circuit: QuantumCircuit, backend: Optional[Union[Backend, QuantumInstance]] = None, expectation: Optional[ExpectationBase] = None, ) -> Callable[[np.ndarray, np.ndarray], float]: r"""Get a function to compute the fidelity of ``circuit`` with itself. Let ``circuit`` be a parameterized quantum circuit performing the operation :math:`U(\theta)` given a set of parameters :math:`\theta`. Then this method returns a function to evaluate .. math:: F(\theta, \phi) = \big|\langle 0 | U^\dagger(\theta) U(\phi) |0\rangle \big|^2. The output of this function can be used as input for the ``fidelity`` to the :class:~`qiskit.algorithms.optimizers.QNSPSA` optimizer. Args: circuit: The circuit preparing the parameterized ansatz. backend: A backend of quantum instance to evaluate the circuits. If None, plain matrix multiplication will be used. expectation: An expectation converter to specify how the expected value is computed. If a shot-based readout is used this should be set to ``PauliExpectation``. Returns: A handle to the function :math:`F`. """ params_x = ParameterVector("x", circuit.num_parameters) params_y = ParameterVector("y", circuit.num_parameters) expression = ~StateFn(circuit.assign_parameters(params_x)) @ StateFn( circuit.assign_parameters(params_y)) if expectation is not None: expression = expectation.convert(expression) if backend is None: def fidelity(values_x, values_y): value_dict = dict( zip(params_x[:] + params_y[:], values_x.tolist() + values_y.tolist())) return np.abs(expression.bind_parameters(value_dict).eval())**2 else: sampler = CircuitSampler(backend) def fidelity(values_x, values_y): value_dict = dict( zip(params_x[:] + params_y[:], values_x.tolist() + values_y.tolist())) return np.abs( sampler.convert(expression, params=value_dict).eval())**2 return fidelity
def __init__(self, operator: OperatorBase, input_params: Optional[List[Parameter]] = None, weight_params: Optional[List[Parameter]] = None, exp_val: Optional[ExpectationBase] = None, gradient: Optional[Gradient] = None, quantum_instance: Optional[Union[QuantumInstance, BaseBackend, Backend]] = None): """Initializes the Opflow Quantum Neural Network. Args: operator: The parametrized operator that represents the neural network. input_params: The operator parameters that correspond to the input of the network. weight_params: The operator parameters that correspond to the trainable weights. exp_val: The Expected Value converter to be used for the operator. gradient: The Gradient converter to be used for the operator's backward pass. quantum_instance: The quantum instance to evaluate the network. """ self.operator = operator self.input_params = list(input_params or []) self.weight_params = list(weight_params or []) self.exp_val = exp_val # TODO: currently not used by Gradient! self.gradient = gradient or Gradient() if isinstance(quantum_instance, (BaseBackend, Backend)): quantum_instance = QuantumInstance(quantum_instance) if quantum_instance: self.quantum_instance = quantum_instance self.circuit_sampler = CircuitSampler( self.quantum_instance, param_qobj=is_aer_provider(self.quantum_instance.backend) ) # TODO: replace by extended caching in circuit sampler after merged: "caching='all'" self.gradient_sampler = deepcopy(self.circuit_sampler) else: self.quantum_instance = None self.circuit_sampler = None self.gradient_sampler = None self.forward_operator = self.exp_val.convert(operator) if exp_val else operator self.gradient_operator = self.gradient.convert(operator, self.input_params + self.weight_params) output_shape = self._get_output_shape_from_op(operator) super().__init__(len(self.input_params), len(self.weight_params), sparse=False, output_shape=output_shape)
def test_is_measurement_correctly_propagated(self): """Test if is_measurement property of StateFn is propagated to converted StateFn.""" 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 backend = Aer.get_backend("aer_simulator") q_instance = QuantumInstance(backend) # no seeds needed since no values are compared state = Plus sampler = CircuitSampler(q_instance).convert(~state @ state) self.assertTrue(sampler.oplist[0].is_measurement)
def test_coefficients_correctly_propagated(self): """Test that the coefficients in SummedOp and states are correctly used.""" 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 with self.subTest('zero coeff in SummedOp'): op = 0 * (I + Z) state = Plus self.assertEqual((~StateFn(op) @ state).eval(), 0j) backend = Aer.get_backend('qasm_simulator') q_instance = QuantumInstance(backend, seed_simulator=97, seed_transpiler=97) op = I with self.subTest('zero coeff in summed StateFn and CircuitSampler'): state = 0 * (Plus + Minus) sampler = CircuitSampler(q_instance).convert(~StateFn(op) @ state) self.assertEqual(sampler.eval(), 0j) with self.subTest( 'coeff gets squared in CircuitSampler shot-based readout'): state = (Plus + Minus) / numpy.sqrt(2) sampler = CircuitSampler(q_instance).convert(~StateFn(op) @ state) self.assertAlmostEqual(sampler.eval(), 1 + 0j)
def __init__( self, epsilon: float = 1e-2, expectation: Optional[ExpectationBase] = None, quantum_instance: Optional[Union[Backend, BaseBackend, QuantumInstance]] = None, ) -> None: r""" Args: epsilon: Error tolerance of the approximation to the solution, i.e. if :math:`x` is the exact solution and :math:`\tilde{x}` the one calculated by the algorithm, then :math:`||x - \tilde{x}|| \le epsilon`. expectation: The expectation converter applied to the expectation values before evaluation. If None then PauliExpectation is used. quantum_instance: Quantum Instance or Backend. If None, a Statevector calculation is done. """ super().__init__() self._epsilon = epsilon # Tolerance for the different parts of the algorithm as per [1] self._epsilon_r = epsilon / 3 # conditioned rotation self._epsilon_s = epsilon / 3 # state preparation self._epsilon_a = epsilon / 6 # hamiltonian simulation self._scaling = None # scaling of the solution if quantum_instance is not None: self._sampler = CircuitSampler(quantum_instance) else: self._sampler = None self._expectation = expectation # For now the default reciprocal implementation is exact self._exact_reciprocal = True # Set the default scaling to 1 self.scaling = 1
def _eval_aux_ops( self, parameters: np.ndarray, aux_operators: ListOrDict[OperatorBase], expectation: ExpectationBase, threshold: float = 1e-12, ) -> ListOrDict[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))) values = np.real(sampler.convert(aux_op_expect).eval()) # Discard values below threshold aux_op_results = values * (np.abs(values) > threshold) # 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
def quantum_instance( self, quantum_instance: Optional[Union[QuantumInstance, Backend]]) -> None: """ Sets a quantum instance and a circuit sampler. Args: quantum_instance: The quantum instance used to run this algorithm. """ if isinstance(quantum_instance, Backend): quantum_instance = QuantumInstance(quantum_instance) self._circuit_sampler = None if quantum_instance is not None: self._circuit_sampler = CircuitSampler(quantum_instance) self._quantum_instance = quantum_instance