Loading examples/arithmetic/integer_add.cpp +19 −0 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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 lib/impl/integer_arithmetic.hpp +32 −1 Original line number Diff line number Diff line Loading @@ -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); } } Loading
examples/arithmetic/integer_add.cpp +19 −0 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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
lib/impl/integer_arithmetic.hpp +32 −1 Original line number Diff line number Diff line Loading @@ -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); } }