Commit afccb2df authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

adding as_unitary_matrix() to c++ QuantumKernel

parent 89528309
Loading
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line

__qpu__ void ansatz(qreg q, double x) {
  X(q[0]);
  Ry(q[1], x);
  CX(q[1], q[0]);
}

int main() {
  auto q = qalloc(2);

  // Map the ansatz to a unitary matrix
  UnitaryMatrix u_mat = ansatz::as_unitary_matrix(q, .59);

  // Create the Hamiltonian, map to a DenseMatrix (complex values)
  auto H = -2.1433 * X(0) * X(1) - 2.1433 * Y(0) * Y(1) + .21829 * Z(0) -
           6.125 * Z(1) + 5.907;
  DenseMatrix Hmat = get_dense_matrix(H);

  // Create the initial |0> state
  DenseVector init_state = DenseVector::Zero(4);
  init_state(0) = 1.;

  // Compute |psi> = U |0>
  DenseVector final_state = u_mat * init_state;

  // Compute the energy E = <psi | H | psi>
  std::complex<double> energy = final_state.transpose() * Hmat * final_state;
  std::cout << energy.real() << "\n";
}
+23 −7
Original line number Diff line number Diff line
@@ -30,7 +30,8 @@ enum class QrtType { NISQ, FTQC };
// with an appropriate implementation of constructors and destructors.
// Users can then call for adjoint/ctrl methods like this
// foo::adjoint(q); foo::ctrl(1, q);
template <typename Derived, typename... Args> class QuantumKernel {
template <typename Derived, typename... Args>
class QuantumKernel {
 protected:
  // Tuple holder for variadic kernel arguments
  std::tuple<Args...> args_tuple;
@@ -63,7 +64,8 @@ public:
  QuantumKernel(std::shared_ptr<qcor::CompositeInstruction> _parent_kernel,
                Args... args)
      : args_tuple(std::forward_as_tuple(args...)),
        parent_kernel(_parent_kernel), is_callable(false) {
        parent_kernel(_parent_kernel),
        is_callable(false) {
    runtime_env = (__qrt_env == "ftqc") ? QrtType::FTQC : QrtType::NISQ;
  }

@@ -87,7 +89,6 @@ public:
  // Create the Adjoint of this quantum kernel
  static void adjoint(std::shared_ptr<CompositeInstruction> parent_kernel,
                      Args... args) {

    // instantiate and don't let it call the destructor
    Derived derived(args...);
    derived.disable_destructor = true;
@@ -170,7 +171,6 @@ public:
  // Create the controlled version of this quantum kernel
  static void ctrl(std::shared_ptr<CompositeInstruction> parent_kernel,
                   qubit ctrl_qbit, Args... args) {

    int ctrl_bit = (int)ctrl_qbit.second;

    // instantiate and don't let it call the destructor
@@ -197,6 +197,22 @@ public:
    // Need to reset and point current program to the parent
    quantum::set_current_program(parent_kernel);
  }

  static Eigen::MatrixXcd as_unitary_matrix(Args... args) {
    Derived derived(args...);
    derived.disable_destructor = true;
    derived(args...);
    qcor::KernelToUnitaryVisitor visitor(derived.parent_kernel->nLogicalBits());
    xacc::InstructionIterator iter(derived.parent_kernel);
    while (iter.hasNext()) {
      auto inst = iter.next();
      if (!inst->isComposite() && inst->isEnabled()) {
        inst->accept(&visitor);
      }
    }
    return visitor.getMat();
  }

  virtual ~QuantumKernel() {}
};

+21 −0
Original line number Diff line number Diff line
@@ -48,6 +48,27 @@ PauliOperator SM(int idx) {
  std::complex<double> imag(0.0, 1.0);
  return X(idx) - imag * Y(idx);
}

Eigen::MatrixXcd get_dense_matrix(PauliOperator &op) {
  auto mat_el = op.to_sparse_matrix();
  auto size = std::pow(2, op.nBits());
  Eigen::MatrixXcd mat = Eigen::MatrixXcd::Zero(size, size);
  for (auto el : mat_el) {
    mat(el.row(), el.col()) = el.coeff();
  }
  return mat;
}

Eigen::MatrixXcd get_dense_matrix(std::shared_ptr<Observable> op) {
  auto mat_el = op->to_sparse_matrix();
  auto size = std::pow(2, op->nBits());
  Eigen::MatrixXcd mat = Eigen::MatrixXcd::Zero(size, size);
  for (auto el : mat_el) {
    mat(el.row(), el.col()) = el.coeff();
  }
  return mat;
}

std::shared_ptr<xacc::Observable> createObservable(const std::string &repr) {
  if (!xacc::isInitialized())
    xacc::internal_compiler::compiler_InitializeXACC();
+4 −0
Original line number Diff line number Diff line
@@ -30,6 +30,10 @@ PauliOperator operator+(PauliOperator &op, double coeff);
PauliOperator operator-(double coeff, PauliOperator &op);
PauliOperator operator-(PauliOperator &op, double coeff);


Eigen::MatrixXcd get_dense_matrix(PauliOperator &op);
Eigen::MatrixXcd get_dense_matrix(std::shared_ptr<Observable> op);

// Public observe function, returns expected value of Observable
template <typename... Args>
auto observe(void (*quantum_kernel_functor)(
+1 −0
Original line number Diff line number Diff line
@@ -99,6 +99,7 @@ std::shared_ptr<qcor::CompositeInstruction> decompose_unitary(
}

}  // namespace __internal__

using namespace xacc::quantum;

MatrixXcd X_Mat{MatrixXcd::Zero(2, 2)};
Loading