Update to 0.15 syntax, batch 1 (#590)

This change updates the katas and tutorials to the new syntax introduced in Q# 0.15:
* "use" keyword instead of "using"
* no round brackets in for loops
This commit is contained in:
Mariia Mykhailova 2021-01-28 23:09:48 -08:00 коммит произвёл GitHub
Родитель 6b3ff0d9ab
Коммит e9c86e2dbb
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
16 изменённых файлов: 682 добавлений и 727 удалений

Просмотреть файл

@ -48,26 +48,25 @@ namespace Quantum.Kata.BasicGates {
testImpl : (Qubit[] => Unit is Adj+Ctl),
refImpl : (Qubit[] => Unit is Adj+Ctl)
) : Unit {
using (qs = Qubit[N]) {
// Prepare the input state and show it
statePrep(qs);
Message("The starting state:");
DumpMachine();
use qs = Qubit[N];
// Prepare the input state and show it
statePrep(qs);
Message("The starting state:");
DumpMachine();
// Apply the reference solution and show result
refImpl(qs);
Message("The desired state:");
DumpMachine();
ResetAll(qs);
// Apply the reference solution and show result
refImpl(qs);
Message("The desired state:");
DumpMachine();
ResetAll(qs);
// Prepare the input state again for test implementation
statePrep(qs);
// Apply learner's solution and show result
testImpl(qs);
Message("The actual state:");
DumpMachine();
ResetAll(qs);
}
// Prepare the input state again for test implementation
statePrep(qs);
// Apply learner's solution and show result
testImpl(qs);
Message("The actual state:");
DumpMachine();
ResetAll(qs);
}
@ -115,7 +114,7 @@ namespace Quantum.Kata.BasicGates {
Message($"Applying amplitude change with alpha = {dumpAlpha}");
DumpDiffOnOneQubit(AmplitudeChange(dumpAlpha, _), AmplitudeChange_Reference(dumpAlpha, _));
for (i in 0 .. 36) {
for i in 0 .. 36 {
let alpha = ((2.0 * PI()) * IntAsDouble(i)) / 36.0;
AssertOperationsEqualReferenced(2, ArrayWrapperControlled(AmplitudeChange(alpha, _), _),
ArrayWrapperControlled(AmplitudeChange_Reference(alpha, _), _));
@ -139,7 +138,7 @@ namespace Quantum.Kata.BasicGates {
Message($"Applying phase change with alpha = {dumpAlpha}");
DumpDiffOnOneQubit(PhaseChange(dumpAlpha,_), PhaseChange_Reference(dumpAlpha,_));
for (i in 0 .. 36) {
for i in 0 .. 36 {
let alpha = ((2.0 * PI()) * IntAsDouble(i)) / 36.0;
AssertOperationsEqualReferenced(2, ArrayWrapperControlled(PhaseChange(alpha, _), _),
ArrayWrapperControlled(PhaseChange_Reference(alpha, _), _));
@ -192,23 +191,22 @@ namespace Quantum.Kata.BasicGates {
// ------------------------------------------------------
operation VerifyBellStateConversion (testOp : (Qubit[] => Unit is Adj+Ctl), startState : Int, targetState : Int) : Unit {
// (note the use of controlled versions of operations to keep track of the phase potentially acquired by testOp)
using (qs = Qubit[3]) {
H(qs[0]);
use qs = Qubit[3];
H(qs[0]);
// prepare Bell state startState
Controlled StatePrep_BellState([qs[0]], (Rest(qs), startState));
// prepare Bell state startState
Controlled StatePrep_BellState([qs[0]], (Rest(qs), startState));
// apply operation that needs to be tested
Controlled testOp([qs[0]], Rest(qs));
// apply operation that needs to be tested
Controlled testOp([qs[0]], Rest(qs));
// verify the result by applying adjoint of state prep for target state
Controlled Adjoint StatePrep_BellState([qs[0]], (Rest(qs), targetState));
// verify the result by applying adjoint of state prep for target state
Controlled Adjoint StatePrep_BellState([qs[0]], (Rest(qs), targetState));
H(qs[0]);
H(qs[0]);
// assert that all qubits end up in |0⟩ state
AssertAllZero(qs);
}
// assert that all qubits end up in |0⟩ state
AssertAllZero(qs);
}
@ -248,25 +246,24 @@ namespace Quantum.Kata.BasicGates {
// Note that the way the problem is formulated, we can't just compare two unitaries,
// we need to create a specific input state and check that the output state is correct
using (qs = Qubit[2]) {
for (i in 0 .. 36) {
let alpha = ((2.0 * PI()) * IntAsDouble(i)) / 36.0;
use qs = Qubit[2];
for i in 0 .. 36 {
let alpha = ((2.0 * PI()) * IntAsDouble(i)) / 36.0;
within {
// prepare state cos(α) * |0⟩ + sin(α) * |1⟩
Ry(2.0 * alpha, qs[0]);
}
apply {
// apply operation that needs to be tested
TwoQubitGate1(qs);
// apply adjoint reference operation
Adjoint TwoQubitGate1_Reference(qs);
}
// assert that all qubits end up in |0⟩ state
AssertAllZero(qs);
within {
// prepare state cos(α) * |0⟩ + sin(α) * |1⟩
Ry(2.0 * alpha, qs[0]);
}
apply {
// apply operation that needs to be tested
TwoQubitGate1(qs);
// apply adjoint reference operation
Adjoint TwoQubitGate1_Reference(qs);
}
// assert that all qubits end up in |0⟩ state
AssertAllZero(qs);
}
}
@ -275,21 +272,20 @@ namespace Quantum.Kata.BasicGates {
@Test("QuantumSimulator")
operation T202_TwoQubitGate2 () : Unit {
DumpDiff(2, ApplyToEachCA(H, _), TwoQubitGate2, TwoQubitGate2_Reference);
using (qs = Qubit[2]) {
within {
// prepare |+⟩ ⊗ |+⟩ state
ApplyToEachCA(H, qs);
} apply {
// apply operation that needs to be tested
TwoQubitGate2(qs);
use qs = Qubit[2];
within {
// prepare |+⟩ ⊗ |+⟩ state
ApplyToEachCA(H, qs);
} apply {
// apply operation that needs to be tested
TwoQubitGate2(qs);
// apply adjoint reference operation
Adjoint TwoQubitGate2_Reference(qs);
}
// assert that all qubits end up in |0⟩ state
AssertAllZero(qs);
// apply adjoint reference operation
Adjoint TwoQubitGate2_Reference(qs);
}
// assert that all qubits end up in |0⟩ state
AssertAllZero(qs);
}
@ -297,7 +293,7 @@ namespace Quantum.Kata.BasicGates {
// Prepare a state for tests 2.3-2.5
operation StatePrepMiscAmplitudes (qs : Qubit[]) : Unit is Adj+Ctl {
let alphas = [5.0, 10.0, 15.0];
for (index in 0 .. Length(qs) - 1) {
for index in 0 .. Length(qs) - 1 {
Ry(2.0 * (alphas[index] + IntAsDouble(index + 1)), qs[index]);
}
}

Просмотреть файл

@ -112,7 +112,7 @@ namespace Quantum.Kata.Measurements {
// Example: for bit strings [false, true, false] and [false, false, true]
// return 0 corresponds to state |010⟩, and return 1 corresponds to state |001⟩.
function FindFirstDiff_Reference (bits1 : Bool[], bits2 : Bool[]) : Int {
for (i in 0 .. Length(bits1) - 1) {
for i in 0 .. Length(bits1) - 1 {
if (bits1[i] != bits2[i]) {
return i;
}
@ -135,16 +135,16 @@ namespace Quantum.Kata.Measurements {
// Task 1.8. Distinguish two superposition states given by two arrays of bit strings - 1 measurement
function FindFirstSuperpositionDiff_Reference (bits1 : Bool[][], bits2 : Bool[][], Nqubits : Int) : Int {
for (i in 0 .. Nqubits - 1) {
for i in 0 .. Nqubits - 1 {
// count the number of 1s in i-th position in bit strings of both arrays
mutable val1 = 0;
mutable val2 = 0;
for (j in 0 .. Length(bits1) - 1) {
for j in 0 .. Length(bits1) - 1 {
if (bits1[j][i]) {
set val1 += 1;
}
}
for (k in 0 .. Length(bits2) - 1) {
for k in 0 .. Length(bits2) - 1 {
if (bits2[k][i]) {
set val2 += 1;
}
@ -181,7 +181,7 @@ namespace Quantum.Kata.Measurements {
// measure all qubits and check in which array you can find the resulting bit string
let meas = ResultArrayAsBoolArray(MultiM(qs));
for (i in 0 .. Length(bits1) - 1) {
for i in 0 .. Length(bits1) - 1 {
if (EqualA(EqualB, bits1[i], meas)) {
return 0;
}
@ -198,7 +198,7 @@ namespace Quantum.Kata.Measurements {
// measure all qubits and, treating the result as an integer, check whether it can be found in one of the bit arrays
let measuredState = ResultArrayAsInt(MultiM(qs));
for (s in bits1) {
for s in bits1 {
if (BoolArrayAsInt(s) == measuredState) {
return 0;
}
@ -219,7 +219,7 @@ namespace Quantum.Kata.Measurements {
// (and there should never be two or more Ones)
mutable countOnes = 0;
for (q in qs) {
for q in qs {
if (M(q) == One) {
set countOnes += 1;
}
@ -253,7 +253,7 @@ namespace Quantum.Kata.Measurements {
// (and there should never be a different number of Ones)
mutable countOnes = 0;
for (q in qs) {
for q in qs {
if (M(q) == One) {
set countOnes += 1;
}
@ -407,11 +407,10 @@ namespace Quantum.Kata.Measurements {
Adjoint WState_Arbitrary_Reference(qs);
// need one qubit to store result of comparison "000" vs "not 000"
using (anc = Qubit()) {
// compute the OR function into anc
(ControlledOnInt(0, X))(qs, anc);
set result = MResetZ(anc) == One ? 0 | 1;
}
use anc = Qubit();
// compute the OR function into anc
(ControlledOnInt(0, X))(qs, anc);
set result = MResetZ(anc) == One ? 0 | 1;
// Fix up the state so that it is identical to the input state
// (this is not required if the state of the qubits after the operation does not matter)
@ -566,36 +565,35 @@ namespace Quantum.Kata.Measurements {
// the final resulting circuit without additional commentary.
let alpha = ArcCos(Sqrt(2.0 / 3.0));
using (a = Qubit()) {
Z(q);
CNOT(a, q);
Controlled H([q], a);
S(a);
X(q);
use a = Qubit();
Z(q);
CNOT(a, q);
Controlled H([q], a);
S(a);
X(q);
(ControlledOnInt(0, Ry))([a], (-2.0 * alpha, q));
CNOT(a, q);
Controlled H([q], a);
CNOT(a, q);
(ControlledOnInt(0, Ry))([a], (-2.0 * alpha, q));
CNOT(a, q);
Controlled H([q], a);
CNOT(a, q);
// finally, measure in the standard basis
let res0 = MResetZ(a);
let res1 = M(q);
// finally, measure in the standard basis
let res0 = MResetZ(a);
let res1 = M(q);
// dispatch on the cases
if (res0 == Zero and res1 == Zero) {
return 0;
}
elif (res0 == One and res1 == Zero) {
return 1;
}
elif (res0 == Zero and res1 == One) {
return 2;
}
else {
// this should never occur
return 3;
}
// dispatch on the cases
if (res0 == Zero and res1 == Zero) {
return 0;
}
elif (res0 == One and res1 == Zero) {
return 1;
}
elif (res0 == Zero and res1 == One) {
return 2;
}
else {
// this should never occur
return 3;
}
}
}

Просмотреть файл

@ -28,29 +28,28 @@ namespace Quantum.Kata.Measurements {
let nStates = 2;
mutable misclassifications = new Int[nStates];
using (q = Qubit()) {
for (i in 1 .. nTotal) {
// get a random bit to define whether qubit will be in a state corresponding to true return (1) or to false one (0)
// state = 0 false return
// state = 1 true return
let state = DrawRandomInt(0, 1);
use q = Qubit();
for i in 1 .. nTotal {
// get a random bit to define whether qubit will be in a state corresponding to true return (1) or to false one (0)
// state = 0 false return
// state = 1 true return
let state = DrawRandomInt(0, 1);
// do state prep: convert |0⟩ to outcome with false return or to outcome with true return depending on state
statePrep(q, state);
// do state prep: convert |0⟩ to outcome with false return or to outcome with true return depending on state
statePrep(q, state);
// get the solution's answer and verify if NOT a match, then differentiate what kind of mismatch
let ans = testImpl(q);
if (ans != (state == 1)) {
set misclassifications w/= state <- misclassifications[state] + 1;
}
// we're not checking the state of the qubit after the operation
Reset(q);
// get the solution's answer and verify if NOT a match, then differentiate what kind of mismatch
let ans = testImpl(q);
if (ans != (state == 1)) {
set misclassifications w/= state <- misclassifications[state] + 1;
}
// we're not checking the state of the qubit after the operation
Reset(q);
}
mutable totalMisclassifications = 0;
for (i in 0 .. nStates - 1) {
for i in 0 .. nStates - 1 {
if (misclassifications[i] != 0) {
set totalMisclassifications += misclassifications[i];
Message($"Misclassified {stateName[i]} as {stateName[1 - i]} in {misclassifications[i]} test runs.");
@ -79,17 +78,16 @@ namespace Quantum.Kata.Measurements {
// ------------------------------------------------------
@Test("QuantumSimulator")
operation T102_InitializeQubit () : Unit {
using (q = Qubit()) {
for (i in 0 .. 36) {
let alpha = ((2.0 * PI()) * IntAsDouble(i)) / 36.0;
Ry(2.0 * alpha, q);
use q = Qubit();
for i in 0 .. 36 {
let alpha = ((2.0 * PI()) * IntAsDouble(i)) / 36.0;
Ry(2.0 * alpha, q);
// Test Task 1
InitializeQubit(q);
// Test Task 1
InitializeQubit(q);
// Confirm that the state is |0⟩.
AssertQubit(Zero, q);
}
// Confirm that the state is |0⟩.
AssertQubit(Zero, q);
}
}
@ -138,7 +136,7 @@ namespace Quantum.Kata.Measurements {
DistinguishTwoStates_OneQubit(StatePrep_IsQubitPlus, IsQubitA(PI() / 4.0, _),
[$"|B⟩=(-sin(π/4)|0⟩ + cos(π/4)|1⟩)", $"|A⟩=(cos(π/4)|0⟩ + sin(π/4)|1⟩)"]);
for (i in 0 .. 10) {
for i in 0 .. 10 {
let alpha = (PI() * IntAsDouble(i)) / 10.0;
DistinguishTwoStates_OneQubit(StatePrep_IsQubitA(alpha, _, _), IsQubitA(alpha, _),
[$"|B⟩=(-sin({i}π/10)|0⟩ + cos({i}π/10)|1⟩)", $"|A⟩=(cos({i}π/10)|0⟩ + sin({i}π/10)|1⟩)"]);
@ -162,43 +160,42 @@ namespace Quantum.Kata.Measurements {
// unknownClassifications will store the number of times state i has been classified as some invalid state (index < 0 or >= nStates)
mutable unknownClassifications = new Int[nStates];
using (qs = Qubit[nQubits]) {
for (i in 1 .. nTotal) {
// get a random integer to define the state of the qubits
let state = DrawRandomInt(0, nStates - 1);
use qs = Qubit[nQubits];
for _ in 1 .. nTotal {
// get a random integer to define the state of the qubits
let state = DrawRandomInt(0, nStates - 1);
// do state prep: convert |0...0⟩ to outcome with return equal to state
statePrep(qs, state);
// do state prep: convert |0...0⟩ to outcome with return equal to state
statePrep(qs, state);
if (measurementsPerRun > 0) {
ResetOracleCallsCount();
}
// get the solution's answer and verify that it's a match, if not, increase the exact mismatch count
let ans = testImpl(qs);
if ((ans >= 0) and (ans < nStates)) {
// classification result is a valid state index - check if is it correct
if (ans != state) {
set misclassifications w/= ((state * nStates) + ans) <- (misclassifications[(state * nStates) + ans] + 1);
}
}
else {
// classification result is an invalid state index - file it separately
set unknownClassifications w/= state <- (unknownClassifications[state] + 1);
}
// if we have a max number of measurements per solution run specified, check that it is not exceeded
if (measurementsPerRun > 0) {
let nm = GetOracleCallsCount(M) + GetOracleCallsCount(Measure);
EqualityFactB(nm <= 1, true, $"You are allowed to do at most one measurement, and you did {nm}");
}
// we're not checking the state of the qubit after the operation
ResetAll(qs);
if (measurementsPerRun > 0) {
ResetOracleCallsCount();
}
// get the solution's answer and verify that it's a match, if not, increase the exact mismatch count
let ans = testImpl(qs);
if ((ans >= 0) and (ans < nStates)) {
// classification result is a valid state index - check if is it correct
if (ans != state) {
set misclassifications w/= ((state * nStates) + ans) <- (misclassifications[(state * nStates) + ans] + 1);
}
}
else {
// classification result is an invalid state index - file it separately
set unknownClassifications w/= state <- (unknownClassifications[state] + 1);
}
// if we have a max number of measurements per solution run specified, check that it is not exceeded
if (measurementsPerRun > 0) {
let nm = GetOracleCallsCount(M) + GetOracleCallsCount(Measure);
EqualityFactB(nm <= 1, true, $"You are allowed to do at most one measurement, and you did {nm}");
}
// we're not checking the state of the qubit after the operation
ResetAll(qs);
}
mutable totalMisclassifications = 0;
for (i in 0 .. nStates - 1) {
for (j in 0 .. nStates - 1) {
for i in 0 .. nStates - 1 {
for j in 0 .. nStates - 1 {
if (misclassifications[(i * nStates) + j] != 0) {
set totalMisclassifications += misclassifications[i * nStates + j];
Message($"Misclassified {stateNames[i]} as {stateNames[j]} in {misclassifications[(i * nStates) + j]} test runs.");
@ -251,7 +248,7 @@ namespace Quantum.Kata.Measurements {
// ------------------------------------------------------
operation StatePrep_Bitstring (qs : Qubit[], bits : Bool[]) : Unit {
for (i in 0 .. Length(qs) - 1) {
for i in 0 .. Length(qs) - 1 {
if (bits[i]) {
X(qs[i]);
}
@ -268,7 +265,7 @@ namespace Quantum.Kata.Measurements {
// Helper function to convert a boolean array to its ket state representation
function BoolArrayAsKetState (bits : Bool[]) : String {
mutable stateName = "|";
for (i in 0 .. Length(bits) - 1) {
for i in 0 .. Length(bits) - 1 {
set stateName += (bits[i] ? "1" | "0");
}
return stateName + "⟩";
@ -303,7 +300,7 @@ namespace Quantum.Kata.Measurements {
// ------------------------------------------------------
operation StatePrep_FindFirstDiff (bits1 : Bool[], bits2 : Bool[]) : Int {
for (i in 0 .. Length(bits1) - 1) {
for i in 0 .. Length(bits1) - 1 {
if (bits1[i] != bits2[i]) {
return i;
}
@ -317,7 +314,7 @@ namespace Quantum.Kata.Measurements {
let L = Length(bits);
Fact(L == 1 or L == 2 or L == 4, "State preparation only supports arrays of 1, 2 or 4 bit strings");
if (L == 1) {
for (i in 0 .. Length(qs) - 1) {
for i in 0 .. Length(qs) - 1 {
if (bits[0][i]) {
X(qs[i]);
}
@ -331,7 +328,7 @@ namespace Quantum.Kata.Measurements {
H(qs[firstDiff]);
// iterate through the bit strings again setting the final state of qubits
for (i in 0 .. Length(qs) - 1) {
for i in 0 .. Length(qs) - 1 {
if (bits[0][i] == bits[1][i]) {
// if two bits are the same, apply X or nothing
if (bits[0][i]) {
@ -351,27 +348,26 @@ namespace Quantum.Kata.Measurements {
if (L == 4) {
let N = Length(qs);
using (anc = Qubit[2]) {
// Put two ancillas into equal superposition of 2-qubit basis states
ApplyToEachA(H, anc);
use anc = Qubit[2];
// Put two ancillas into equal superposition of 2-qubit basis states
ApplyToEachA(H, anc);
// Set up the right pattern on the main qubits with control on ancillas
for (i in 0 .. 3) {
for (j in 0 .. N - 1) {
if ((bits[i])[j]) {
(ControlledOnInt(i, X))(anc, qs[j]);
}
// Set up the right pattern on the main qubits with control on ancillas
for i in 0 .. 3 {
for j in 0 .. N - 1 {
if ((bits[i])[j]) {
(ControlledOnInt(i, X))(anc, qs[j]);
}
}
}
// Uncompute the ancillas, using patterns on main qubits as control
for (i in 0 .. 3) {
if (i % 2 == 1) {
(ControlledOnBitString(bits[i], X))(qs, anc[0]);
}
if (i / 2 == 1) {
(ControlledOnBitString(bits[i], X))(qs, anc[1]);
}
// Uncompute the ancillas, using patterns on main qubits as control
for i in 0 .. 3 {
if (i % 2 == 1) {
(ControlledOnBitString(bits[i], X))(qs, anc[0]);
}
if (i / 2 == 1) {
(ControlledOnBitString(bits[i], X))(qs, anc[1]);
}
}
}
@ -387,7 +383,7 @@ namespace Quantum.Kata.Measurements {
// Helper function to convert an array of bit strings to its ket state representation
function IntArrayAsStateName (qubits : Int, bitStrings : Bool[][]) : String {
mutable statename = "";
for (i in 0 .. Length(bitStrings) - 1) {
for i in 0 .. Length(bitStrings) - 1 {
if (i > 0) {
set statename += " + ";
}
@ -512,7 +508,7 @@ namespace Quantum.Kata.Measurements {
@Test("Microsoft.Quantum.Katas.CounterSimulator")
operation T110_AllZerosOrWState () : Unit {
for (i in 2 .. 6) {
for i in 2 .. 6 {
DistinguishStates_MultiQubit(i, 2, StatePrep_AllZerosOrWState, AllZerosOrWState, 0, ["|0...0⟩", "|W⟩"]);
}
}
@ -521,7 +517,7 @@ namespace Quantum.Kata.Measurements {
// ------------------------------------------------------
operation GHZ_State_Reference (qs : Qubit[]) : Unit is Adj {
H(Head(qs));
for (q in Rest(qs)) {
for q in Rest(qs) {
CNOT(Head(qs), q);
}
}
@ -540,7 +536,7 @@ namespace Quantum.Kata.Measurements {
@Test("Microsoft.Quantum.Katas.CounterSimulator")
operation T111_GHZOrWState () : Unit {
for (i in 2 .. 6) {
for i in 2 .. 6 {
DistinguishStates_MultiQubit(i, 2, StatePrep_GHZOrWState, GHZOrWState, 0, ["|GHZ⟩", "|W⟩"]);
}
}
@ -667,23 +663,22 @@ namespace Quantum.Kata.Measurements {
let nTotal = 1000;
mutable nOk = 0;
using (qs = Qubit[Nqubit]) {
for (i in 1 .. nTotal) {
// get a random integer to define the state of the qubits
let state = DrawRandomInt(0, Nstate - 1);
use qs = Qubit[Nqubit];
for i in 1 .. nTotal {
// get a random integer to define the state of the qubits
let state = DrawRandomInt(0, Nstate - 1);
// do state prep: convert |0⟩ to outcome with return equal to state
statePrep(qs[0], state);
// do state prep: convert |0⟩ to outcome with return equal to state
statePrep(qs[0], state);
// get the solution's answer and verify that it's a match
let ans = testImpl(qs[0]);
if (ans == (state == 0)) {
set nOk += 1;
}
// we're not checking the state of the qubit after the operation
ResetAll(qs);
// get the solution's answer and verify that it's a match
let ans = testImpl(qs[0]);
if (ans == (state == 0)) {
set nOk += 1;
}
// we're not checking the state of the qubit after the operation
ResetAll(qs);
}
if (IntAsDouble(nOk) < threshold * IntAsDouble(nTotal)) {
@ -714,44 +709,43 @@ namespace Quantum.Kata.Measurements {
// counts total conclusive |+> state identifications
mutable nConclPlus = 0;
using (qs = Qubit[Nqubit]) {
for (i in 1 .. nTotal) {
use qs = Qubit[Nqubit];
for i in 1 .. nTotal {
// get a random integer to define the state of the qubits
let state = DrawRandomInt(0, Nstate - 1);
// get a random integer to define the state of the qubits
let state = DrawRandomInt(0, Nstate - 1);
// do state prep: convert |0⟩ to outcome with return equal to state
statePrep(qs[0], state);
// do state prep: convert |0⟩ to outcome with return equal to state
statePrep(qs[0], state);
// get the solution's answer and verify that it's a match
let ans = testImpl(qs[0]);
// get the solution's answer and verify that it's a match
let ans = testImpl(qs[0]);
// check that the answer is actually in allowed range
if (ans < -1 or ans > 1) {
fail $"state {state} led to invalid response {ans}.";
}
// keep track of the number of inconclusive answers given
if (ans == -1) {
set nInconc += 1;
}
if (ans == 0 and state == 0) {
set nConclOne += 1;
}
if (ans == 1 and state == 1) {
set nConclPlus += 1;
}
// check if upon conclusive result the answer is actually correct
if (ans == 0 and state == 1 or ans == 1 and state == 0) {
fail $"state {state} led to incorrect conclusive response {ans}.";
}
// we're not checking the state of the qubit after the operation
ResetAll(qs);
// check that the answer is actually in allowed range
if (ans < -1 or ans > 1) {
fail $"state {state} led to invalid response {ans}.";
}
// keep track of the number of inconclusive answers given
if (ans == -1) {
set nInconc += 1;
}
if (ans == 0 and state == 0) {
set nConclOne += 1;
}
if (ans == 1 and state == 1) {
set nConclPlus += 1;
}
// check if upon conclusive result the answer is actually correct
if (ans == 0 and state == 1 or ans == 1 and state == 0) {
fail $"state {state} led to incorrect conclusive response {ans}.";
}
// we're not checking the state of the qubit after the operation
ResetAll(qs);
}
if (IntAsDouble(nInconc) > thresholdInconcl * IntAsDouble(nTotal)) {
@ -800,31 +794,30 @@ namespace Quantum.Kata.Measurements {
let nTotal = 1000;
using (qs = Qubit[Nqubit]) {
use qs = Qubit[Nqubit];
for (i in 1 .. nTotal) {
// get a random integer to define the state of the qubits
let state = DrawRandomInt(0, Nstate - 1);
for i in 1 .. nTotal {
// get a random integer to define the state of the qubits
let state = DrawRandomInt(0, Nstate - 1);
// do state prep: convert |0⟩ to outcome with return equal to state
statePrep(qs[0], state);
// do state prep: convert |0⟩ to outcome with return equal to state
statePrep(qs[0], state);
// get the solution's answer and verify that it's a match
let ans = testImpl(qs[0]);
// get the solution's answer and verify that it's a match
let ans = testImpl(qs[0]);
// check that the value of ans is 0, 1 or 2
if (ans < 0 or ans > 2) {
fail "You can not return any value other than 0, 1 or 2.";
}
// check if upon conclusive result the answer is actually correct
if (ans == state) {
fail $"State {state} led to incorrect conclusive response {ans}.";
}
// we're not checking the state of the qubit after the operation
ResetAll(qs);
// check that the value of ans is 0, 1 or 2
if (ans < 0 or ans > 2) {
fail "You can not return any value other than 0, 1 or 2.";
}
// check if upon conclusive result the answer is actually correct
if (ans == state) {
fail $"State {state} led to incorrect conclusive response {ans}.";
}
// we're not checking the state of the qubit after the operation
ResetAll(qs);
}
}

Просмотреть файл

@ -386,7 +386,7 @@
"outputs": [],
"source": [
"function FindFirstDiff (bits1 : Bool[], bits2 : Bool[]) : Int {\n",
" for (i in 0 .. Length(bits1) - 1) {\n",
" for i in 0 .. Length(bits1) - 1 {\n",
" if (bits1[i] != bits2[i]) {\n",
" return i;\n",
" }\n",
@ -487,17 +487,17 @@
"metadata": {},
"outputs": [],
"source": [
"function FindFirstSuperpositionDiff (bits1 : Bool[][], bits2 : Bool[][], Nqubits : Int) : Int {\n",
" for (i in 0 .. Nqubits - 1) {\n",
"function FindFirstSuperpositionDiff (bits1 : Bool[][], bits2 : Bool[][], nQubits : Int) : Int {\n",
" for i in 0 .. nQubits - 1 {\n",
" // count the number of 1s in i-th position in bit strings of both arrays\n",
" mutable val1 = 0;\n",
" mutable val2 = 0;\n",
" for (j in 0 .. Length(bits1) - 1) {\n",
" for j in 0 .. Length(bits1) - 1 {\n",
" if (bits1[j][i]) {\n",
" set val1 += 1;\n",
" }\n",
" }\n",
" for (k in 0 .. Length(bits2) - 1) {\n",
" for k in 0 .. Length(bits2) - 1 {\n",
" if (bits2[k][i]) {\n",
" set val2 += 1;\n",
" }\n",
@ -605,7 +605,7 @@
"\n",
"operation SuperpositionMeasurement (qs : Qubit[], bits1 : Bool[][], bits2 : Bool[][]) : Int {\n",
" let measuredState = ResultArrayAsInt(MultiM(qs));\n",
" for (s in bits1) {\n",
" for s in bits1 {\n",
" if (BoolArrayAsInt(s) == measuredState) {\n",
" return 0;\n",
" }\n",
@ -661,7 +661,7 @@
"operation AllZerosOrWState (qs : Qubit[]) : Int {\n",
" mutable countOnes = 0;\n",
"\n",
" for (q in qs) {\n",
" for q in qs {\n",
" if (M(q) == One) {\n",
" set countOnes += 1;\n",
" }\n",
@ -741,7 +741,7 @@
"operation GHZOrWState (qs : Qubit[]) : Int {\n",
" mutable countOnes = 0;\n",
"\n",
" for (q in qs) {\n",
" for q in qs {\n",
" if (M(q) == One) {\n",
" set countOnes += 1;\n",
" }\n",
@ -1138,7 +1138,7 @@
"file_extension": ".qs",
"mimetype": "text/x-qsharp",
"name": "qsharp",
"version": "0.10"
"version": "0.14"
}
},
"nbformat": 4,

Просмотреть файл

@ -322,47 +322,46 @@
"open Microsoft.Quantum.Measurement;\n",
"\n",
"operation IsQubitNotInABC (q : Qubit) : Int {\n",
" using (a = Qubit()) {\n",
" // I ⊗ 𝑍\n",
" Z(q);\n",
" \n",
" // diag(1, H, 1)\n",
" CNOT(a, q);\n",
" Controlled H([q], a);\n",
" CNOT(a, q);\n",
" \n",
" // S ⊗ I\n",
" S(a);\n",
" use a = Qubit();\n",
" // I ⊗ 𝑍\n",
" Z(q);\n",
"\n",
" // Ry + row/column reordering\n",
" CNOT(a, q);\n",
" X(q);\n",
" let alpha = ArcCos(Sqrt(2.0 / 3.0));\n",
" (ControlledOnInt(0, Ry))([a], (-2.0 * alpha, q));\n",
" \n",
" // diag(1, H, 1)\n",
" CNOT(a, q);\n",
" Controlled H([q], a);\n",
" CNOT(a, q);\n",
" // diag(1, H, 1)\n",
" CNOT(a, q);\n",
" Controlled H([q], a);\n",
" CNOT(a, q);\n",
"\n",
" // finally, measure in the standard basis\n",
" let res0 = MResetZ(a);\n",
" let res1 = M(q);\n",
" // S ⊗ I\n",
" S(a);\n",
"\n",
" // dispatch on the cases\n",
" if (res0 == Zero and res1 == Zero) {\n",
" return 0;\n",
" }\n",
" elif (res0 == One and res1 == Zero) {\n",
" return 1;\n",
" }\n",
" elif (res0 == Zero and res1 == One) {\n",
" return 2;\n",
" }\n",
" else {\n",
" // this should never occur\n",
" return 3;\n",
" }\n",
" // Ry + row/column reordering\n",
" CNOT(a, q);\n",
" X(q);\n",
" let alpha = ArcCos(Sqrt(2.0 / 3.0));\n",
" (ControlledOnInt(0, Ry))([a], (-2.0 * alpha, q));\n",
"\n",
" // diag(1, H, 1)\n",
" CNOT(a, q);\n",
" Controlled H([q], a);\n",
" CNOT(a, q);\n",
"\n",
" // finally, measure in the standard basis\n",
" let res0 = MResetZ(a);\n",
" let res1 = M(q);\n",
"\n",
" // dispatch on the cases\n",
" if (res0 == Zero and res1 == Zero) {\n",
" return 0;\n",
" }\n",
" elif (res0 == One and res1 == Zero) {\n",
" return 1;\n",
" }\n",
" elif (res0 == Zero and res1 == One) {\n",
" return 2;\n",
" }\n",
" else {\n",
" // this should never occur\n",
" return 3;\n",
" }\n",
"}"
]
@ -385,7 +384,7 @@
"file_extension": ".qs",
"mimetype": "text/x-qsharp",
"name": "qsharp",
"version": "0.12"
"version": "0.14"
}
},
"nbformat": 4,

Просмотреть файл

@ -124,10 +124,9 @@ namespace Quantum.Kata.Superposition {
// Input: N qubits in |0...0⟩ state.
// Goal: create a GHZ state (|0...0⟩ + |1...1⟩) / sqrt(2) on these qubits.
operation GHZ_State_Reference (qs : Qubit[]) : Unit is Adj {
H(Head(qs));
for (q in Rest(qs)) {
for q in Rest(qs) {
CNOT(Head(qs), q);
}
}
@ -138,8 +137,7 @@ namespace Quantum.Kata.Superposition {
// Goal: create an equal superposition of all basis vectors from |0...0⟩ to |1...1⟩
// (i.e. state (|0...0⟩ + ... + |1...1⟩) / sqrt(2^N) ).
operation AllBasisVectorsSuperposition_Reference (qs : Qubit[]) : Unit is Adj {
for (q in qs) {
for q in qs {
H(q);
}
}
@ -152,8 +150,7 @@ namespace Quantum.Kata.Superposition {
// Goal: create a superposition of all even numbers on N qubits if isEven is true,
// or a superposition of all odd numbers on N qubits if isEven is false.
operation EvenOddNumbersSuperposition_Reference (qs : Qubit[], isEven : Bool) : Unit is Adj {
for (q in Most(qs)) {
for q in Most(qs) {
H(q);
}
// for odd numbers, flip the last bit to 1
@ -181,7 +178,7 @@ namespace Quantum.Kata.Superposition {
H(Head(qs));
// iterate through the bit string and CNOT to qubits corresponding to true bits
for (i in 1 .. Length(qs) - 1) {
for i in 1 .. Length(qs) - 1 {
if (bits[i]) {
CNOT(Head(qs), qs[i]);
}
@ -201,7 +198,7 @@ namespace Quantum.Kata.Superposition {
// helper function for TwoBitstringSuperposition_Reference
function FindFirstDiff_Reference (bits1 : Bool[], bits2 : Bool[]) : Int {
for (i in 0 .. Length(bits1) - 1) {
for i in 0 .. Length(bits1) - 1 {
if (bits1[i] != bits2[i]) {
return i;
}
@ -218,7 +215,7 @@ namespace Quantum.Kata.Superposition {
H(qs[firstDiff]);
// iterate through the bit strings again setting the final state of qubits
for (i in 0 .. Length(qs) - 1) {
for i in 0 .. Length(qs) - 1 {
if (bits1[i] == bits2[i]) {
// if two bits are the same apply X or nothing
if (bits1[i]) {
@ -247,27 +244,26 @@ namespace Quantum.Kata.Superposition {
//
// Goal: create an equal superposition of the four basis states given by the bit strings.
operation FourBitstringSuperposition_Reference (qs : Qubit[], bits : Bool[][]) : Unit is Adj {
using (anc = Qubit[2]) {
// Put two ancillas into equal superposition of 2-qubit basis states
ApplyToEachA(H, anc);
use anc = Qubit[2];
// Put two ancillas into equal superposition of 2-qubit basis states
ApplyToEachA(H, anc);
// Set up the right pattern on the main qubits with control on ancillas
for (i in 0 .. 3) {
for (j in 0 .. Length(qs) - 1) {
if (bits[i][j]) {
(ControlledOnInt(i, X))(anc, qs[j]);
}
// Set up the right pattern on the main qubits with control on ancillas
for i in 0 .. 3 {
for j in 0 .. Length(qs) - 1 {
if (bits[i][j]) {
(ControlledOnInt(i, X))(anc, qs[j]);
}
}
}
// Uncompute the ancillas, using patterns on main qubits as control
for (i in 0 .. 3) {
if (i % 2 == 1) {
(ControlledOnBitString(bits[i], X))(qs, anc[0]);
}
if (i / 2 == 1) {
(ControlledOnBitString(bits[i], X))(qs, anc[1]);
}
// Uncompute the ancillas, using patterns on main qubits as control
for i in 0 .. 3 {
if (i % 2 == 1) {
(ControlledOnBitString(bits[i], X))(qs, anc[0]);
}
if (i / 2 == 1) {
(ControlledOnBitString(bits[i], X))(qs, anc[1]);
}
}
}
@ -298,17 +294,16 @@ namespace Quantum.Kata.Superposition {
// Alternative solution, based on post-selection
operation AllStatesWithParitySuperposition_Postselection (qs : Qubit[], parity : Int) : Unit {
using (anc = Qubit()) {
// Create equal superposition of all basis states
ApplyToEach(H, qs);
// Calculate the parity of states using CNOTs
ApplyToEach(CNOT(_, anc), qs);
let res = MResetZ(anc);
// Now, if we got measurement result that matches parity, we're good;
// otherwise we can apply X to any one qubit to get our result!
if ((res == Zero ? 0 | 1) != parity) {
X(qs[0]);
}
use anc = Qubit();
// Create equal superposition of all basis states
ApplyToEach(H, qs);
// Calculate the parity of states using CNOTs
ApplyToEach(CNOT(_, anc), qs);
let res = MResetZ(anc);
// Now, if we got measurement result that matches parity, we're good;
// otherwise we can apply X to any one qubit to get our result!
if ((res == Zero ? 0 | 1) != parity) {
X(qs[0]);
}
}
@ -355,18 +350,17 @@ namespace Quantum.Kata.Superposition {
// Alternative solution, based on post-selection
operation ThreeStates_TwoQubits_Postselection (qs : Qubit[]) : Unit {
using (ancilla = Qubit()) {
repeat {
// Create |00⟩ + |01⟩ + |10⟩ + |11⟩ state
ApplyToEach(H, qs);
// Create (|00⟩ + |01⟩ + |10⟩) ⊗ |0⟩ + |11⟩ ⊗ |1⟩
Controlled X(qs, ancilla);
let res = MResetZ(ancilla);
}
until (res == Zero)
fixup {
ResetAll(qs);
}
use ancilla = Qubit();
repeat {
// Create |00⟩ + |01⟩ + |10⟩ + |11⟩ state
ApplyToEach(H, qs);
// Create (|00⟩ + |01⟩ + |10⟩) ⊗ |0⟩ + |11⟩ ⊗ |1⟩
Controlled X(qs, ancilla);
let res = MResetZ(ancilla);
}
until (res == Zero)
fixup {
ResetAll(qs);
}
}
@ -419,15 +413,14 @@ namespace Quantum.Kata.Superposition {
// the next K qubits are in |0...0⟩ state
// allocate ancilla in |+⟩ state
using (anc = Qubit()) {
H(anc);
use anc = Qubit();
H(anc);
for (i in 0 .. K - 1) {
Controlled SWAP([anc], (qs[i], qs[i + K]));
}
for (i in K .. N - 1) {
CNOT(qs[i], anc);
}
for i in 0 .. K - 1 {
Controlled SWAP([anc], (qs[i], qs[i + K]));
}
for i in K .. N - 1 {
CNOT(qs[i], anc);
}
}
}
@ -466,7 +459,7 @@ namespace Quantum.Kata.Superposition {
operation WState_Arbitrary_Iterative (qs : Qubit[]) : Unit is Adj {
let N = Length(qs);
FractionSuperposition(N, qs[0]);
for (i in 1 .. N - 1) {
for i in 1 .. N - 1 {
(ControlledOnInt(0, FractionSuperposition))(qs[0..i-1], (N-i, qs[i]));
}
}
@ -497,28 +490,27 @@ namespace Quantum.Kata.Superposition {
// find the smallest power of 2 which is greater than or equal to N
// as a hack, we know we're not doing it on more than 64 qubits
mutable P = 1;
for (i in 1 .. 6) {
for i in 1 .. 6 {
if (P < N) {
set P *= 2;
}
}
// allocate extra qubits (might be 0 qubits if N is a power of 2)
using (anc = Qubit[P - N]) {
repeat {
// prepare state W_P on original + ancilla qubits
WState_PowerOfTwo(qs + anc);
use anc = Qubit[P - N];
repeat {
// prepare state W_P on original + ancilla qubits
WState_PowerOfTwo(qs + anc);
// measure extra qubits; if all of the results are Zero, we got the right state on main qubits
mutable allZeros = true;
for (i in 0 .. (P - N) - 1) {
if (MResetZ(anc[i]) == One) {
set allZeros = false;
}
// measure extra qubits; if all of the results are Zero, we got the right state on main qubits
mutable allZeros = true;
for i in 0 .. (P - N) - 1 {
if (MResetZ(anc[i]) == One) {
set allZeros = false;
}
}
until (allZeros);
}
until (allZeros);
}
}
}

Просмотреть файл

@ -23,35 +23,34 @@ namespace Quantum.Kata.Superposition {
refImpl : (Qubit[] => Unit is Adj),
verbose : Bool,
testStr : String) : Unit {
using (qs = Qubit[N]) {
if (verbose) {
if (testStr != "") {
Message($"The desired state for {testStr}");
} else {
Message("The desired state:");
}
refImpl(qs);
DumpMachine(());
ResetAll(qs);
use qs = Qubit[N];
if (verbose) {
if (testStr != "") {
Message($"The desired state for {testStr}");
} else {
Message("The desired state:");
}
refImpl(qs);
DumpMachine(());
ResetAll(qs);
}
// apply operation that needs to be tested
testImpl(qs);
// apply operation that needs to be tested
testImpl(qs);
if (verbose) {
Message("The actual state:");
DumpMachine(());
}
if (verbose) {
Message("The actual state:");
DumpMachine(());
}
// apply adjoint reference operation and check that the result is |0⟩
Adjoint refImpl(qs);
// apply adjoint reference operation and check that the result is |0⟩
Adjoint refImpl(qs);
// assert that all qubits end up in |0⟩ state
AssertAllZero(qs);
// assert that all qubits end up in |0⟩ state
AssertAllZero(qs);
if (verbose) {
Message("Test case passed");
}
if (verbose) {
Message("Test case passed");
}
}
@ -111,7 +110,7 @@ namespace Quantum.Kata.Superposition {
// ------------------------------------------------------
@Test("QuantumSimulator")
operation T107_AllBellStates () : Unit {
for (i in 0 .. 3) {
for i in 0 .. 3 {
AssertEqualOnZeroState(2, AllBellStates(_, i), AllBellStates_Reference(_, i), true, $"index = {i}");
}
}
@ -127,7 +126,7 @@ namespace Quantum.Kata.Superposition {
AssertEqualOnZeroState(2, GHZ_State, BellState_Reference, true, "N = 2");
Message("Testing on hidden test cases...");
for (n in 3 .. 9) {
for n in 3 .. 9 {
AssertEqualOnZeroState(n, GHZ_State, GHZ_State_Reference, false, "");
}
}
@ -142,7 +141,7 @@ namespace Quantum.Kata.Superposition {
AssertEqualOnZeroState(2, AllBasisVectorsSuperposition, AllBasisVectorsSuperposition_Reference, true, "N = 2");
Message("Testing on hidden test cases...");
for (n in 3 .. 8) {
for n in 3 .. 8 {
AssertEqualOnZeroState(n, AllBasisVectorsSuperposition, AllBasisVectorsSuperposition_Reference, false, "");
}
}
@ -151,15 +150,15 @@ namespace Quantum.Kata.Superposition {
// ------------------------------------------------------
@Test("QuantumSimulator")
operation T110_EvenOddNumbersSuperposition () : Unit {
for (n in 1 .. 2) {
for (isEven in [false, true]) {
for n in 1 .. 2 {
for isEven in [false, true] {
AssertEqualOnZeroState(n, EvenOddNumbersSuperposition(_, isEven), EvenOddNumbersSuperposition_Reference(_, isEven), true, $"N = {n}, isEven = {isEven}");
}
}
Message("Testing on hidden test cases...");
for (n in 3 .. 8) {
for (isEven in [false, true]) {
for n in 3 .. 8 {
for isEven in [false, true] {
AssertEqualOnZeroState(n, EvenOddNumbersSuperposition(_, isEven), EvenOddNumbersSuperposition_Reference(_, isEven), false, "");
}
}
@ -258,15 +257,15 @@ namespace Quantum.Kata.Superposition {
AssertEqualOnZeroState(4, FourBitstringSuperposition(_, bits), WState_Arbitrary_Reference, false, "");
// random tests
for (N in 3 .. 10) {
for N in 3 .. 10 {
// generate 4 distinct numbers corresponding to the bit strings
mutable numbers = new Int[4];
repeat {
mutable ok = true;
for (i in 0 .. 3) {
for i in 0 .. 3 {
set numbers w/= i <- DrawRandomInt(0, 1 <<< N - 1);
for (j in 0 .. i - 1) {
for j in 0 .. i - 1 {
if (numbers[i] == numbers[j]) {
set ok = false;
}
@ -276,7 +275,7 @@ namespace Quantum.Kata.Superposition {
until (ok);
// convert numbers to bit strings
for (i in 0 .. 3) {
for i in 0 .. 3 {
set bits w/= i <- IntAsBoolArray(numbers[i], N);
}
@ -288,13 +287,13 @@ namespace Quantum.Kata.Superposition {
@Test("QuantumSimulator")
operation T114_AllStatesWithParitySuperposition () : Unit {
// remember to repeat the tests (for the small case of N = 2), lest the post-selection solution doesn't detect failure and retry
for (i in 1 .. 10) {
for (parity in 0 .. 1) {
for i in 1 .. 10 {
for parity in 0 .. 1 {
AssertEqualOnZeroState(2, AllStatesWithParitySuperposition(_, parity), AllStatesWithParitySuperposition_Reference(_, parity), false, "");
}
}
for (N in 3 .. 6) {
for (parity in 0 .. 1) {
for N in 3 .. 6 {
for parity in 0 .. 1 {
AssertEqualOnZeroState(N, AllStatesWithParitySuperposition(_, parity), AllStatesWithParitySuperposition_Reference(_, parity), false, "");
}
}
@ -315,7 +314,7 @@ namespace Quantum.Kata.Superposition {
Message("Testing on hidden test cases...");
AssertEqualOnZeroState(1, ArrayWrapperOperation(UnequalSuperposition(_, 0.0), _), ApplyToEachA(I, _), false, "");
for (i in 1 .. 36) {
for i in 1 .. 36 {
let alpha = ((2.0 * PI()) * IntAsDouble(i)) / 36.0;
AssertEqualOnZeroState(1, ArrayWrapperOperation(UnequalSuperposition(_, alpha), _), ArrayWrapperOperationA(UnequalSuperposition_Reference(_, alpha), _), false, "");
}
@ -370,11 +369,11 @@ namespace Quantum.Kata.Superposition {
AssertEqualOnZeroState(2, WState_Arbitrary, WState_PowerOfTwo_Reference, true, "N = 2");
Message("Testing on hidden test cases...");
for (n in [4, 8, 16]) {
for n in [4, 8, 16] {
AssertEqualOnZeroState(n, WState_Arbitrary, WState_PowerOfTwo_Reference, false, "");
}
for (i in 2 .. 16) {
for i in 2 .. 16 {
AssertEqualOnZeroState(i, WState_Arbitrary, WState_Arbitrary_Reference, false, "");
}
}

Просмотреть файл

@ -74,7 +74,7 @@
" H(qs[0]);\n",
" \n",
" // Library function Rest returns all array elements except for the first one\n",
" for (q in Rest(qs)) {\n",
" for q in Rest(qs) {\n",
" CNOT(qs[0], q);\n",
" }\n",
"}"
@ -133,7 +133,7 @@
"%kata T109_AllBasisVectorsSuperposition\n",
"\n",
"operation AllBasisVectorsSuperposition (qs : Qubit[]) : Unit {\n",
" for (q in qs) {\n",
" for q in qs {\n",
" H(q);\n",
" }\n",
"}"
@ -207,7 +207,7 @@
"\n",
"operation EvenOddNumbersSuperposition (qs : Qubit[], isEven : Bool) : Unit is Adj {\n",
" let N = Length(qs);\n",
" for (i in 0 .. N-2) {\n",
" for i in 0 .. N-2 {\n",
" H(qs[i]);\n",
" }\n",
" // for odd numbers, flip the last bit to 1\n",
@ -278,7 +278,7 @@
"operation ZeroAndBitstringSuperposition (qs : Qubit[], bits : Bool[]) : Unit {\n",
" H(qs[0]);\n",
"\n",
" for (i in 1 .. Length(qs) - 1) {\n",
" for i in 1 .. Length(qs) - 1 {\n",
" if (bits[i]) {\n",
" CNOT(qs[0], qs[i]);\n",
" }\n",
@ -343,21 +343,20 @@
"%kata T112_TwoBitstringSuperposition\n",
"\n",
"operation TwoBitstringSuperposition (qs : Qubit[], bits1 : Bool[], bits2 : Bool[]) : Unit {\n",
" using (q = Qubit()) {\n",
" H(q);\n",
" \n",
" for (i in 0 .. Length(qs) - 1) {\n",
" if (bits1[i]) {\n",
" (ControlledOnInt(0, X))([q], qs[i]);\n",
" }\n",
" if (bits2[i]) {\n",
" (ControlledOnInt(1, X))([q], qs[i]);\n",
" }\n",
" use q = Qubit();\n",
" H(q);\n",
"\n",
" for i in 0 .. Length(qs) - 1 {\n",
" if (bits1[i]) {\n",
" (ControlledOnInt(0, X))([q], qs[i]);\n",
" }\n",
" if (bits2[i]) {\n",
" (ControlledOnInt(1, X))([q], qs[i]);\n",
" }\n",
" \n",
" // uncompute the auxiliary qubit to release it\n",
" (ControlledOnBitString(bits2, X))(qs, q);\n",
" }\n",
"\n",
" // uncompute the auxiliary qubit to release it\n",
" (ControlledOnBitString(bits2, X))(qs, q);\n",
"}"
]
},
@ -379,7 +378,7 @@
"outputs": [],
"source": [
"function FindFirstDiff (bits1 : Bool[], bits2 : Bool[]) : Int {\n",
" for (i in 0 .. Length(bits1) - 1) {\n",
" for i in 0 .. Length(bits1) - 1 {\n",
" if (bits1[i] != bits2[i]) {\n",
" return i;\n",
" }\n",
@ -404,7 +403,7 @@
" H(qs[firstDiff]);\n",
"\n",
" // iterate through the bit strings again setting the final state of qubits\n",
" for (i in 0 .. Length(qs) - 1) {\n",
" for i in 0 .. Length(qs) - 1 {\n",
" if (bits1[i] == bits2[i]) {\n",
" // if two bits are the same, apply X or nothing\n",
" if (bits1[i]) {\n",
@ -486,27 +485,26 @@
"%kata T113_FourBitstringSuperposition\n",
"\n",
"operation FourBitstringSuperposition (qs : Qubit[], bits : Bool[][]) : Unit {\n",
" using (anc = Qubit[2]) {\n",
" // Put two ancillas into equal superposition of 2-qubit basis states\n",
" ApplyToEachA(H, anc);\n",
" use anc = Qubit[2];\n",
" // Put two ancillas into equal superposition of 2-qubit basis states\n",
" ApplyToEachA(H, anc);\n",
"\n",
" // Set up the right pattern on the main qubits with control on ancillas\n",
" for (i in 0 .. 3) {\n",
" for (j in 0 .. Length(qs) - 1) {\n",
" if (bits[i][j]) {\n",
" (ControlledOnInt(i, X))(anc, qs[j]);\n",
" }\n",
" // Set up the right pattern on the main qubits with control on ancillas\n",
" for i in 0 .. 3 {\n",
" for j in 0 .. Length(qs) - 1 {\n",
" if (bits[i][j]) {\n",
" (ControlledOnInt(i, X))(anc, qs[j]);\n",
" }\n",
" }\n",
" }\n",
"\n",
" // Uncompute the ancillas, using patterns on main qubits as control\n",
" for (i in 0 .. 3) {\n",
" if (i % 2 == 1) {\n",
" (ControlledOnBitString(bits[i], X))(qs, anc[0]);\n",
" }\n",
" if (i / 2 == 1) {\n",
" (ControlledOnBitString(bits[i], X))(qs, anc[1]);\n",
" }\n",
" // Uncompute the ancillas, using patterns on main qubits as control\n",
" for i in 0 .. 3 {\n",
" if (i % 2 == 1) {\n",
" (ControlledOnBitString(bits[i], X))(qs, anc[0]);\n",
" }\n",
" if (i / 2 == 1) {\n",
" (ControlledOnBitString(bits[i], X))(qs, anc[1]);\n",
" }\n",
" }\n",
"}"
@ -571,7 +569,7 @@
" \n",
" if (rows >= 1 and currentIndex < Length(qs)) {\n",
" // figure out what percentage of the bits should be |0⟩\n",
" for (row in 0..rows-1) {\n",
" for row in 0 .. rows - 1 {\n",
" if (bits[row][currentIndex]) {\n",
" set oneLeads = oneLeads + [bits[row]];\n",
" } else {\n",
@ -701,13 +699,12 @@
"open Microsoft.Quantum.Measurement;\n",
"\n",
"operation AllStatesWithParitySuperposition (qs : Qubit[], parity : Int) : Unit {\n",
" using (aux = Qubit()) {\n",
" ApplyToEach(H, qs);\n",
" ApplyToEach(CNOT(_, aux), qs);\n",
" let res = M(aux);\n",
" if ((res == Zero ? 0 | 1) != parity) {\n",
" X(qs[0]);\n",
" }\n",
" use aux = Qubit();\n",
" ApplyToEach(H, qs);\n",
" ApplyToEach(CNOT(_, aux), qs);\n",
" let res = M(aux);\n",
" if ((res == Zero ? 0 | 1) != parity) {\n",
" X(qs[0]);\n",
" }\n",
"}"
]
@ -942,17 +939,16 @@
"\n",
"operation ThreeStates_TwoQubits (qs : Qubit[]) : Unit {\n",
" // Initialize the extra qubit\n",
" using (anc = Qubit()) { \n",
" // Using the repeat-until-success pattern to prepare the right state\n",
" repeat {\n",
" ApplyToEach(H, qs);\n",
" Controlled X(qs, anc);\n",
" let res = MResetZ(anc);\n",
" } \n",
" until (res == Zero)\n",
" fixup {\n",
" ResetAll(qs);\n",
" }\n",
" use anc = Qubit();\n",
" // Using the repeat-until-success pattern to prepare the right state\n",
" repeat {\n",
" ApplyToEach(H, qs);\n",
" Controlled X(qs, anc);\n",
" let res = MResetZ(anc);\n",
" } \n",
" until (res == Zero)\n",
" fixup {\n",
" ResetAll(qs);\n",
" }\n",
"}"
]
@ -1370,15 +1366,14 @@
" X(qs[0]);\n",
" } else {\n",
" let K = N / 2;\n",
" using (anc = Qubit()) {\n",
" H(anc);\n",
" \n",
" (ControlledOnInt(0, WState_PowerOfTwo))([anc], qs[0 .. K - 1]);\n",
" (ControlledOnInt(1, WState_PowerOfTwo))([anc], qs[K .. N - 1]);\n",
" use anc = Qubit();\n",
" H(anc);\n",
"\n",
" for (i in K .. N - 1) {\n",
" CNOT(qs[i], anc);\n",
" }\n",
" (ControlledOnInt(0, WState_PowerOfTwo))([anc], qs[0 .. K - 1]);\n",
" (ControlledOnInt(1, WState_PowerOfTwo))([anc], qs[K .. N - 1]);\n",
"\n",
" for i in K .. N - 1 {\n",
" CNOT(qs[i], anc);\n",
" }\n",
" }\n",
"}"
@ -1416,15 +1411,14 @@
" let K = N / 2;\n",
" WState_PowerOfTwo(qs[0 .. K - 1]);\n",
"\n",
" using (anc = Qubit()) {\n",
" H(anc);\n",
" use anc = Qubit();\n",
" H(anc);\n",
"\n",
" for (i in 0 .. K - 1) {\n",
" Controlled SWAP([anc], (qs[i], qs[i + K]));\n",
" }\n",
" for (i in K .. N - 1) {\n",
" CNOT(qs[i], anc);\n",
" }\n",
" for i in 0 .. K - 1 {\n",
" Controlled SWAP([anc], (qs[i], qs[i + K]));\n",
" }\n",
" for i in K .. N - 1 {\n",
" CNOT(qs[i], anc);\n",
" }\n",
" }\n",
"}"
@ -1495,7 +1489,7 @@
"operation WState_Arbitrary (qs : Qubit[]) : Unit {\n",
" let N = Length(qs);\n",
" Ry(2.0 * ArcSin(Sqrt(1.0/IntAsDouble(N))), qs[0]);\n",
" for (i in 1 .. N-1) {\n",
" for i in 1 .. N - 1 {\n",
" (ControlledOnInt(0, Ry(2.0 * ArcSin(Sqrt(1.0/IntAsDouble(N - i))), _)))(qs[0 .. i-1], qs[i]);\n",
" }\n",
"}"
@ -1596,28 +1590,27 @@
" // find the smallest power of 2 which is greater than or equal to N\n",
" // as a hack, we know we're not doing it on more than 64 qubits\n",
" mutable P = 1;\n",
" for (i in 1 .. 6) {\n",
" for i in 1 .. 6 {\n",
" if (P < N) {\n",
" set P *= 2;\n",
" }\n",
" }\n",
"\n",
" // allocate extra qubits (might be 0 qubits if N is a power of 2)\n",
" using (anc = Qubit[P - N]) {\n",
" repeat {\n",
" // prepare state W_P on original + ancilla qubits\n",
" WState_PowerOfTwo(qs + anc);\n",
" use anc = Qubit[P - N];\n",
" repeat {\n",
" // prepare state W_P on original + ancilla qubits\n",
" WState_PowerOfTwo(qs + anc);\n",
"\n",
" // measure extra qubits; if all of the results are Zero, we got the right state on main qubits\n",
" mutable allZeros = true;\n",
" for (i in 0 .. (P - N) - 1) {\n",
" if (MResetZ(anc[i]) == One) {\n",
" set allZeros = false;\n",
" }\n",
" // measure extra qubits; if all of the results are Zero, we got the right state on main qubits\n",
" mutable allZeros = true;\n",
" for i in 0 .. (P - N) - 1 {\n",
" if (MResetZ(anc[i]) == One) {\n",
" set allZeros = false;\n",
" }\n",
" }\n",
" until (allZeros);\n",
" }\n",
" until (allZeros);\n",
" }\n",
"}"
]
@ -1640,7 +1633,7 @@
"file_extension": ".qs",
"mimetype": "text/x-qsharp",
"name": "qsharp",
"version": "0.12"
"version": "0.14"
}
},
"nbformat": 4,

Просмотреть файл

@ -20,16 +20,15 @@ namespace Quantum.Kata.MultiQubitGates {
operation AssertEqualOnZeroState (testImpl : (Qubit[] => Unit), refImpl : (Qubit[] => Unit is Adj)) : Unit {
using (qs = Qubit[2]) {
// apply operation that needs to be tested
testImpl(qs);
use qs = Qubit[2];
// apply operation that needs to be tested
testImpl(qs);
// apply adjoint reference operation
Adjoint refImpl(qs);
// apply adjoint reference operation
Adjoint refImpl(qs);
// assert that all qubits end up in |0⟩ state
AssertAllZero(qs);
}
// assert that all qubits end up in |0⟩ state
AssertAllZero(qs);
}
@Test("QuantumSimulator")
@ -39,9 +38,9 @@ namespace Quantum.Kata.MultiQubitGates {
@Test("QuantumSimulator")
operation T3_QubitSwap () : Unit {
for (N in 2 .. 5) {
for (j in 0 .. N-2) {
for (k in j+1 .. N-1) {
for N in 2 .. 5 {
for j in 0 .. N-2 {
for k in j+1 .. N-1 {
AssertOperationsEqualReferenced(N, QubitSwap(_, j, k), QubitSwap_Reference(_, j, k));
}
}
@ -50,7 +49,7 @@ namespace Quantum.Kata.MultiQubitGates {
@Test("QuantumSimulator")
operation T4_ControlledRotation () : Unit {
for (i in 0 .. 20) {
for i in 0 .. 20 {
let angle = IntAsDouble(i) / 10.0;
AssertOperationsEqualReferenced(2, ControlledRotation(_, angle), ControlledRotation_Reference(_,angle));
}
@ -63,7 +62,7 @@ namespace Quantum.Kata.MultiQubitGates {
@Test("QuantumSimulator")
operation T5_MultiControls () : Unit {
for (i in 0 .. (2 ^ 4) - 1) {
for i in 0 .. (2 ^ 4) - 1 {
let bits = IntAsBoolArray(i, 4);
AssertOperationsEqualReferenced(5, ArrayControlledOperationWrapper(MultiControls(_, _, bits), _), ArrayControlledOperationWrapper(MultiControls_Reference(_, _, bits), _));
}

Просмотреть файл

@ -279,59 +279,51 @@
"\n",
"open Microsoft.Quantum.Diagnostics;\n",
"\n",
"operation MultiQubitSystems_Demo () : Unit {\n",
" let divider = \"--------------------------------------------------------------------------------------------------\";\n",
" \n",
"operation MultiQubitSystemsDemo () : Unit {\n",
" // This allocates an array of 2 qubits, each of them in state |0⟩.\n",
" // The overall state of the system is |00⟩\n",
" using (qs = Qubit[2]) {\n",
" // X gate changes the first qubit into state |1⟩\n",
" // The entire system is now in state |10⟩\n",
" X(qs[0]);\n",
" \n",
" Message(\"System in state |10⟩:\");\n",
" DumpMachine();\n",
" Message(divider);\n",
" \n",
" // This changes the second qubit into state |+⟩ = (1/sqrt(2))(|0⟩ + |1⟩).\n",
" // The entire system is now in state (1/sqrt(2))(|10⟩ + |11⟩)\n",
" H(qs[1]);\n",
" \n",
" Message(\"System in state (1/sqrt(2))(|10⟩ + |11⟩):\");\n",
" DumpMachine();\n",
" Message(divider);\n",
" \n",
" // This changes the first qubit into state |-⟩ = (1/sqrt(2))(|0⟩ - |1⟩)\n",
" // The entire system is now in state 0.5(|00⟩ + |01⟩ - |10⟩ - |11⟩)\n",
" H(qs[0]);\n",
" \n",
" Message(\"System in state 0.5(|00⟩ + |01⟩ - |10⟩ - |11⟩):\");\n",
" DumpMachine();\n",
" Message(divider);\n",
" \n",
" // You can use DumpRegister to examine the state of specific qubits rather than the entire simulator.\n",
" // This prints the state of the first qubit\n",
" Message(\"First qubit (in state |-⟩ = (1/sqrt(2))(|0⟩ - |1⟩):\");\n",
" DumpRegister((), [qs[0]]);\n",
" Message(divider);\n",
" \n",
" // The next lines entangle the qubits.\n",
" // Don't worry about what exactly they do for now\n",
" H(qs[1]);\n",
" CNOT(qs[0], qs[1]);\n",
" \n",
" Message(\"Entangled state 0.5(|00⟩ - |11⟩):\");\n",
" DumpMachine();\n",
" Message(divider);\n",
" \n",
" // Since the states of entangled qubits are inseparable,\n",
" // it makes no sense to examine only one of them\n",
" Message(\"Let's try to examine one of two entangled qubits on its own...\");\n",
" DumpRegister((), [qs[0]]);\n",
" \n",
" // This returns the system into state |00⟩\n",
" ResetAll(qs);\n",
" }\n",
" use qs = Qubit[2];\n",
" // X gate changes the first qubit into state |1⟩\n",
" // The entire system is now in state |10⟩\n",
" X(qs[0]);\n",
"\n",
" Message(\"System in state |10⟩:\");\n",
" DumpMachine();\n",
"\n",
" // This changes the second qubit into state |+⟩ = (1/sqrt(2))(|0⟩ + |1⟩).\n",
" // The entire system is now in state (1/sqrt(2))(|10⟩ + |11⟩)\n",
" H(qs[1]);\n",
"\n",
" Message(\"System in state (1/sqrt(2))(|10⟩ + |11⟩):\");\n",
" DumpMachine();\n",
"\n",
" // This changes the first qubit into state |-⟩ = (1/sqrt(2))(|0⟩ - |1⟩)\n",
" // The entire system is now in state 0.5(|00⟩ + |01⟩ - |10⟩ - |11⟩)\n",
" H(qs[0]);\n",
"\n",
" Message(\"System in state 0.5(|00⟩ + |01⟩ - |10⟩ - |11⟩):\");\n",
" DumpMachine();\n",
"\n",
" // You can use DumpRegister to examine the state of specific qubits rather than the entire simulator.\n",
" // This prints the state of the first qubit\n",
" Message(\"First qubit (in state |-⟩ = (1/sqrt(2))(|0⟩ - |1⟩):\");\n",
" DumpRegister((), [qs[0]]);\n",
"\n",
" // The next lines entangle the qubits.\n",
" // Don't worry about what exactly they do for now\n",
" H(qs[1]);\n",
" CNOT(qs[0], qs[1]);\n",
"\n",
" Message(\"Entangled state 0.5(|00⟩ - |11⟩):\");\n",
" DumpMachine();\n",
"\n",
" // Since the states of entangled qubits are inseparable,\n",
" // it makes no sense to examine only one of them\n",
" Message(\"Let's try to examine one of two entangled qubits on its own...\");\n",
" DumpRegister((), [qs[0]]);\n",
"\n",
" // This returns the system into state |00⟩\n",
" ResetAll(qs);\n",
"}"
]
},
@ -343,7 +335,7 @@
},
"outputs": [],
"source": [
"%simulate MultiQubitSystems_Demo"
"%simulate MultiQubitSystemsDemo"
]
},
{
@ -535,7 +527,7 @@
"file_extension": ".qs",
"mimetype": "text/x-qsharp",
"name": "qsharp",
"version": "0.12"
"version": "0.14"
}
},
"nbformat": 4,

Просмотреть файл

@ -13,21 +13,20 @@ namespace Quantum.Kata.MultiQubitSystems {
// ------------------------------------------------------
operation AssertEqualOnZeroState (testImpl : (Qubit[] => Unit is Ctl), refImpl : (Qubit[] => Unit is Adj+Ctl)) : Unit {
using (qs = Qubit[3]) {
within {
H(qs[0]);
}
apply {
// apply operation that needs to be tested
Controlled testImpl([qs[0]], qs[1..2]);
// apply adjoint reference operation
Adjoint Controlled refImpl([qs[0]], qs[1..2]);
}
// assert that all qubits end up in |0⟩ state
AssertAllZero(qs);
use qs = Qubit[3];
within {
H(qs[0]);
}
apply {
// apply operation that needs to be tested
Controlled testImpl([qs[0]], qs[1..2]);
// apply adjoint reference operation
Adjoint Controlled refImpl([qs[0]], qs[1..2]);
}
// assert that all qubits end up in |0⟩ state
AssertAllZero(qs);
}
@Test("QuantumSimulator")

Просмотреть файл

@ -153,6 +153,16 @@
"\n",
"```c#\n",
"// This statement allocates a qubit, and binds it to the variable q\n",
"use q = Qubit();\n",
"// You can work with the qubit here\n",
"// ...\n",
"\n",
"// The qubit is deallocated once it's not used any longer\n",
"```\n",
"\n",
"> Before Q# 0.15 the syntax for qubit allocation was different:\n",
"```c#\n",
"// This statement allocates a qubit, and binds it to the variable q\n",
"using (q = Qubit()) {\n",
" // You can work with the qubit here\n",
" // ...\n",
@ -160,7 +170,7 @@
"// The qubit is no longer allocated outside of the 'using' block\n",
"```\n",
"\n",
"Freshly allocated qubits start out in state $|0\\rangle$, and have to be returned to that state at the end of the block. If you attempt to release a qubit in any state other than $|0\\rangle$, your program will throw a `ReleasedQubitsAreNotInZeroStateException`. We will see why it is important later, when we look at multi-qubit systems."
"Freshly allocated qubits start out in state $|0\\rangle$, and have to be returned to that state by the time they are released. If you attempt to release a qubit in any state other than $|0\\rangle$, your program will throw a `ReleasedQubitsAreNotInZeroStateException`. We will see why it is important later, when we look at multi-qubit systems."
]
},
{
@ -202,52 +212,45 @@
"\n",
"open Microsoft.Quantum.Diagnostics;\n",
"\n",
"operation Qubits_Demo () : Unit {\n",
" let divider = \"--------------------------------------------------------------------------------------------------\";\n",
" \n",
"operation QubitsDemo () : Unit {\n",
" // This line allocates a qubit in state |0⟩\n",
" using (q = Qubit()) {\n",
" Message(\"State |0⟩:\");\n",
" \n",
" // This line prints out the state of the quantum computer\n",
" // Since only one qubit is allocated, only its state is printed\n",
" DumpMachine();\n",
" Message(divider);\n",
" \n",
" // This line changes the qubit from state |0⟩ to state |1⟩\n",
" X(q);\n",
" \n",
" Message(\"State |1⟩:\");\n",
" DumpMachine();\n",
" Message(divider);\n",
" \n",
" // This line changes the qubit to state |-⟩ = (1/sqrt(2))(|0⟩ - |1⟩)\n",
" // That is, this puts the qubit into a superposition\n",
" // 1/sqrt(2) is approximately 0.707107\n",
" H(q);\n",
" \n",
" Message(\"State |-⟩:\");\n",
" DumpMachine();\n",
" Message(divider);\n",
" \n",
" // This line changes the qubit to state |-i⟩ = (1/sqrt(2))(|0⟩ - i|1⟩)\n",
" S(q);\n",
" \n",
" Message(\"State |-i⟩:\");\n",
" DumpMachine();\n",
" Message(divider);\n",
" \n",
" // This will put the qubit into an uneven superposition,\n",
" // where the amplitudes of |0⟩ and |1⟩ have different moduli\n",
" Rx(2.0, q);\n",
" Ry(1.0, q);\n",
" \n",
" Message(\"Uneven superposition state:\");\n",
" DumpMachine();\n",
" \n",
" // This line returns the qubit to state |0⟩\n",
" Reset(q);\n",
" }\n",
" use q = Qubit();\n",
" Message(\"State |0⟩:\");\n",
"\n",
" // This line prints out the state of the quantum computer\n",
" // Since only one qubit is allocated, only its state is printed\n",
" DumpMachine();\n",
"\n",
" // This line changes the qubit from state |0⟩ to state |1⟩\n",
" X(q);\n",
"\n",
" Message(\"State |1⟩:\");\n",
" DumpMachine();\n",
"\n",
" // This line changes the qubit to state |-⟩ = (1/sqrt(2))(|0⟩ - |1⟩)\n",
" // That is, this puts the qubit into a superposition\n",
" // 1/sqrt(2) is approximately 0.707107\n",
" H(q);\n",
"\n",
" Message(\"State |-⟩:\");\n",
" DumpMachine();\n",
"\n",
" // This line changes the qubit to state |-i⟩ = (1/sqrt(2))(|0⟩ - i|1⟩)\n",
" S(q);\n",
"\n",
" Message(\"State |-i⟩:\");\n",
" DumpMachine();\n",
"\n",
" // This will put the qubit into an uneven superposition,\n",
" // where the amplitudes of |0⟩ and |1⟩ have different moduli\n",
" Rx(2.0, q);\n",
" Ry(1.0, q);\n",
"\n",
" Message(\"Uneven superposition state:\");\n",
" DumpMachine();\n",
"\n",
" // This line returns the qubit to state |0⟩\n",
" Reset(q);\n",
"}"
]
},
@ -257,7 +260,7 @@
"metadata": {},
"outputs": [],
"source": [
"%simulate Qubits_Demo"
"%simulate QubitsDemo"
]
},
{
@ -295,7 +298,7 @@
"file_extension": ".qs",
"mimetype": "text/x-qsharp",
"name": "qsharp",
"version": "0.12"
"version": "0.14"
}
},
"nbformat": 4,

Просмотреть файл

@ -368,39 +368,34 @@
"// To use a namespace, you need to use the `open` keyword to access it\n",
"open Microsoft.Quantum.Diagnostics;\n",
"\n",
"operation PauliGates_Demo () : Unit {\n",
" let divider = \"--------------------------------------------------------------------------------------------------\";\n",
"operation PauliGatesDemo () : Unit {\n",
" // This allocates a qubit for us to work with\n",
" using (q = Qubit()) {\n",
" \n",
" // This will put the qubit into an uneven superposition |𝜓❭,\n",
" // where the amplitudes of |0⟩ and |1⟩ have different moduli\n",
" Ry(1.0, q);\n",
" use q = Qubit();\n",
"\n",
" Message(\"Qubit in state |𝜓❭:\");\n",
" DumpMachine();\n",
" Message(divider);\n",
" \n",
" // Let's apply the X gate; notice how it swaps the amplitudes of the |0❭ and |1❭ basis states\n",
" X(q);\n",
" Message(\"Qubit in state X|𝜓❭:\");\n",
" DumpMachine();\n",
" Message(divider);\n",
" \n",
" // Applying the Z gate adds -1 relative phase to the |1❭ basis states\n",
" Z(q);\n",
" Message(\"Qubit in state ZX|𝜓❭:\");\n",
" DumpMachine();\n",
" Message(divider);\n",
" \n",
" // Finally, applying the Y gate returns the qubit to its original state |𝜓❭, with an extra global phase of i\n",
" Y(q);\n",
" Message(\"Qubit in state YZX|𝜓❭:\");\n",
" DumpMachine();\n",
" \n",
" // This returns the qubit into state |0❭\n",
" Reset(q);\n",
" }\n",
" // This will put the qubit into an uneven superposition |𝜓❭,\n",
" // where the amplitudes of |0⟩ and |1⟩ have different moduli\n",
" Ry(1.0, q);\n",
"\n",
" Message(\"Qubit in state |𝜓❭:\");\n",
" DumpMachine();\n",
"\n",
" // Let's apply the X gate; notice how it swaps the amplitudes of the |0❭ and |1❭ basis states\n",
" X(q);\n",
" Message(\"Qubit in state X|𝜓❭:\");\n",
" DumpMachine();\n",
"\n",
" // Applying the Z gate adds -1 relative phase to the |1❭ basis states\n",
" Z(q);\n",
" Message(\"Qubit in state ZX|𝜓❭:\");\n",
" DumpMachine();\n",
"\n",
" // Finally, applying the Y gate returns the qubit to its original state |𝜓❭, with an extra global phase of i\n",
" Y(q);\n",
" Message(\"Qubit in state YZX|𝜓❭:\");\n",
" DumpMachine();\n",
"\n",
" // This returns the qubit into state |0❭\n",
" Reset(q);\n",
"}"
]
},
@ -408,7 +403,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"In the previous tutorials we used `%simulate` command to run the Q# code on the full-state simulator. Here we will use `%trace` command: it will run the code on the full-state simulator as well, but will also print the circuit diagram of the run after the output."
"In the previous tutorials we used `%simulate` command to run the Q# code on the full-state simulator. Here we will use an additional `%trace` command: it will print the circuit diagram of the run after the output."
]
},
{
@ -419,7 +414,8 @@
},
"outputs": [],
"source": [
"%trace PauliGates_Demo"
"%simulate PauliGatesDemo\n",
"%trace PauliGatesDemo"
]
},
{
@ -906,7 +902,7 @@
"file_extension": ".qs",
"mimetype": "text/x-qsharp",
"name": "qsharp",
"version": "0.12"
"version": "0.14"
}
},
"nbformat": 4,

Просмотреть файл

@ -29,21 +29,20 @@ namespace Quantum.Kata.SingleQubitGates {
// ------------------------------------------------------
operation AssertEqualOnZeroState (testImpl : (Qubit => Unit is Ctl), refImpl : (Qubit => Unit is Adj+Ctl)) : Unit {
using (qs = Qubit[2]) {
within {
H(qs[0]);
}
apply {
// apply operation that needs to be tested
Controlled testImpl([qs[0]], qs[1]);
// apply adjoint reference operation
Adjoint Controlled refImpl([qs[0]], qs[1]);
}
// assert that all qubits end up in |0⟩ state
AssertAllZero(qs);
use qs = Qubit[2];
within {
H(qs[0]);
}
apply {
// apply operation that needs to be tested
Controlled testImpl([qs[0]], qs[1]);
// apply adjoint reference operation
Adjoint Controlled refImpl([qs[0]], qs[1]);
}
// assert that all qubits end up in |0⟩ state
AssertAllZero(qs);
}
// Exercise 1.
@ -79,7 +78,7 @@ namespace Quantum.Kata.SingleQubitGates {
// Exercise 6.
@Test("QuantumSimulator")
operation T6_PrepareRotatedState () : Unit {
for (i in 0 .. 10) {
for i in 0 .. 10 {
AssertEqualOnZeroState(PrepareRotatedState(Cos(IntAsDouble(i)), Sin(IntAsDouble(i)), _),
PrepareRotatedState_Reference(Cos(IntAsDouble(i)), Sin(IntAsDouble(i)), _));
}
@ -88,8 +87,8 @@ namespace Quantum.Kata.SingleQubitGates {
// Exercise 7.
@Test("QuantumSimulator")
operation T7_PrepareArbitraryState () : Unit {
for (i in 0 .. 10) {
for (j in 0 .. 10) {
for i in 0 .. 10 {
for j in 0 .. 10 {
AssertEqualOnZeroState(PrepareArbitraryState(Cos(IntAsDouble(i)), Sin(IntAsDouble(i)), IntAsDouble(j), _),
PrepareArbitraryState_Reference(Cos(IntAsDouble(i)), Sin(IntAsDouble(i)), IntAsDouble(j), _));
}

Просмотреть файл

@ -98,21 +98,20 @@
"open Microsoft.Quantum.Math;\n",
"\n",
"operation SimpleMeasurementDemo () : Unit {\n",
" using (q = Qubit()) {\n",
" // Prepare the qubit in the superposition state\n",
" // |𝜓❭ = 0.6 |0❭ + 0.8 |1❭\n",
" Ry(2.0 * ArcTan2(0.8, 0.6), q);\n",
" use q = Qubit();\n",
" // Prepare the qubit in the superposition state\n",
" // |𝜓❭ = 0.6 |0❭ + 0.8 |1❭\n",
" Ry(2.0 * ArcTan2(0.8, 0.6), q);\n",
"\n",
" Message(\"Qubit in state |𝜓❭:\");\n",
" DumpMachine();\n",
" \n",
" Message(\"Measuring the qubit...\");\n",
" let outcome = (M(q) == One ? 1 | 0);\n",
" Message(\"Qubit in state |𝜓❭:\");\n",
" DumpMachine();\n",
"\n",
" Message($\"The measurement outcome is {outcome}.\");\n",
" Message(\"Post-measurement state of the qubit:\");\n",
" DumpMachine();\n",
" }\n",
" Message(\"Measuring the qubit...\");\n",
" let outcome = (M(q) == One ? 1 | 0);\n",
"\n",
" Message($\"The measurement outcome is {outcome}.\");\n",
" Message(\"Post-measurement state of the qubit:\");\n",
" DumpMachine();\n",
"}"
]
},
@ -153,19 +152,18 @@
"operation MeasumentStatisticsDemo () : Unit {\n",
" mutable countZero = 0;\n",
" let numRuns = 100;\n",
" using (q = Qubit()) {\n",
" for (i in 1 .. numRuns) {\n",
" // Prepare the qubit in the superposition state\n",
" // |𝜓❭ = 0.6 |0❭ + 0.8 |1❭\n",
" Ry(2.0 * ArcTan2(0.8, 0.6), q);\n",
" \n",
" // Measure in the computational basis, and update the counts according to the outcomes\n",
" if (M(q) == Zero) {\n",
" set countZero += 1;\n",
" } \n",
" // Reset the qubit for use in the next iteration\n",
" Reset(q);\n",
" }\n",
" use q = Qubit();\n",
" for i in 1 .. numRuns {\n",
" // Prepare the qubit in the superposition state\n",
" // |𝜓❭ = 0.6 |0❭ + 0.8 |1❭\n",
" Ry(2.0 * ArcTan2(0.8, 0.6), q);\n",
"\n",
" // Measure in the computational basis, and update the counts according to the outcomes\n",
" if (M(q) == Zero) {\n",
" set countZero += 1;\n",
" } \n",
" // Reset the qubit for use in the next iteration\n",
" Reset(q);\n",
" }\n",
" let countOne = numRuns - countZero;\n",
" \n",
@ -562,7 +560,7 @@
"file_extension": ".qs",
"mimetype": "text/x-qsharp",
"name": "qsharp",
"version": "0.12"
"version": "0.14"
}
},
"nbformat": 4,

Просмотреть файл

@ -26,34 +26,33 @@ namespace Quantum.Kata.SingleQubitSystemMeasurements {
let nStates = 2;
mutable misclassifications = new Int[nStates];
using (q = Qubit()) {
for (i in 1 .. nTotal) {
// get a random bit to define whether qubit will be in a state corresponding to true return (1) or to false one (0)
// state = 0 false return
// state = 1 true return
let state = DrawRandomInt(0, 1);
use q = Qubit();
for i in 1 .. nTotal {
// get a random bit to define whether qubit will be in a state corresponding to true return (1) or to false one (0)
// state = 0 false return
// state = 1 true return
let state = DrawRandomInt(0, 1);
// do state prep: convert |0⟩ to outcome with false return or to outcome with true return depending on state
statePrep(q, state);
// do state prep: convert |0⟩ to outcome with false return or to outcome with true return depending on state
statePrep(q, state);
// get the solution's answer and verify if NOT a match, then differentiate what kind of mismatch
let ans = testImpl(q);
if (ans != (state == 1)) {
set misclassifications w/= state <- misclassifications[state] + 1;
}
// get the solution's answer and verify if NOT a match, then differentiate what kind of mismatch
let ans = testImpl(q);
if (ans != (state == 1)) {
set misclassifications w/= state <- misclassifications[state] + 1;
}
// If the final state is to be verified, check if it matches the measurement outcome
if (checkFinalState) {
Adjoint statePrep(q, state);
AssertQubit(Zero, q);
} else {
Reset(q);
}
// If the final state is to be verified, check if it matches the measurement outcome
if (checkFinalState) {
Adjoint statePrep(q, state);
AssertQubit(Zero, q);
} else {
Reset(q);
}
}
mutable totalMisclassifications = 0;
for (i in 0 .. nStates - 1) {
for i in 0 .. nStates - 1 {
if (misclassifications[i] != 0) {
set totalMisclassifications += misclassifications[i];
Message($"Misclassified {stateName[i]} as {stateName[1 - i]} in {misclassifications[i]} test runs.");
@ -144,7 +143,7 @@ namespace Quantum.Kata.SingleQubitSystemMeasurements {
@Test("QuantumSimulator")
operation T6_IsQubitA () : Unit {
for (i in 0 .. 10) {
for i in 0 .. 10 {
let alpha = (PI() * IntAsDouble(i)) / 10.0;
DistinguishTwoStates(StatePrep_IsQubitA(alpha, _, _), IsQubitA(alpha, _),
[$"|B⟩ = -i sin({i}π/10)|0⟩ + cos({i}π/10)|1⟩", $"|A⟩ = cos({i}π/10)|0⟩ + i sin({i}π/10)|1⟩"], false);
@ -171,7 +170,7 @@ namespace Quantum.Kata.SingleQubitSystemMeasurements {
// We can use the StatePrep_IsQubitA operation for the testing
@Test("QuantumSimulator")
operation T7_MeasureInABBasis () : Unit {
for (i in 0 .. 10) {
for i in 0 .. 10 {
let alpha = (PI() * IntAsDouble(i)) / 10.0;
DistinguishTwoStates(StatePrep_IsQubitA(alpha, _, _), IsResultZero(MeasureInABBasis(alpha, _),_),
[$"|B⟩=(-i sin({i}π/10)|0⟩ + cos({i}π/10)|1⟩)", $"|A⟩=(cos({i}π/10)|0⟩ + i sin({i}π/10)|1⟩)"], true);