QCOR
vqe.hpp
1 #pragma once
2 
3 #include <qcor_common>
4 #include <vector>
5 
6 #include "qcor_observable.hpp"
7 
8 #ifdef _QCOR_FTQC_RUNTIME
9 namespace ftqc {
10 __qpu__ void estimate_term_expectation(
11  qreg q, const std::function<void(qreg)> &statePrep,
12  std::vector<qcor::Operator> bases, int nSamples, double &out_energy) {
13  double sum = 0.0;
14  for (int i = 0; i < nSamples; ++i) {
15  statePrep(q);
16  int parity = 0;
17  measure_basis(q, bases, parity);
18  if (parity == 1) {
19  sum = sum - 1.0;
20  } else {
21  sum = sum + 1.0;
22  }
23  reset_all(q);
24  }
25  out_energy = sum / nSamples;
26 }
27 
28 // Estimates the energy of a Pauli observable by summing the energy contributed
29 // by the individual terms. Input:
30 // - observable
31 // The Pauli Hamiltonian.
32 // - nSamples
33 // The number of samples to use for the estimation of the term expectations.
34 //
35 // Output
36 // The estimated energy of the observable
37 __qpu__ void estimate_energy(qreg q, const std::function<void(qreg)> &statePrep,
38  qcor::Operator observable, int nSamples,
39  double &out_energy) {
40  std::complex<double> energy = observable.hasIdentitySubTerm() ? observable.getIdentitySubTerm().coefficient().real() : 0.0;
41  for (auto pauliInst : observable.getNonIdentitySubTerms()) {
42  auto coeff = pauliInst.coefficient().real();
43  auto [zv, xv] = pauliInst.toBinaryVectors(q.size());
44  std::vector<qcor::Operator> ops;
45  for (auto [i, x_val] : enumerate(xv)) {
46  auto z_val = zv[i];
47  if (x_val == z_val) {
48  // Y(q[i]);
49  ops.emplace_back(qcor::Y(i));
50  } else if (x_val == 0) {
51  // Z(q[i]);
52  ops.emplace_back(qcor::Z(i));
53 
54  } else {
55  // X(q[i]);
56  ops.emplace_back(qcor::X(i));
57  }
58  }
59  if (!ops.empty()) {
60  double termEnergy = 0.0;
61  estimate_term_expectation(q, statePrep, ops, nSamples, termEnergy);
62  energy = energy + (coeff * termEnergy);
63  } else {
64  // Identity term:
65  energy = energy + coeff;
66  }
67  }
68  out_energy = energy.real();
69 }
70 } // namespace ftqc
71 #endif
qcor::Operator
Definition: qcor_observable.hpp:24