These code samples were written by Mariia Mykhailova.
// Deutsch-Jozsa algorithm
operation ApplyConstantFunctionOracle (x : Qubit[]) : Unit {
// Do nothing... (or add a global phase of -1, which is effectively the same)
}
operation ApplyBalancedFunctionOracle (x : Qubit[]) : Unit {
// f(x) = 1 if qubit x[0] is equal to 1
Z(x[0]);
}
// Operation that implements Deutsch-Jozsa algorithm
operation IsConstantFunction (N : Int, oracle : (Qubit[] => Unit)) : Bool {
mutable isConstant = true;
// Allocate an array of N qubits for the input register x.
use x = Qubit[N];
// Newly allocated qubits start in the |0⟩ state.
// The first step is to prepare the qubits in the required state before calling the oracle.
ApplyToEach(H, x);
// Apply the oracle to the input register.
oracle(x);
// Apply a Hadamard gate to each qubit of the input register again.
ApplyToEach(H, x);
// Measure each qubit of the input register in the computational basis using the M operation.
for q in x {
if (M(q) == One) {
set isConstant = false;
}
}
return isConstant;
}
operation RunDeutschJozsaAlgorithm () : Unit {
for (oracle, fStr) in [(ApplyConstantFunctionOracle, "f(x) = 0"),
(ApplyBalancedFunctionOracle, "f(x) = x[0]")] {
let verdict = IsConstantFunction(2, oracle);
Message($"Function {fStr} identified as {verdict ? "constant" | "balanced"}");
}
}
%simulate RunDeutschJozsaAlgorithm
Function f(x) = 0 identified as constant Function f(x) = x[0] identified as balanced
()
// Bernstein-Vazirani algorithm
operation ApplyProductOracle (x : Qubit[], r : Int[]) : Unit {
// f(x) = Σᵢ rᵢ xᵢ modulo 2 for a given bit vector r (scalar product function)
for i in 0 .. Length(x) - 1 {
if (r[i] == 1) {
Z(x[i]);
}
}
}
// Operation that implements Bernstein-Vazirani algorithm
operation RecoveredVector (N : Int, oracle : (Qubit[] => Unit)) : Int[] {
mutable r = new Int[N];
// Allocate an array of N qubits for the input register x.
use x = Qubit[N];
// Newly allocated qubits start in the |0⟩ state.
// The first step is to prepare the qubits in the required state before calling the oracle.
ApplyToEach(H, x);
// Apply the oracle to the input register.
oracle(x);
// Apply a Hadamard gate to each qubit of the input register again.
ApplyToEach(H, x);
// Measure each qubit of the input register in the computational basis using the M operation.
for i in 0 .. Length(x) - 1 {
set r w/= i <- M(x[i]) == One ? 1 | 0;
}
return r;
}
operation RunBernsteinVaziraniAlgorithm () : Unit {
for r in [[0, 0], [1, 0], [0, 1], [1, 1]] {
let oracle = ApplyProductOracle(_, r);
let recoveredR = RecoveredVector(2, oracle);
Message($"Bit vector {r} recovered as {recoveredR}");
}
}
%simulate RunBernsteinVaziraniAlgorithm
Bit vector [0,0] recovered as [0,0] Bit vector [1,0] recovered as [1,0] Bit vector [0,1] recovered as [0,1] Bit vector [1,1] recovered as [1,1]
()