The "Phase Estimation" quantum kata is a series of exercises designed to teach you the basics of using phase estimation algorithms.
It covers the following topics:
Each task is wrapped in one operation preceded by the description of the task.
Your goal is to fill in the blank (marked with the // ...
comments)
with some Q# code that solves the task. To verify your answer, run the cell using Ctrl+Enter (⌘+Enter on macOS).
Within each section, tasks are given in approximate order of increasing difficulty; harder ones are marked with asterisks.
Inputs:
A qubit in the $|0\rangle$ state.
An integer state
indicating which eigenstate to prepare.
Goal:
Prepare one of the eigenstates of Z gate (which are the same as eigenstates of S or T gates):
eigenstate $|0\rangle$ if state = 0
, or eigenstate $|1\rangle$ if state = 1
.
%kata T11_Eigenstates_ZST
operation Eigenstates_ZST (q : Qubit, state : Int) : Unit is Adj {
// ...
}
Inputs:
A single-qubit unitary U.
A positive integer power
.
Output:
A single-qubit unitary equal to U raised to the given power.
%kata T12_UnitaryPower
function UnitaryPower (U : (Qubit => Unit is Adj + Ctl), power : Int) : (Qubit => Unit is Adj + Ctl) {
// ...
return ...;
}
Inputs:
A single-qubit unitary U.
A single-qubit state $|\psi\rangle$ represented by a unitary P such that $|\psi\rangle = P|0\rangle$
(i.e., applying the unitary P to state $|0\rangle$ prepares state $|\psi\rangle$).
Goal:
Assert that the given state is an eigenstate of the given unitary, i.e., do nothing if it is, and throw an exception if it is not.
Note that since this task requires you to throw an exception in some cases, its test consists of two parts:
- The first part of the test, executed when you run the cell containing the solution code, checks that your solution does not throw an exception if the given state is an eigenstate of the given unitary.
- The second part of the test is provided in the second code cell (operation
TestAssertIsEigenstate_False
). This operation runs your solution on several pairs of unitaries and states that are not the eigenstates of those unitaries, and thus it should throw an exception on each pair. To test this, run this operation as is using the%simulate
cell below it to test that your solution throws an exception for the first pair, then comment out the first line and run it again to test that your solution throws an exception for the second pair, and so on.
%kata TestAssertIsEigenstate_True
open Microsoft.Quantum.Diagnostics;
operation AssertIsEigenstate (U : Qubit => Unit, P : Qubit => Unit is Adj) : Unit {
// ...
}
operation TestAssertIsEigenstate_False () : Unit {
// Each of these lines runs your solution on a unitary and a state that is not its eigenstate.
// Run the code as is to test that your solution throws an exception for the first pair,
// then comment out the first line and run it again
// to test that your solution throws an exception for the second pair,
// and so on.
AssertIsEigenstate(Z, H);
AssertIsEigenstate(X, X);
AssertIsEigenstate(X, Z);
AssertIsEigenstate(Y, H);
AssertIsEigenstate(Y, X);
AssertIsEigenstate(Y, Z);
// Feel free to come up with your own tests as well!
}
%simulate TestAssertIsEigenstate_False
Inputs:
A single-qubit unitary U.
A single-qubit state $|\psi\rangle$ represented by a unitary P such that $|\psi\rangle = P|0\rangle$
(i.e., applying the unitary P to state $|0\rangle$ prepares state $|\psi\rangle$).
n
.Output:
The phase of the eigenvalue that corresponds to the eigenstate $|\psi\rangle$, with n
bits of precision.
The phase should be between 0.0 and 1.0.
%kata T14_QPE
operation QPE (U : (Qubit => Unit is Adj + Ctl), P : (Qubit => Unit is Adj), n : Int) : Double {
// ...
}
Goal: Use your QPE implementation from task 1.4 to run quantum phase estimation on several simple unitaries and their eigenstates. This task is not covered by a test and allows you to experiment with running the algorithm.
This is an open-ended task, and is not covered by a unit test. To run the code, execute the cell with the definition of the
Run_QPE
operation first; if it compiled successfully without any errors, you can run the operation by executing the next cell (%simulate Run_QPE
).
operation Run_QPE () : Unit {
// ...
}
%simulate Run_QPE
Unlike quantum phase estimation, which is a single algorithm, iterative phase estimation is a whole class of algorithms based on the same idea: treating phase estimation as a classical algorithm which learns the phase via a sequence of measurements (the measurement performed on each iteration can depend on the outcomes of previous iterations).
A typical circuit for one iteration has the following structure:
($\psi$ is the procedure to prepare the eigenstate $|\psi\rangle$, R is a rotation gate, and M is a power of the unitary U; both depend on the current information about the phase).
The result of the measurement performed on the top qubit defines the next iteration.
Inputs:
(with eigenphases $0.0$ or $0.5$, respectively).
(i.e., applying the unitary P to state $|0\rangle$ prepares state $|\psi\rangle$).
Output:
The eigenvalue which corresponds to the eigenstate $|\psi\rangle$ ($+1$ or $-1$).
You are allowed to allocate exactly two qubits and call Controlled U
exactly once.
It is possible to use the QPE implementation from task 1.4 to solve this task,
but we suggest you implement the circuit by hand for the sake of learning.
%kata T21_SingleBitPE
operation SingleBitPE (U : (Qubit => Unit is Adj + Ctl), P : (Qubit => Unit is Adj)) : Int {
// ...
}
Inputs:
(with eigenphases $0.0$, $0.25$, $0.5$ or $0.75$, respectively).
(i.e., applying the unitary P to state $|0\rangle$ prepares state $|\psi\rangle$).
Output:
The eigenphase which corresponds to the eigenstate $|\psi\rangle$ ($0.0$, $0.25$, $0.5$ or $0.75$). The returned value has to be accurate within the absolute error of 0.001.
You are allowed to allocate exactly two qubits and call Controlled U
multiple times.
%kata T22_TwoBitPE
operation TwoBitPE (U : (Qubit => Unit is Adj + Ctl), P : (Qubit => Unit is Adj)) : Double {
// ...
return -1.0;
}
To be continued...