Commit cb585a05 authored by Nguyen, Thien Minh's avatar Nguyen, Thien Minh
Browse files

added modular adder



Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent 2c1eb073
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -6,6 +6,12 @@ __qpu__ void test_add_integer(qreg q) {
  Measure(q);
}

__qpu__ void test_add_integer_mod(qreg q, qubit anc) {
  H(q[2]); // |000> + |001>
  add_integer_mod(q, anc, 3, 5); // |3 mod 5> and |7 mod 5>
  Measure(q);
  Measure(anc);
}

int main(int argc, char **argv) {
  set_shots(1024);
@@ -19,5 +25,18 @@ int main(int argc, char **argv) {
  qcor_expect(a.counts()["111"] > 400);
  qcor_expect(a.counts()["110"] > 400);

  // Test modular add
  auto b = qalloc(3);
  auto anc = qalloc(1);
  test_add_integer_mod::print_kernel(b, anc[0]);
  test_add_integer_mod(b, anc[0]);
  // |3 mod 5> and |7 mod 5> == |2> + |3>
  b.print();
  qcor_expect(b.counts().size() == 2);
  qcor_expect(b.counts()["110"] > 400);
  qcor_expect(b.counts()["010"] > 400);
  anc.print();
  // anc returns to 0
  qcor_expect(anc.counts()["0"] == 1024);
  return 0;
}
 No newline at end of file
+32 −1
Original line number Diff line number Diff line
@@ -83,3 +83,34 @@ __qpu__ void add_integer(qreg q, int a) {
  compute { qft_opt_swap(q, 0); }
  action { phase_add_integer(q, a); }
}

// + a mod N in phase space
// need an additional ancilla qubit since we don't do allocation
// inside a kernel.
// See Fig. 5 of https://arxiv.org/pdf/quant-ph/0205095.pdf
__qpu__ void phase_add_integer_mod(qreg q, qubit anc, int a, int N) {
  Reset(anc);
  phase_add_integer(q, a);
  phase_add_integer::adjoint(q, N);
  qft_opt_swap::adjoint(q, 0);
  X::ctrl(q.tail(), anc);
  qft_opt_swap(q, 0);
  phase_add_integer::ctrl(anc, q, N);
  phase_add_integer::adjoint(q, a);
  qft_opt_swap::adjoint(q, 0);
  X(q.tail());
  X::ctrl(q.tail(), anc);
  X(q.tail());
  qft_opt_swap(q, 0);
  phase_add_integer(q, a);
}

// Add an integer a mod N to the a qubit register:
// |q> --> |q + a mod N>
// TODO: ability to create scratch qubits
__qpu__ void add_integer_mod(qreg q, qubit anc, int a, int N) {
  // Bring it to Fourier basis
  // (IQFT automatically)
  compute { qft_opt_swap(q, 0); }
  action { phase_add_integer_mod(q, anc, a, N); }
}