-
Notifications
You must be signed in to change notification settings - Fork 1.2k
quantum counting algorithm #168
base: main
Are you sure you want to change the base?
Conversation
It's fine to start with just a Q# project for now, and polish the Notebook later - depending on what exactly you do in the testing harness it might be a bit tricky, and it is usually easier to convert the final versions of the tasks to Notebook format than to update both presentations at each review iteration. I'll take a closer look a bit later - I didn't expect that you have the kata ready, and I'm a bit busy today. Sorry about the delay, and thank you for the PR! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The most interesting thing about quantum counting is that it can be used to find the approximate number of solutions to the problem (which then can be used to decide on the number of iterations to use in Grover search). The exact counting tales a lot of oracle calls (I'll need to do the math carefully but I think it's O(N) calls, so it's not an improvement over classical counting). I don't have a good reference for this at the moment, sorry, I'll try to find one and post it here.
If you want to keep developing this kata, this should be the direction to take it.
Sorry for the delay reviewing this PR!
Counting/ReferenceImplementation.qs
Outdated
|
||
|
||
// The Grover iteration | ||
operation GroverIteration (register : Qubit[], oracle : (Qubit[] => Unit is Adj+Ctl)) : Unit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You might want to use a more concise version of Grover iteration, similar to the one used here. The version from GroversAlgorithm kata is split into a lot of pieces for the purposes of making it into a kata, if you just need the iteration and the oracle conversion you can make it much shorter.
Counting/Tasks.qs
Outdated
// - GroverIteration for the Grover operator | ||
// - QuantumPhaseEstimation, for estimating the phase | ||
// Counting should return the number of models, 4 in this case | ||
operation Counting() : Double { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll want to teach the learner to implement a general-case quantum counting, not specific to one oracle instance. For that we'll need to pass the oracle and the problem size to the task as a parameter, otherwise a lot of things can be hardcoded. You can see this tutorial as an example.
Counting/Tests.qs
Outdated
operation T21_Counting_Test () : Unit { | ||
let reference=Counting(); | ||
let actual=4.0; | ||
EqualityWithinToleranceFact(reference,actual,3.0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to the previous comment, you'll need to adjust the test to check the results on multiple oracles and input sizes. I found it easiest to use an oracle which just marks the first M out of N inputs as answers - it is not a very interesting oracle per se, but in the tasks in which we just care about the number of solutions to the problem it is a nice fast option (faster than, say, using an oracle that encodes a SAT problem).
operation Oracle_SolutionCount (queryRegister : Qubit[], target : Qubit, nSol : Int) : Unit is Adj {
// Designate first nSol integers solutions (since we don't really care which ones are solutions)
for (i in 0 .. nSol - 1) {
(ControlledOnInt(i, X))(queryRegister, target);
}
}
You'll also need to account for the fact that phase estimation is a probabilistic algorithm, so quantum counting fails with certain probability - you need to either modify the test harness to run the learner's solution multiple times or to stress in the task description that the solution has to take care of that.
Counting/Tasks.qs
Outdated
// Hint: to solve this task you also need to use ancilla qubits | ||
// This formula has 4 models out of 8 possible worlds | ||
|
||
operation Oracle_Sprinkler (queryRegister : Qubit[], target : Qubit, ancilla : Qubit[]) : Unit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ancilla qubits are typically allocated inside the oracle operation and deallocated after their role in the computation is over; it will be better for this oracle to have just queryRegister
and target
as inputs and to handle ancilla qubits inside the operation. (In this case it is also possible to implement the oracle without using the ancillae by hardcoding the solutions, so it should be up to the learner to choose the implementation)
@tcNickolas the complexity of quantum counting is O(sqrt(N)), see the Nilsson Cheung book. |
Hi @tcNickolas,
but I get this error
Line 61 is the following
in |
I found the problem. |
Hi @tcNickolas |
The problem is the number of solutions found is 2^N-n_sol instead of n_sol |
3 tests with different number of solutions: 16, 20, 40
Hi, the kata now works but I had to add a global phase
to |
@tcNickolas I'm submitting a pull request for quantum counting. Haven't yet had tim to do the jupyther notebook