Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
namespace Quantum.Sample
{
open Microsoft.Quantum.Primitive;
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Extensions.Convert;
open Microsoft.Quantum.Extensions.Math;
operation SprinklerAnc (queryRegister: Qubit[], target : Qubit,ancilla: Qubit[]) : Unit {
body (...) {
X(queryRegister[2]);
X(queryRegister[3]);
X(queryRegister[4]);
X(queryRegister[5]);
X(queryRegister[6]);
X(ancilla[0]);
X(ancilla[1]);
X(ancilla[2]);
CCNOT(queryRegister[0],queryRegister[1],ancilla[0]);
CCNOT(queryRegister[1],queryRegister[2],ancilla[1]);
CCNOT(queryRegister[0],queryRegister[2],ancilla[2]);
(Controlled X)([ancilla[0],ancilla[1],ancilla[2],queryRegister[3],queryRegister[4],queryRegister[5],queryRegister[6]],target);
CCNOT(queryRegister[0],queryRegister[2],ancilla[2]);
CCNOT(queryRegister[1],queryRegister[2],ancilla[1]);
CCNOT(queryRegister[0],queryRegister[1],ancilla[0]);
X(ancilla[2]);
X(ancilla[1]);
X(ancilla[0]);
X(queryRegister[2]);
X(queryRegister[6]);
X(queryRegister[5]);
X(queryRegister[4]);
X(queryRegister[3]);
}
adjoint invert;
controlled auto;
controlled adjoint auto;
}
operation OracleConverterImpl (markingOracle : ((Qubit[], Qubit) => Unit : Adjoint, Controlled), register : Qubit[]) : Unit {
body (...) {
using (target = Qubit()) {
// Put the target into the |-⟩ state
X(target);
H(target);
// Apply the marking oracle; since the target is in the |-⟩ state,
// flipping the target if the register satisfies the oracle condition will apply a -1 factor to the state
markingOracle(register, target);
// Put the target back into |0⟩ so we can return it
H(target);
X(target);
}
}
adjoint invert;
controlled auto;
adjoint controlled auto;
}
operation HadamardTransform (register : Qubit[]) : Unit {
body (...) {
//ApplyToEachA(H, register);
// ApplyToEach is a library routine that is equivalent to the following code:
let nQubits = Length(register);
for (idxQubit in 0..nQubits - 1) {
H(register[idxQubit]);
}
}
adjoint invert;
controlled auto;
controlled adjoint auto;
}
operation Oracle_ArbitraryPattern (queryRegister : Qubit[], target : Qubit, pattern : Bool[]) : Unit {
body (...) {
(ControlledOnBitString(pattern, X))(queryRegister, target);
}
adjoint invert;
controlled auto;
controlled adjoint auto;
}
// Task 2.2. Conditional phase flip
operation ConditionalPhaseFlip (register : Qubit[]) : Unit {
body (...) {
// Define a marking oracle which detects an all zero state
let allZerosOracle = Oracle_ArbitraryPattern(_, _, new Bool[Length(register)]);
// Convert it into a phase-flip oracle and apply it
let flipOracle = OracleConverter(allZerosOracle);
flipOracle(register);
}
adjoint self;
controlled auto;
controlled adjoint auto;
}
// Task 2.3. The Grover iteration
operation GroverIteration (register : Qubit[], oracle : (Qubit[] => Unit : Adjoint, Controlled)) : Unit {
body (...) {
oracle(register);
HadamardTransform(register);
ConditionalPhaseFlip(register);
HadamardTransform(register);
}
adjoint invert;
controlled auto;
controlled adjoint auto;
}
function OracleConverter (markingOracle : ((Qubit[], Qubit) => Unit : Adjoint, Controlled)) : (Qubit[] => Unit : Adjoint, Controlled) {
return OracleConverterImpl(markingOracle, _);
}
operation UnitaryPowerImpl (U : (Qubit[] => Unit : Adjoint, Controlled), power : Int, q : Qubit[]) : Unit {
body (...) {
for (i in 1..power) {
U(q);
}
}
adjoint auto;
controlled auto;
controlled adjoint auto;
}
operation QPE() : Double {
mutable phase = -1.0;
let n=8;
using ((reg,phaseRegister,ancilla)=(Qubit[7 ], Qubit[n],Qubit[3]))
{
// Construct a phase estimation oracle from the unitary
let phaseOracle = OracleConverter(SprinklerAnc(_,_,ancilla));
let oracle = DiscreteOracle(UnitaryPowerImpl(GroverIteration(_, phaseOracle), _, _));
// let markingOracle = Sprinkler(_, _);
// Allocate qubits to hold the eigenstate of U and the phase in a big endian register
let phaseRegisterBE = BigEndian(phaseRegister);
// Prepare the eigenstate of U
HadamardTransform(reg);
// Call library
QuantumPhaseEstimation(oracle, reg, phaseRegisterBE);
// Read out the phase
set phase = ToDouble(MeasureIntegerBE(phaseRegisterBE)) / ToDouble(1 <<< (n));
ResetAll(reg);
ResetAll(phaseRegister);
}
let angle = PI()*phase;
let res = 128.0 *(1.0- PowD(Sin(angle),2.0));
return res;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.