Commit 1966b002 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

adding QuantumKernel::observe

parent 5fd52bb0
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -18,7 +18,9 @@ H = FOp('', 0.0002899) + FOp('0^ 0', -.43658) + \
n_params = 1
obj = createObjectiveFunction(ansatz, H, n_params)

# Run full optimization
# Create the COBYLA Optimizer
optimizer = createOptimizer('nlopt')

# Run the full optimization
results = optimizer.optimize(obj)
print(results)
 No newline at end of file
+48 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@

#include "qcor_utils.hpp"
#include "qrt.hpp"
#include "qcor_observable.hpp"

namespace qcor {
enum class QrtType { NISQ, FTQC };
@@ -213,6 +214,53 @@ class QuantumKernel {
    return visitor.getMat();
  }

  static double observe(Observable& obs, Args... args) {
    // instantiate and don't let it call the destructor
    Derived derived(args...);
    derived.disable_destructor = true;

    // run the operator()(args...) call to get the the functor
    // as a CompositeInstruction (derived.parent_kernel)
    derived(args...);

    auto instructions = derived.parent_kernel->getInstructions();
    // Assert that we don't have measurement
    if (!std::all_of(
            instructions.cbegin(), instructions.cend(),
            [](const auto &inst) { return inst->name() != "Measure"; })) {
      error(
          "Unable to observe kernels that already have Measure operations.");
    }

    // Will fail to compile if more than one qreg is passed.
    std::tuple<Args...> tmp(std::forward_as_tuple(args...));
    auto q = std::get<qreg>(tmp);
    return qcor::observe(derived.parent_kernel, obs, q);
  }

  static double observe(std::shared_ptr<Observable> obs, Args... args) {
    // instantiate and don't let it call the destructor
    Derived derived(args...);
    derived.disable_destructor = true;

    // run the operator()(args...) call to get the the functor
    // as a CompositeInstruction (derived.parent_kernel)
    derived(args...);

    auto instructions = derived.parent_kernel->getInstructions();
    // Assert that we don't have measurement
    if (!std::all_of(
            instructions.cbegin(), instructions.cend(),
            [](const auto &inst) { return inst->name() != "Measure"; })) {
      error(
          "Unable to observe kernels that already have Measure operations.");
    }

    // Will fail to compile if more than one qreg is passed.
    std::tuple<Args...> tmp(std::forward_as_tuple(args...));
    auto q = std::get<qreg>(tmp);
    return qcor::observe(derived.parent_kernel, obs, q);
  }
  virtual ~QuantumKernel() {}
};

+7 −5
Original line number Diff line number Diff line
@@ -48,8 +48,9 @@ auto observe(void (*quantum_kernel_functor)(
  // all quantum instructions to the parent kernel
  quantum_kernel_functor(program, args...);
  return [program, obs](Args... args) {
    // Get the first argument, which should be a qreg
    auto q = std::get<0>(std::forward_as_tuple(args...));
    // Get qreg arg, will fail if more than one
    std::tuple<Args...> tmp(std::forward_as_tuple(args...));
    auto q = std::get<qreg>(tmp);

    // Observe the program
    auto programs = obs->observe(program);
@@ -76,8 +77,9 @@ auto observe(void (*quantum_kernel_functor)(
  // all quantum instructions to the parent kernel
  quantum_kernel_functor(program, args...);
  return [program, &obs](Args... args) {
    // Get the first argument, which should be a qreg
    auto q = std::get<0>(std::forward_as_tuple(args...));
    // Get the qreg argument. will fail if more than 1 passed
    std::tuple<Args...> tmp(std::forward_as_tuple(args...));
    auto q = std::get<qreg>(tmp);
    
    // Observe the program
    auto programs = obs.observe(program);