def get_pauli_expectation_value(self, state_circuit: Circuit, pauli: QubitPauliString) -> complex: """Calculates the expectation value of the given circuit using the built-in QVM functionality :param state_circuit: Circuit that generates the desired state :math:`\\left|\\psi\\right>`. :type state_circuit: Circuit :param pauli: Pauli operator :type pauli: QubitPauliString :return: :math:`\\left<\\psi | P | \\psi \\right>` :rtype: complex """ prog = tk_to_pyquil(state_circuit) pauli_term = self._gen_PauliTerm(pauli) return complex(self._sim.expectation(prog, [pauli_term]))
def get_operator_expectation_value( self, state_circuit: Circuit, operator: QubitPauliOperator) -> complex: """Calculates the expectation value of the given circuit with respect to the operator using the built-in QVM functionality :param state_circuit: Circuit that generates the desired state :math:`\\left|\\psi\\right>`. :type state_circuit: Circuit :param operator: Operator :math:`H`. :type operator: QubitPauliOperator :return: :math:`\\left<\\psi | H | \\psi \\right>` :rtype: complex """ prog = tk_to_pyquil(state_circuit) pauli_sum = PauliSum([ self._gen_PauliTerm(term, coeff) for term, coeff in operator._dict.items() ]) return complex(self._sim.expectation(prog, pauli_sum))
def process_circuits( self, circuits: Iterable[Circuit], n_shots: Optional[int] = None, valid_check: bool = True, **kwargs: KwargTypes, ) -> List[ResultHandle]: """ See :py:meth:`pytket.backends.Backend.process_circuits`. Supported kwargs: `seed`. """ if n_shots is None or n_shots < 1: raise ValueError( "Parameter n_shots is required for this backend for ForestBackend" ) if valid_check: self._check_all_circuits(circuits) handle_list = [] for circuit in circuits: p, bits = tk_to_pyquil(circuit, return_used_bits=True) p.wrap_in_numshots_loop(n_shots) ex = self._qc.compiler.native_quil_to_executable(p) qam = copy(self._qc.qam) qam.load(ex) qam.random_seed = kwargs.get("seed") # type: ignore qam.run() handle = ResultHandle(uuid4().int) measures = circuit.n_gates_of_type(OpType.Measure) if measures == 0: self._cache[handle] = { "qam": qam, "c_bits": sorted(bits), "result": self.empty_result(circuit, n_shots=n_shots), } else: self._cache[handle] = {"qam": qam, "c_bits": sorted(bits)} handle_list.append(handle) return handle_list
def process_circuits( self, circuits: Iterable[Circuit], n_shots: Optional[int] = None, valid_check: bool = True, **kwargs: KwargTypes, ) -> List[ResultHandle]: handle_list = [] if valid_check: self._check_all_circuits(circuits) for circuit in circuits: p = tk_to_pyquil(circuit) for qb in circuit.qubits: # Qubits with no gates will not be included in the Program # Add identities to ensure all qubits are present and dimension # is as expected p += I(Qubit_(qb.index[0])) handle = ResultHandle(uuid4().int) state = np.array(self._sim.wavefunction(p).amplitudes) try: phase = float(circuit.phase) coeff = np.exp(phase * np.pi * 1j) state *= coeff except ValueError: warning( "Global phase is dependent on a symbolic parameter, so cannot " "adjust for phase") implicit_perm = circuit.implicit_qubit_permutation() res_qubits = [ implicit_perm[qb] for qb in sorted(circuit.qubits, reverse=True) ] res = BackendResult(q_bits=res_qubits, state=state) self._cache[handle] = {"result": res} handle_list.append(handle) return handle_list