Loading python/py-qcor.cpp +34 −2 Original line number Diff line number Diff line Loading @@ -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)) { Loading @@ -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)) { Loading @@ -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."); Loading Loading @@ -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: { Loading python/tests/test_qcor_spec_api.py +44 −2 Original line number Diff line number Diff line Loading @@ -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') Loading Loading
python/py-qcor.cpp +34 −2 Original line number Diff line number Diff line Loading @@ -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)) { Loading @@ -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)) { Loading @@ -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."); Loading Loading @@ -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: { Loading
python/tests/test_qcor_spec_api.py +44 −2 Original line number Diff line number Diff line Loading @@ -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') Loading