These code samples were written by Mariia Mykhailova.
// Example 3-1: Creating a multi-qubit state that can be expressed in terms of its qubits
// open namespace which defines diagnostic routines
open Microsoft.Quantum.Diagnostics;
operation SeparableState () : Unit {
// allocate the qubits
use (q1, q2, q3) = (Qubit(), Qubit(), Qubit());
// put each of the qubits q2 and q3 into superposition of 0 and 1
H(q2);
H(q3);
// output the wave function of the three-qubit state
DumpMachine();
// make sure the qubits are back to the 0 state
ResetAll([q1, q2, q3]);
}
%simulate SeparableState
Qubit IDs | 0, 1, 2 | ||
---|---|---|---|
Basis state (little endian) | Amplitude | Meas. Pr. | Phase |
$\left|0\right\rangle$ | $0.5000 + 0.0000 i$ | ↑ | |
$\left|1\right\rangle$ | $0.0000 + 0.0000 i$ | ↑ | |
$\left|2\right\rangle$ | $0.5000 + 0.0000 i$ | ↑ | |
$\left|3\right\rangle$ | $0.0000 + 0.0000 i$ | ↑ | |
$\left|4\right\rangle$ | $0.5000 + 0.0000 i$ | ↑ | |
$\left|5\right\rangle$ | $0.0000 + 0.0000 i$ | ↑ | |
$\left|6\right\rangle$ | $0.5000 + 0.0000 i$ | ↑ | |
$\left|7\right\rangle$ | $0.0000 + 0.0000 i$ | ↑ |
()
// Example 3-2: Make a Bell pair
operation PrepareAndMeasureBellPair () : Unit {
// allocate the qubits
use (a, b) = (Qubit(), Qubit());
// put qubit a in superposition
H(a);
// entangle qubits a and b
CNOT(a, b);
// measure both qubits and output the results
Message($"Measurement results: {M(a)}, {M(b)}");
// make sure the qubits are back to the 0 state
ResetAll([a, b]);
}
operation PrepareMultipleBellPairs () : Unit {
// repeat the experiment multiple times to observe the correlation between measurement results:
// the two bits will be random but always the same
for i in 1..10 {
PrepareAndMeasureBellPair();
}
}
%simulate PrepareMultipleBellPairs
Measurement results: Zero, Zero Measurement results: One, One Measurement results: One, One Measurement results: Zero, Zero Measurement results: One, One Measurement results: Zero, Zero Measurement results: Zero, Zero Measurement results: Zero, Zero Measurement results: Zero, Zero Measurement results: Zero, Zero
()
// Example 3-3: Phase kickback
// open namespace which defines diagnostic routines
open Microsoft.Quantum.Diagnostics;
operation PhaseKickback () : Unit {
// allocate two registers, control and target
use (reg1, reg2) = (Qubit[2], Qubit());
// put each qubit of the control register into superposition of 0 and 1
ApplyToEach(H, reg1);
// initialize the target qubit into 1 state
X(reg2);
// output the wave function of the three-qubit state BEFORE phase kickback
DumpMachine();
// apply phase rotations controlled on the first register
Controlled T(reg1[0..0], reg2);
Controlled S(reg1[1..1], reg2);
// output the wave function of the three-qubit state AFTER phase kickback
DumpMachine();
// make sure the qubits are back to the 0 state
ResetAll(reg1 + [reg2]);
}
%simulate PhaseKickback
Qubit IDs | 0, 1, 2 | ||
---|---|---|---|
Basis state (little endian) | Amplitude | Meas. Pr. | Phase |
$\left|0\right\rangle$ | $0.0000 + 0.0000 i$ | ↑ | |
$\left|1\right\rangle$ | $0.0000 + 0.0000 i$ | ↑ | |
$\left|2\right\rangle$ | $0.0000 + 0.0000 i$ | ↑ | |
$\left|3\right\rangle$ | $0.0000 + 0.0000 i$ | ↑ | |
$\left|4\right\rangle$ | $0.5000 + 0.0000 i$ | ↑ | |
$\left|5\right\rangle$ | $0.5000 + 0.0000 i$ | ↑ | |
$\left|6\right\rangle$ | $0.5000 + 0.0000 i$ | ↑ | |
$\left|7\right\rangle$ | $0.5000 + 0.0000 i$ | ↑ |
Qubit IDs | 0, 1, 2 | ||
---|---|---|---|
Basis state (little endian) | Amplitude | Meas. Pr. | Phase |
$\left|0\right\rangle$ | $0.0000 + 0.0000 i$ | ↑ | |
$\left|1\right\rangle$ | $0.0000 + 0.0000 i$ | ↑ | |
$\left|2\right\rangle$ | $0.0000 + 0.0000 i$ | ↑ | |
$\left|3\right\rangle$ | $0.0000 + 0.0000 i$ | ↑ | |
$\left|4\right\rangle$ | $0.5000 + 0.0000 i$ | ↑ | |
$\left|5\right\rangle$ | $0.3536 + 0.3536 i$ | ↑ | |
$\left|6\right\rangle$ | $0.0000 + 0.5000 i$ | ↑ | |
$\left|7\right\rangle$ | $-0.3536 + 0.3536 i$ | ↑ |
()
// Example 3-4: The swap test
// open namespace which defines type conversion functions
open Microsoft.Quantum.Convert;
// open namespace which defines MResetZ
open Microsoft.Quantum.Measurement;
// Returns True if the states of the input qubits are equal
operation SwapTest (input1 : Qubit, input2 : Qubit) : Bool {
// allocate the output qubit
use output = Qubit();
// initialize the output qubit
H(output);
// swap the input states conditioned on the output state
Controlled SWAP([output], (input1, input2));
// extract the result and return the output qubit back to 0 state
H(output);
X(output);
return M(output) == One;
}
operation RunSwapTest () : Unit {
let attempts = 100;
mutable reportedEqual = 0;
// repeat the test multiple times to observe the probability of the states being reported equal
for i in 1..attempts {
// allocate qubits to be tested
use (input1, input2) = (Qubit(), Qubit());
// initialize the qubits in the states we want to compare
// leave input1 in the |0⟩ state and rotate input2 - the larger the angle, the further away are the states
// try replacing 0.1 with 0.0 (when the states will be equal)
// and with 0.2, 0.3, ... up to 1.0 when the state is rotated all the way to the -|0⟩
Ry(2.0 * 3.14 * 0.1, input2);
// some other suggested state initializations:
// X(input1); H(input1); H(input2); Z(input2); // same state |-⟩, prepared in different ways
// X(input1); H(input1); H(input2); // orthogonal states: input1 in the |-⟩ state, input2 in the |+⟩ state
if (SwapTest(input1, input2)) {
set reportedEqual += 1;
}
ResetAll([input1, input2]);
}
Message($"The states were reported equal {IntAsDouble(reportedEqual) / IntAsDouble(attempts) * 100.0 }% of the time");
}
%simulate RunSwapTest
The states were reported equal 97% of the time
()
// Example 3-5: Custom conditional phase
// open namespace which defines diagnostic routines
open Microsoft.Quantum.Diagnostics;
operation CustomConditionalPhase () : Unit {
// allocate two qubits
use (q1, q2) = (Qubit(), Qubit());
// put each of the qubits into superposition of 0 and 1
H(q1);
H(q2);
// apply phases
T(q2);
CNOT(q1, q2);
Adjoint T(q2);
CNOT(q1, q2);
T(q1);
// output the wave function of the two-qubit state
DumpMachine();
// apply a single gate equivalent to the earlier sequence of gates
Controlled S([q1], q2);
// output the wave function of the two-qubit state
DumpMachine();
// make sure the qubits are back to the 0 state
ResetAll([q1, q2]);
}
%simulate CustomConditionalPhase
Qubit IDs | 0, 1 | ||
---|---|---|---|
Basis state (little endian) | Amplitude | Meas. Pr. | Phase |
$\left|0\right\rangle$ | $0.5000 + 0.0000 i$ | ↑ | |
$\left|1\right\rangle$ | $0.5000 + 0.0000 i$ | ↑ | |
$\left|2\right\rangle$ | $0.5000 + 0.0000 i$ | ↑ | |
$\left|3\right\rangle$ | $0.0000 + 0.5000 i$ | ↑ |
Qubit IDs | 0, 1 | ||
---|---|---|---|
Basis state (little endian) | Amplitude | Meas. Pr. | Phase |
$\left|0\right\rangle$ | $0.5000 + 0.0000 i$ | ↑ | |
$\left|1\right\rangle$ | $0.5000 + 0.0000 i$ | ↑ | |
$\left|2\right\rangle$ | $0.5000 + 0.0000 i$ | ↑ | |
$\left|3\right\rangle$ | $-0.5000 + 0.0000 i$ | ↑ |
()
// Example 3-6: Remote-controlled randomness
// open namespace which defines type conversion functions
open Microsoft.Quantum.Convert;
// open namespace which defines MResetZ
open Microsoft.Quantum.Measurement;
operation RemoteControlledRandomness () : Unit {
let attempts = 1000;
mutable result = [0, 0, 0, 0];
for i in 1 .. attempts {
// allocate two qubits
use (a, b) = (Qubit(), Qubit());
H(a);
// measuring a now will give us 0 or 1 with 50% probability
H(b);
T(b);
H(b);
// measuring b now will give us 0 with 85% probability and 1 with 15% probability
// entangle a and b
CNOT(a, b);
// now, you can read *either* qubit and get 0 or 1 with 50% probability;
// if the result is 0, then the probability of the *remaining* qubit measuring 1 is 15%, else it's 85%;
// if the result is 1, the probabilities are the other way around
// let's measure qubit a first
// (we'll convert measurement results into integer to keep statistics in an array)
let index = (M(a) == One ? 1 | 0) * 2 + (M(b) == One ? 1 | 0);
set result w/= index <- result[index] + 1;
}
Message($"Overall measurement counts (out of {attempts}): {result}");
let a0b0_percentage = IntAsDouble(result[0]) / IntAsDouble(result[0] + result[1]) * 100.0;
Message($"When a was measured to be 0, b was measured 0 {a0b0_percentage}% of times");
let a1b0_percentage = IntAsDouble(result[2]) / IntAsDouble(result[2] + result[3]) * 100.0;
Message($"When a was measured to be 1, b was measured 0 {a1b0_percentage}% of times");
}
%simulate RemoteControlledRandomness
Overall measurement counts (out of 1000): [446,73,73,408] When a was measured to be 0, b was measured 0 85.9344894026975% of times When a was measured to be 1, b was measured 0 15.176715176715177% of times
()