def test_paulisum_validation(): q = cirq.LineQubit.range(2) pstr1 = cirq.X(q[0]) * cirq.X(q[1]) pstr2 = cirq.Y(q[0]) * cirq.Y(q[1]) with pytest.raises(ValueError) as e: cirq.PauliSum([pstr1, pstr2]) assert e.match("Consider using") with pytest.raises(ValueError): ld = cirq.LinearDict({pstr1: 2.0}) cirq.PauliSum(ld) with pytest.raises(ValueError): key = frozenset([('q0', cirq.X)]) ld = cirq.LinearDict({key: 2.0}) cirq.PauliSum(ld) with pytest.raises(ValueError): key = frozenset([(q[0], cirq.H)]) ld = cirq.LinearDict({key: 2.0}) cirq.PauliSum(ld) key = frozenset([(q[0], cirq.X)]) ld = cirq.LinearDict({key: 2.0}) assert (cirq.PauliSum(ld) == cirq.PauliSum.from_pauli_strings( [2 * cirq.X(q[0])]))
def expval(self, observable, shot_range=None, bin_size=None): # pylint: disable=missing-function-docstring # Analytic mode if self.shots is None: if not isinstance(observable, qml.operation.Tensor): # Observable on a single wire # Projector, Hermitian if self._observable_map[ observable. name] is None or observable.name == "Projector": return super().expval(observable, shot_range, bin_size) if observable.name == "Hadamard": circuit = self.circuit obs = cirq.PauliSum() + self.to_paulistring( qml.PauliZ(wires=observable.wires)) else: circuit = self.pre_rotated_circuit obs = cirq.PauliSum() + self.to_paulistring(observable) # Observables are in tensor form else: # Projector, Hamiltonian, Hermitian for name in observable.name: if self._observable_map[ name] is None or name == "Projector": return super().expval(observable, shot_range, bin_size) if "Hadamard" in observable.name: list_obs = [] for obs in observable.obs: list_obs.append(qml.PauliZ(wires=obs.wires)) T = qml.operation.Tensor(*list_obs) circuit = self.circuit obs = cirq.PauliSum() + self.to_paulistring(T) else: circuit = self.pre_rotated_circuit obs = cirq.PauliSum() + self.to_paulistring(observable) return self._simulator.simulate_expectation_values( program=circuit, observables=obs, initial_state=self._initial_state, )[0].real # Shots mode samples = self.sample(observable, shot_range=shot_range, bin_size=bin_size) return np.squeeze(np.mean(samples, axis=0))
def qubitop_to_paulisum( qubit_operator: QubitOperator, qubits: Union[List[cirq.GridQubit], List[cirq.LineQubit]] = None, ) -> cirq.PauliSum: """Convert and openfermion QubitOperator to a cirq PauliSum Args: qubit_operator (openfermion.QubitOperator): The openfermion operator to convert qubits() Returns: cirq.PauliSum """ operator_map = {"X": cirq.X, "Y": cirq.Y, "Z": cirq.Z} if qubits is None: qubits = [cirq.GridQubit(i, 0) for i in range(count_qubits(qubit_operator))] converted_sum = cirq.PauliSum() for term, coefficient in qubit_operator.terms.items(): # Identity term if len(term) == 0: converted_sum += coefficient continue cirq_term = cirq.PauliString() for qubit_index, operator in term: cirq_term *= operator_map[operator](qubits[qubit_index]) converted_sum += cirq_term * coefficient return converted_sum
def expval(self, observable): # pylint: disable=missing-function-docstring if not hasattr(self._simulator, "simulate_expectation_values"): return super().expval(observable) return self._simulator.simulate_expectation_values( self.circuit, cirq.PauliSum() + self.to_paulistring(observable) )[0]
def deserialize_paulisum(proto): """Constructs a `cirq.PauliSum` from pauli_sum proto. Args: proto: A pauli_sum proto object. Returns: A `cirq.PauliSum` object. """ if not isinstance(proto, pauli_sum_pb2.PauliSum): raise TypeError("deserialize requires a pauli_sum_pb2 object." " Given: " + str(type(proto))) res = cirq.PauliSum() for term_proto in proto.terms: coef = float(_round(term_proto.coefficient_real)) + \ 1.0j * float(_round(term_proto.coefficient_imag)) term = coef * cirq.PauliString() for pauli_qubit_pair in term_proto.paulis: op = _process_pauli_type(pauli_qubit_pair.pauli_type) term *= op( op_deserializer.qubit_from_proto(pauli_qubit_pair.qubit_id)) res += term return res
def qubit_operator_to_pauli_sum( operator: QubitOperator, qubits: Optional[Sequence[cirq.Qid]] = None) -> cirq.PauliSum: """ Convert QubitOperator to a sum of PauliString. Args: operator (QubitOperator): operator to convert. qubits (List): Optional list of qubit names. If `None` a list of `cirq.LineQubit` of length number of qubits in operator is created. Returns: pauli_sum (PauliSum): cirq PauliSum object. Raises: TypeError: if qubit_op is not a QubitOpertor. """ if not isinstance(operator, QubitOperator): raise TypeError('Input must be a QubitOperator.') if qubits is None: qubits = cirq.LineQubit.range(count_qubits(operator)) pauli_sum = cirq.PauliSum() for pauli in operator.terms.items(): pauli_sum += _qubit_operator_term_to_pauli_string(pauli, qubits) return pauli_sum
def test_pauli_sum_construction(): q = cirq.LineQubit.range(2) pstr1 = cirq.X(q[0]) * cirq.X(q[1]) pstr2 = cirq.Y(q[0]) * cirq.Y(q[1]) psum = pstr1 + pstr2 assert psum # should be truthy assert list(psum) == [pstr1, pstr2] psum2 = cirq.PauliSum.from_pauli_strings([pstr1, pstr2]) assert psum == psum2 zero = cirq.PauliSum() assert len(zero) == 0
def test_pauli_string_sample_collector_identity(): p = cirq.PauliSumCollector(circuit=cirq.Circuit(), observable=cirq.PauliSum() + 2j, samples_per_term=100) p.collect(sampler=cirq.Simulator()) assert p.estimated_energy() == 2j