These code samples were written by Mariia Mykhailova.
// Example 8-1: Using the phase estimation primitive
open Microsoft.Quantum.Arithmetic;
open Microsoft.Quantum.Characterization;
open Microsoft.Quantum.Convert;
open Microsoft.Quantum.Diagnostics;
open Microsoft.Quantum.Math;
open Microsoft.Quantum.Oracles;
// Helper operation to define powers of H gate
operation HPower (power : Int, register : Qubit[]) : Unit is Adj + Ctl {
// We know that H² = I, so we just need to apply H if power is odd
if (power % 2 == 1) {
H(register[0]);
}
}
operation UsingQPE () : Unit {
let precision = 4;
// Allocate qubits to hold the eigenstate of H and the phase (in a big endian register)
use (eigenstate, phaseRegister) = (Qubit[1], Qubit[precision]);
// Prepare the eigenstate of H gate corresponding to eigenphase of 180°
// (for 0° we'd use 0.25 * PI() as rotation angle)
Ry(-0.75 * PI(), eigenstate[0]);
// Call library implementation of quantum phase estimation
let phaseRegisterBE = BigEndian(phaseRegister);
let powerUnitary = DiscreteOracle(HPower);
QuantumPhaseEstimation(powerUnitary, eigenstate, phaseRegisterBE);
// Read out the phase
let phase = IntAsDouble(MeasureInteger(BigEndianAsLittleEndian(phaseRegisterBE))) / IntAsDouble(1 <<< precision);
Message($"Estimated phase = {phase * 360.0}°");
ResetAll(eigenstate + phaseRegister);
}
%simulate UsingQPE
Estimated phase = 180°
()
// Example 8-2: Implementation of the phase estimation primitive
open Microsoft.Quantum.Arithmetic;
open Microsoft.Quantum.Characterization;
open Microsoft.Quantum.Convert;
open Microsoft.Quantum.Diagnostics;
open Microsoft.Quantum.Math;
open Microsoft.Quantum.Oracles;
operation QPE (powerUnitary : ((Int, Qubit[]) => Unit is Adj+Ctl),
eigenstate : Qubit[],
phaseRegister : Qubit[]) : Unit {
ApplyToEach(H, phaseRegister);
// Apply conditional powers of U
for i in 0 .. Length(phaseRegister) - 1 {
Controlled powerUnitary([phaseRegister[i]], (1 <<< i, eigenstate));
}
QFTLE(LittleEndian(phaseRegister));
}
// Helper operation to define powers of the rotation gate
operation RotatePower (power : Int, register : Qubit[]) : Unit is Adj + Ctl {
// To apply higher powers of the rotation gate, we can rotate by multiples of the angle
R1(-PI() * 5.0/6.0 * IntAsDouble(power), register[0]);
}
operation ImplementingQPE () : Unit {
let precision = 3;
// Allocate qubits to hold the eigenstate of H and the phase (in a big endian register)
use (eigenstate, phaseRegister) = (Qubit[1], Qubit[precision]);
// Prepare the eigenstate of the rotation gate corresponding to eigenphase of 150°;
// for R1 gate, that is simply a |1⟩
X(eigenstate[0]);
// Call our implementation of quantum phase estimation
QPE(RotatePower, eigenstate, phaseRegister);
// Inspect the state we obtain after applying QPE
DumpRegister((), phaseRegister);
// Read out the phase
let phase = IntAsDouble(MeasureInteger(LittleEndian(phaseRegister))) / IntAsDouble(1 <<< precision);
Message($"Estimated phase = {phase * 360.0}°");
ResetAll(eigenstate + phaseRegister);
}
%simulate ImplementingQPE
Qubit IDs | 1, 2, 3 | ||
---|---|---|---|
Basis state (little endian) | Amplitude | Meas. Pr. | Phase |
$\left|0\right\rangle$ | $0.1083 + 0.0290 i$ | ↑ | |
$\left|1\right\rangle$ | $0.1353 -0.0178 i$ | ↑ | |
$\left|2\right\rangle$ | $0.1875 -0.1083 i$ | ↑ | |
$\left|3\right\rangle$ | $0.5049 -0.6580 i$ | ↑ | |
$\left|4\right\rangle$ | $-0.1083 + 0.4040 i$ | ↑ | |
$\left|5\right\rangle$ | $0.0232 + 0.1763 i$ | ↑ | |
$\left|6\right\rangle$ | $0.0625 + 0.1083 i$ | ↑ | |
$\left|7\right\rangle$ | $0.0866 + 0.0665 i$ | ↑ |
Estimated phase = 90°
()