Commit 7130a00a authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

adding openfermion to qcor observe() api

parent d252f2c7
Loading
Loading
Loading
Loading
Loading
+34 −2
Original line number Diff line number Diff line
@@ -113,7 +113,18 @@ std::shared_ptr<qcor::Observable> convertToPauliOperator(py::object op) {
          }
        } else {
          // this was identity
          ss << terms[term].cast<double>();
          try {
            auto coeff = terms[term].cast<double>();
            ss << coeff;
          } catch (std::exception &e) {
            try {
              auto coeff = terms[term].cast<std::complex<double>>();
              ss << coeff;
            } catch (std::exception &e) {
              qcor::error(
                  "Could not cast identity coefficient to double or complex.");
            }
          }
        }
        i++;
        if (i != py::len(terms)) {
@@ -139,7 +150,19 @@ std::shared_ptr<qcor::Observable> convertToPauliOperator(py::object op) {
          }
        } else {
          // this was identity
          ss << terms[term].cast<double>();

          try {
            auto coeff = terms[term].cast<double>();
            ss << coeff;
          } catch (std::exception &e) {
            try {
              auto coeff = terms[term].cast<std::complex<double>>();
              ss << coeff;
            } catch (std::exception &e) {
              qcor::error(
                  "Could not cast identity coefficient to double or complex.");
            }
          }
        }
        i++;
        if (i != py::len(terms)) {
@@ -150,6 +173,7 @@ std::shared_ptr<qcor::Observable> convertToPauliOperator(py::object op) {
    }
  } else {
    // throw an error
    std::cout << "THrowing an error\n";
    qcor::error(
        "Invalid python object passed as a QCOR Operator/Observable. "
        "Currently, we only accept OpenFermion datastructures.");
@@ -511,6 +535,14 @@ PYBIND11_MODULE(_pyqcor, m) {
        return qcor::observe(kernel, obs, q);
      },
      "");
  m.def(
      "internal_observe",
      [](std::shared_ptr<CompositeInstruction> kernel, py::object obs) {
        auto observable = convertToPauliOperator(obs);
        auto q = ::qalloc(observable->nBits());
        return qcor::observe(kernel, observable, q);
      },
      "");

  // qsim sub-module bindings:
  {
+44 −2
Original line number Diff line number Diff line
@@ -70,7 +70,49 @@ class TestQCORSpecAPI(unittest.TestCase):
        optimizer = createOptimizer('nlopt', {'nlopt-maxeval':20})
        opt_val, opt_params = optimizer.optimize(objective_function, 1)   
        self.assertAlmostEqual(opt_val, 0.0, places=1)
        self.assertAlmostEqual(opt_params[0], .5, places=1)

    def test_observe_openfermion(self):
        try:
            from openfermion.ops import FermionOperator as FOp
            from openfermion.ops import QubitOperator as QOp
            from openfermion.transforms import jordan_wigner

            H = FOp('', 0.0002899) + FOp('0^ 0', -.43658) + \
                FOp('1 0^', 4.2866) + FOp('1^ 0', -4.2866) + FOp('1^ 1', 12.25) 
            
            @qjit
            def ansatz(q : qreg, theta : float):
                X(q[0])
                Ry(q[1], theta)
                CX(q[1], q[0])
            
            target_energy = -1.74

            def objective_function(x):
                q = qalloc(2)
                energy = ansatz.observe(H, q, x[0])
                print(energy)
                return abs(target_energy - energy)

            optimizer = createOptimizer('nlopt', {'nlopt-maxeval':20})
            opt_val, opt_params = optimizer.optimize(objective_function, 1)   
            print(opt_val, opt_params)
            self.assertAlmostEqual(opt_val, 0.0, places=1)
 
            Hq = jordan_wigner(H)
            def objective_function2(x):
                q = qalloc(2)
                energy = ansatz.observe(Hq, q, x[0])
                print(energy)
                return abs(target_energy - energy)

            objective_function2([2.2])
            optimizer = createOptimizer('nlopt', {'nlopt-maxeval':20})
            opt_val, opt_params = optimizer.optimize(objective_function2, 1)   
            self.assertAlmostEqual(opt_val, 0.0, places=1)

        except:
            pass

    def test_operator(self):
        H = createOperator('-2.1433 X0X1 - 2.1433 Y0Y1 + .21829 Z0 - 6.125 Z1 + 5.907')