5

Like the title says, how to realize the Grover's Diffusion Operator in Q#? I know it's defined as 2 ⟨s|s⟩ - I where |s⟩ is the uniform state for any arbitrary number of qubits. This can further be defined in terms of Z0 (saw it called U0) gate sandwiched by a pair of H-gates. I was unable to find any function in the quantum primitive and canon docs starting with possible names like Grover, diff etc.

I don't want to use the function AmpAmpByOracle since it is very high level implementation and doesn't clear my understanding. I want to implement a function that takes a oracle Uf(unknown to me suppose) and the number of qubit it takes(N) and perform the Grover's algorithm by simply following the circuit given in Grover's Algorithm | Wikipedia and measure the required state by measuring all the N qubits at the end of r = approx(2^(N/2)) iterations.

Chris Granade
  • 913
  • 7
  • 21

1 Answers1

4

The diffusion operation is a bit tricky. I find it easiest to decompose it into pieces:

  1. As you point out, it's much simpler to look at the diffusion operation in the X basis. If you apply H to every qubit before and after, then in the middle the uniform state looks like the 000...0 state.
  2. The diffusion operation (in the X basis) is -1 on the 000...0 state, and the identity (+1) on all other basis states. The first step is to pick out the 000...0 state; I can do that with a multi-controlled X gate -- except I need to flip all of the qubits first from 0 to 1 (and vice versa), since controlled operations look for 1s, not 0s. Of course, after the controlled X I'll need to undo the flips.
  3. To generate the -1, I can start with the ancilla in the |-> state, so that the X will turn it into -|->.
  4. After I'm done with everything, I need to reset the ancilla so I can return it in the |0> state.

This all turns into:

// register is the Qubit[] that we want to apply the diffusion operation to
using (ancillae = Qubit[1])
{
  let ancilla = ancillae[0];

  X(ancilla); // Puts the ancilla into the |1> state
  H(ancilla); // And now into the |-> state

  ApplyToEach(H, register);  // Put the register qubits into the X basis
  ApplyToEach(X, register);  // Flip 0->1 and 1->0
  (Controlled X)(register, ancilla);  // Do the controlled flip of the ancilla
  ApplyToEach(X, register);  // Undo the flip
  ApplyToEach(H, register);  // Undo the basis change

  H(ancilla); // Put the ancilla back into |1>
  X(ancilla); // And back to |0> so we can return it
}

This is uncompiled code, so there might be some typos...

Alan Geller
  • 494
  • 2
  • 5
  • 1
    Just to elaborate slightly on @Alan's solution, it's common in quantum programming and Q# in particular to have patterns where you transform a register by , apply an operation, then undo the . Here, for instance, you could write out much of the body as `WithCA(ApplyToEachCA(BindCA([H; X]), _), (Controlled X)(_, ancilla), register)`, as a formalization of that kind of pattern. – Chris Granade Aug 08 '18 at 17:26