qsharp-lang 1.0.5-dev → 1.0.13-dev
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -29,7 +29,7 @@ export default {
|
|
|
29
29
|
"KatasLibrary.qs",
|
|
30
30
|
"getting_started__flip_qubit__Verification.qs"
|
|
31
31
|
],
|
|
32
|
-
"placeholderCode": "namespace Kata {\n operation FlipQubit(q : Qubit): Unit is Adj + Ctl {\n // Uncomment the following line to solve this exercise.\n //X(q);\n }\n}",
|
|
32
|
+
"placeholderCode": "namespace Kata {\n operation FlipQubit(q : Qubit) : Unit is Adj + Ctl {\n // Uncomment the following line to solve this exercise.\n //X(q);\n }\n}\n",
|
|
33
33
|
"explainedSolution": {
|
|
34
34
|
"type": "explained-solution",
|
|
35
35
|
"items": [
|
|
@@ -41,7 +41,7 @@ export default {
|
|
|
41
41
|
{
|
|
42
42
|
"type": "solution",
|
|
43
43
|
"id": "getting_started__flip_qubit_solution",
|
|
44
|
-
"code": "namespace Kata {\n operation FlipQubit(q : Qubit): Unit is Adj + Ctl {\n // Perform a \"bit flip\" on the qubit by applying the X gate.\n X(q);\n }\n}"
|
|
44
|
+
"code": "namespace Kata {\n operation FlipQubit(q : Qubit) : Unit is Adj + Ctl {\n // Perform a \"bit flip\" on the qubit by applying the X gate.\n X(q);\n }\n}\n"
|
|
45
45
|
}
|
|
46
46
|
]
|
|
47
47
|
}
|
|
@@ -113,7 +113,7 @@ export default {
|
|
|
113
113
|
{
|
|
114
114
|
"type": "example",
|
|
115
115
|
"id": "qubit__single_qubit_dump_machine_demo",
|
|
116
|
-
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n\n @EntryPoint()\n operation RunExample(): Unit {\n // This line allocates a qubit in state |0⟩.\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 where the absolute\n // value of the probability amplitudes is 1/sqrt(2), which is
|
|
116
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n\n @EntryPoint()\n operation RunExample() : Unit {\n // This line allocates a qubit in state |0⟩.\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 where the absolute\n // value of the probability amplitudes is 1/sqrt(2), which is\n // 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, where the\n // amplitudes of |0⟩ and |1⟩ have different absolute values.\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⟩, which must be done before\n // the qubit is released or otherwise a runtime error might occur.\n Reset(q);\n }\n}\n"
|
|
117
117
|
},
|
|
118
118
|
{
|
|
119
119
|
"type": "text-content",
|
|
@@ -135,7 +135,7 @@ export default {
|
|
|
135
135
|
"KatasLibrary.qs",
|
|
136
136
|
"qubit__learn_single_qubit_state__Verification.qs"
|
|
137
137
|
],
|
|
138
|
-
"placeholderCode": "namespace Kata {\n operation LearnSingleQubitState(q: Qubit): (Double, Double) {\n // Implement your solution here...\n\n return (0.0, 0.0);\n }\n}\n",
|
|
138
|
+
"placeholderCode": "namespace Kata {\n operation LearnSingleQubitState(q : Qubit) : (Double, Double) {\n // Implement your solution here...\n\n return (0.0, 0.0);\n }\n}\n",
|
|
139
139
|
"explainedSolution": {
|
|
140
140
|
"type": "explained-solution",
|
|
141
141
|
"items": [
|
|
@@ -165,7 +165,7 @@ export default {
|
|
|
165
165
|
{
|
|
166
166
|
"type": "example",
|
|
167
167
|
"id": "qubit__multi_qubit_dump_machine_demo",
|
|
168
|
-
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n\n @EntryPoint()\n operation MultiQubitDumpMachineDemo(): Unit {\n // This line allocates two qubits in state |00⟩.\n use qs = Qubit[2];\n Message(\"State |00⟩:\");\n\n // This line prints out the state of the quantum system.\n DumpMachine();\n\n // X gate changes the second qubit into state |1⟩.\n // The entire system is now in state |01⟩, or, in little-endian notation, |2⟩.\n X(qs[1]);\n Message(\"State |01⟩:\");\n DumpMachine();\n\n CNOT(qs[1], qs[0]);\n Rx(1.0, qs[0]);\n Ry(2.0, qs[1]);\n Rz(3.0, qs[1]);\n\n Message(\"Uneven superposition state:\");\n DumpMachine();\n\n // This line returns the qubits to state |0⟩ before releasing them.\n ResetAll(qs);\n }\n}\n"
|
|
168
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n\n @EntryPoint()\n operation MultiQubitDumpMachineDemo() : Unit {\n // This line allocates two qubits in state |00⟩.\n use qs = Qubit[2];\n Message(\"State |00⟩:\");\n\n // This line prints out the state of the quantum system.\n DumpMachine();\n\n // X gate changes the second qubit into state |1⟩.\n // The entire system is now in state |01⟩, or, in little-endian notation, |2⟩.\n X(qs[1]);\n Message(\"State |01⟩:\");\n DumpMachine();\n\n CNOT(qs[1], qs[0]);\n Rx(1.0, qs[0]);\n Ry(2.0, qs[1]);\n Rz(3.0, qs[1]);\n\n Message(\"Uneven superposition state:\");\n DumpMachine();\n\n // This line returns the qubits to state |0⟩ before releasing them.\n ResetAll(qs);\n }\n}\n"
|
|
169
169
|
}
|
|
170
170
|
]
|
|
171
171
|
},
|
|
@@ -182,7 +182,7 @@ export default {
|
|
|
182
182
|
"KatasLibrary.qs",
|
|
183
183
|
"qubit__learn_basis_state_amplitudes__Verification.qs"
|
|
184
184
|
],
|
|
185
|
-
"placeholderCode": "namespace Kata {\n operation LearnBasisStateAmplitudes(qs: Qubit[]): (Double, Double) {\n // Implement your solution here...\n\n return (0.0, 0.0);\n }\n}\n",
|
|
185
|
+
"placeholderCode": "namespace Kata {\n operation LearnBasisStateAmplitudes(qs : Qubit[]) : (Double, Double) {\n // Implement your solution here...\n\n return (0.0, 0.0);\n }\n}\n",
|
|
186
186
|
"explainedSolution": {
|
|
187
187
|
"type": "explained-solution",
|
|
188
188
|
"items": [
|
|
@@ -194,7 +194,7 @@ export default {
|
|
|
194
194
|
{
|
|
195
195
|
"type": "solution",
|
|
196
196
|
"id": "qubit__learn_basis_state_amplitudes_solution",
|
|
197
|
-
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n\n operation LearnBasisStateAmplitudes(qs: Qubit[]): (Double, Double) {\n DumpMachine(); // Only used to learn the amplitudes.\n return (0.3821, 0.339);\n }\n}\n"
|
|
197
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n\n operation LearnBasisStateAmplitudes(qs : Qubit[]) : (Double, Double) {\n DumpMachine(); // Only used to learn the amplitudes.\n return (0.3821, 0.339);\n }\n}\n"
|
|
198
198
|
}
|
|
199
199
|
]
|
|
200
200
|
}
|
|
@@ -1210,7 +1210,7 @@ export default {
|
|
|
1210
1210
|
{
|
|
1211
1211
|
"type": "solution",
|
|
1212
1212
|
"id": "single_qubit_measurements__distinguish_plus_and_minus_solution",
|
|
1213
|
-
"code": "namespace Kata {\n operation IsQubitMinus(q : Qubit): Bool {\n return Measure([PauliX], [q]) == One;\n }\n\n}\n"
|
|
1213
|
+
"code": "namespace Kata {\n operation IsQubitMinus(q : Qubit) : Bool {\n return Measure([PauliX], [q]) == One;\n }\n\n}\n"
|
|
1214
1214
|
}
|
|
1215
1215
|
]
|
|
1216
1216
|
}
|
|
@@ -1253,7 +1253,7 @@ export default {
|
|
|
1253
1253
|
{
|
|
1254
1254
|
"type": "solution",
|
|
1255
1255
|
"id": "single_qubit_measurements__distinguish_orthogonal_states_1_solution",
|
|
1256
|
-
"code": "namespace Kata {\n open Microsoft.Quantum.Math;\n\n operation IsQubitPsiPlus(q: Qubit): Bool {
|
|
1256
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Math;\n\n operation IsQubitPsiPlus(q : Qubit) : Bool {\n Ry(-2.0 * ArcTan2(0.8, 0.6), q);\n return M(q) == Zero;\n }\n\n}\n"
|
|
1257
1257
|
}
|
|
1258
1258
|
]
|
|
1259
1259
|
}
|
|
@@ -1284,7 +1284,7 @@ export default {
|
|
|
1284
1284
|
{
|
|
1285
1285
|
"type": "solution",
|
|
1286
1286
|
"id": "single_qubit_measurements__distinguish_orthogonal_states_2_solution",
|
|
1287
|
-
"code": "namespace Kata {\n\n operation IsQubitA(alpha: Double, q: Qubit): Bool {
|
|
1287
|
+
"code": "namespace Kata {\n\n operation IsQubitA(alpha : Double, q : Qubit) : Bool {\n Rx(-2.0 * alpha, q);\n return M(q) == Zero;\n }\n\n}\n"
|
|
1288
1288
|
}
|
|
1289
1289
|
]
|
|
1290
1290
|
}
|
|
@@ -1315,7 +1315,7 @@ export default {
|
|
|
1315
1315
|
{
|
|
1316
1316
|
"type": "solution",
|
|
1317
1317
|
"id": "single_qubit_measurements__a_b_basis_measurements_solution",
|
|
1318
|
-
"code": "namespace Kata {\n\n operation MeasureInABBasis(alpha: Double, q: Qubit): Result {\n Rx(-2.0 * alpha, q);\n let measurementResult = M(q);\n Rx(2.0 * alpha, q);\n return measurementResult;\n }\n\n}\n"
|
|
1318
|
+
"code": "namespace Kata {\n\n operation MeasureInABBasis(alpha : Double, q : Qubit) : Result {\n Rx(-2.0 * alpha, q);\n let measurementResult = M(q);\n Rx(2.0 * alpha, q);\n return measurementResult;\n }\n\n}\n"
|
|
1319
1319
|
}
|
|
1320
1320
|
]
|
|
1321
1321
|
}
|
|
@@ -1363,7 +1363,7 @@ export default {
|
|
|
1363
1363
|
{
|
|
1364
1364
|
"type": "example",
|
|
1365
1365
|
"id": "multi_qubit_measurements__multi_qubit_probabilities_2_example",
|
|
1366
|
-
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Math;\n\n operation SetInitialState(qs: Qubit[]): Unit is Adj + Ctl {\n // Next two lines set the second qubit into the desired state\n let second_bit_angle = 2.0 * ArcCos(2.0 / 3.0);\n Ry(second_bit_angle, qs[1]);\n\n // Next two lines set the first qubit into the desired state\n let first_bit_angle = 2.0 * ArcCos(1.0 / Sqrt(5.0));\n Controlled Ry([qs[1]], (first_bit_angle, qs[0]));\n }\n\n operation ChangeBasis(qs: Qubit[]): Unit is Adj + Ctl {\n H(qs[0]);\n H(qs[1]);\n }\n\n @EntryPoint()\n operation CalculateProbabilities(): Unit {\n // This allocates qubits for us to work with\n use qs = Qubit[2];\n\n SetInitialState(qs);\n\n // Check that we've prepared the state |𝜓⟩\n Message(\"The state of the system before the transformation:\");\n DumpMachine();\n\n ChangeBasis(qs);\n\n Message(\"Final state of the two-qubit system:\");\n DumpMachine();\n\n // This returns the qubit array into state |00❭\n ResetAll(qs);\n }\n\n}\n"
|
|
1366
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Math;\n\n operation SetInitialState(qs : Qubit[]) : Unit is Adj + Ctl {\n // Next two lines set the second qubit into the desired state\n let second_bit_angle = 2.0 * ArcCos(2.0 / 3.0);\n Ry(second_bit_angle, qs[1]);\n\n // Next two lines set the first qubit into the desired state\n let first_bit_angle = 2.0 * ArcCos(1.0 / Sqrt(5.0));\n Controlled Ry([qs[1]], (first_bit_angle, qs[0]));\n }\n\n operation ChangeBasis(qs : Qubit[]) : Unit is Adj + Ctl {\n H(qs[0]);\n H(qs[1]);\n }\n\n @EntryPoint()\n operation CalculateProbabilities() : Unit {\n // This allocates qubits for us to work with\n use qs = Qubit[2];\n\n SetInitialState(qs);\n\n // Check that we've prepared the state |𝜓⟩\n Message(\"The state of the system before the transformation:\");\n DumpMachine();\n\n ChangeBasis(qs);\n\n Message(\"Final state of the two-qubit system:\");\n DumpMachine();\n\n // This returns the qubit array into state |00❭\n ResetAll(qs);\n }\n\n}\n"
|
|
1367
1367
|
},
|
|
1368
1368
|
{
|
|
1369
1369
|
"type": "text-content",
|
|
@@ -1385,7 +1385,7 @@ export default {
|
|
|
1385
1385
|
{
|
|
1386
1386
|
"type": "example",
|
|
1387
1387
|
"id": "multi_qubit_measurements__measuring_one_at_a_time",
|
|
1388
|
-
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Arithmetic;\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Math;\n\n @EntryPoint()\n operation DemoBasisMeasurement() : Unit {\n let numRuns = 1000;\n\n // Define coefficients and obtain measurement probabilities for the\n // state |psi❭ = 0.33 |00❭ + 0.67 |01❭ + 0.67 |11❭\n // Use little endian format to encode basis states as integer indices.\n let coefficients = [0.333, 0.0, 0.667, 0.667];\n let expected_probabilities = [0.111, 0.0, 0.445, 0.445];\n\n // Set up counter array for measurements.\n mutable countArray = [0, 0, 0, 0];\n\n use qs = Qubit[2];\n for i in 1 .. numRuns {\n // Prepare the state from Exercise 1:\n PrepareEx1State(qs);\n if i == 1 {\n Message(\"The state |psi❭ of the system before measurement is:\");\n DumpMachine();\n }\n\n // Measure the first qubit, followed by the second qubit, and\n // convert the result to little endian integer\n let result = MeasureInteger(qs);\n\n // Update countArray\n set countArray w/= result <- countArray[result] + 1;\n }\n\n // Obtain simulated probability of measurement for each outcome\n mutable simulated_probabilities = [];\n for i in 0 .. 3 {\n set simulated_probabilities +=\n [IntAsDouble(countArray[i]) / IntAsDouble(numRuns)];\n }\n\n Message($\"Theoretical measurement probabilities are {expected_probabilities}\");\n Message($\"Simulated measurement probabilities are {simulated_probabilities}\");\n }\n\n operation PrepareEx1State(q: Qubit[]): Unit {\n Ry(-ArcCos(1.0/9.0), q[0]);\n within {\n S(q[1]);\n H(q[1]);\n } apply {\n Rz(ArcTan(0.5), q[1]);\n CNOT(q[0], q[1]);\n Rz(ArcTan(0.5)-PI(), q[1]);\n CNOT(q[0], q[1]);\n }\n }\n}"
|
|
1388
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Arithmetic;\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Math;\n\n @EntryPoint()\n operation DemoBasisMeasurement() : Unit {\n let numRuns = 1000;\n\n // Define coefficients and obtain measurement probabilities for the\n // state |psi❭ = 0.33 |00❭ + 0.67 |01❭ + 0.67 |11❭\n // Use little endian format to encode basis states as integer indices.\n let coefficients = [0.333, 0.0, 0.667, 0.667];\n let expected_probabilities = [0.111, 0.0, 0.445, 0.445];\n\n // Set up counter array for measurements.\n mutable countArray = [0, 0, 0, 0];\n\n use qs = Qubit[2];\n for i in 1 .. numRuns {\n // Prepare the state from Exercise 1:\n PrepareEx1State(qs);\n if i == 1 {\n Message(\"The state |psi❭ of the system before measurement is:\");\n DumpMachine();\n }\n\n // Measure the first qubit, followed by the second qubit, and\n // convert the result to little endian integer\n let result = MeasureInteger(qs);\n\n // Update countArray\n set countArray w/= result <- countArray[result] + 1;\n }\n\n // Obtain simulated probability of measurement for each outcome\n mutable simulated_probabilities = [];\n for i in 0 .. 3 {\n set simulated_probabilities +=\n [IntAsDouble(countArray[i]) / IntAsDouble(numRuns)];\n }\n\n Message($\"Theoretical measurement probabilities are {expected_probabilities}\");\n Message($\"Simulated measurement probabilities are {simulated_probabilities}\");\n }\n\n operation PrepareEx1State(q : Qubit[]) : Unit {\n Ry(-ArcCos(1.0/9.0), q[0]);\n within {\n S(q[1]);\n H(q[1]);\n } apply {\n Rz(ArcTan(0.5), q[1]);\n CNOT(q[0], q[1]);\n Rz(ArcTan(0.5)-PI(), q[1]);\n CNOT(q[0], q[1]);\n }\n }\n}\n"
|
|
1389
1389
|
},
|
|
1390
1390
|
{
|
|
1391
1391
|
"type": "text-content",
|
|
@@ -1420,7 +1420,7 @@ export default {
|
|
|
1420
1420
|
{
|
|
1421
1421
|
"type": "solution",
|
|
1422
1422
|
"id": "multi_qubit_measurements__full_measurements_solution",
|
|
1423
|
-
"code": "namespace Kata {\n
|
|
1423
|
+
"code": "namespace Kata {\n\n operation BasisStateMeasurement(qs : Qubit[]) : Int {\n // Measurement on the first qubit gives the higher bit of the answer, on the second - the lower\n let m1 = M(qs[0]) == Zero ? 0 | 1;\n let m2 = M(qs[1]) == Zero ? 0 | 1;\n return m1 * 2 + m2;\n }\n\n}\n"
|
|
1424
1424
|
},
|
|
1425
1425
|
{
|
|
1426
1426
|
"type": "text-content",
|
|
@@ -1460,7 +1460,7 @@ export default {
|
|
|
1460
1460
|
{
|
|
1461
1461
|
"type": "example",
|
|
1462
1462
|
"id": "multi_qubit_measurements__partial_measurements_demo",
|
|
1463
|
-
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Arithmetic;\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Math;\n\n @EntryPoint()\n operation DemoPartialMeasurement() : Unit {\n let numRuns = 1000;\n let divider = \"--------------------------------------------------------------------------------------------------\";\n
|
|
1463
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Arithmetic;\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Math;\n\n @EntryPoint()\n operation DemoPartialMeasurement() : Unit {\n let numRuns = 1000;\n let divider = \"--------------------------------------------------------------------------------------------------\";\n //\n // We can use coefficients without normalization in PrepareArbitraryStateD,\n // the operation will normalize them automatically.\n let coefficients = [3., 1., 1., 1.];\n let expected_probabilities = [0.833, 0.167];\n\n // Set up the counter array for measurements.\n mutable countArray = [0, 0];\n\n use qs = Qubit[2];\n for i in 1 .. numRuns {\n // Prepare the state from Exercise 4:\n // |𝜓❭ = (1/√12)(3|00⟩+|01⟩+|10⟩+|11⟩)\n PrepareHardyState(qs);\n\n // Display the state of the qubits.\n if i == 1 {\n Message(\"The state |𝜓❭ of the system before measurement is:\");\n DumpMachine();\n Message(divider);\n }\n\n // Measure the first qubit.\n let outcome = M(qs[0]) == Zero ? 0 | 1;\n set countArray w/= outcome <- countArray[outcome] + 1;\n\n if countArray[outcome] == 1 {\n // The first time the outcome is 0/1, print the system state afterwards.\n Message(\"For outcome {outcome}, the post-measurement state of the system is:\");\n DumpMachine();\n }\n ResetAll(qs);\n }\n\n // Obtain simulated probability of measurement for each outcome\n mutable simulated_probabilities = [];\n for i in 0 .. 1 {\n set simulated_probabilities += [IntAsDouble(countArray[i]) / IntAsDouble(numRuns)];\n }\n\n Message($\"Theoretical measurement probabilities are {expected_probabilities}\");\n Message($\"Simulated measurement probabilities are {simulated_probabilities}\");\n }\n\n operation PrepareHardyState(q : Qubit[]) : Unit {\n Ry(ArcCos(2.0/3.0), q[1]);\n within {\n S(q[0]);\n H(q[0]);\n } apply {\n CNOT(q[1], q[0]);\n Rz(ArcTan(1.0/2.0), q[0]);\n CNOT(q[1], q[0]);\n Rz(-ArcTan(2.0), q[0]);\n }\n }\n\n}\n"
|
|
1464
1464
|
},
|
|
1465
1465
|
{
|
|
1466
1466
|
"type": "text-content",
|
|
@@ -1495,7 +1495,7 @@ export default {
|
|
|
1495
1495
|
{
|
|
1496
1496
|
"type": "solution",
|
|
1497
1497
|
"id": "multi_qubit_measurements__partial_measurements_for_system_solution",
|
|
1498
|
-
"code": "namespace Kata {\n\n operation IsPlusPlusMinus(qs: Qubit[]): Int {\n return Measure([PauliX], [qs[0]]) == Zero ? 0 | 1;\n }\n\n}\n"
|
|
1498
|
+
"code": "namespace Kata {\n\n operation IsPlusPlusMinus(qs : Qubit[]) : Int {\n return Measure([PauliX], [qs[0]]) == Zero ? 0 | 1;\n }\n\n}\n"
|
|
1499
1499
|
}
|
|
1500
1500
|
]
|
|
1501
1501
|
}
|
|
@@ -1581,7 +1581,7 @@ export default {
|
|
|
1581
1581
|
{
|
|
1582
1582
|
"type": "solution",
|
|
1583
1583
|
"id": "multi_qubit_measurements__state_preparation_solution",
|
|
1584
|
-
"code": "namespace Kata {\n open Microsoft.Quantum.Measurement;\n\n operation PostSelection(qs: Qubit[]): Unit {\n // Initialize the extra qubit\n use anc = Qubit();\n // Using the repeat-until-success pattern to prepare the right state\n mutable res = Zero;\n repeat {\n ApplyToEach(H, qs);\n Controlled X(qs, anc);\n set res = MResetZ(anc);\n }
|
|
1584
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Measurement;\n\n operation PostSelection(qs : Qubit[]) : Unit {\n // Initialize the extra qubit\n use anc = Qubit();\n // Using the repeat-until-success pattern to prepare the right state\n mutable res = Zero;\n repeat {\n ApplyToEach(H, qs);\n Controlled X(qs, anc);\n set res = MResetZ(anc);\n }\n until (res == Zero)\n fixup {\n ResetAll(qs);\n }\n }\n\n}\n"
|
|
1585
1585
|
}
|
|
1586
1586
|
]
|
|
1587
1587
|
}
|
|
@@ -1624,7 +1624,7 @@ export default {
|
|
|
1624
1624
|
{
|
|
1625
1625
|
"type": "solution",
|
|
1626
1626
|
"id": "multi_qubit_measurements__joint_measurements_solution",
|
|
1627
|
-
"code": "namespace Kata {\n\n operation ParityMeasurement(qs: Qubit[]): Int {\n return Measure([PauliZ, PauliZ], qs) == Zero ? 0 | 1;\n }\n
|
|
1627
|
+
"code": "namespace Kata {\n\n operation ParityMeasurement(qs : Qubit[]) : Int {\n return Measure([PauliZ, PauliZ], qs) == Zero ? 0 | 1;\n }\n\n}\n"
|
|
1628
1628
|
}
|
|
1629
1629
|
]
|
|
1630
1630
|
}
|
|
@@ -1740,7 +1740,7 @@ export default {
|
|
|
1740
1740
|
{
|
|
1741
1741
|
"type": "solution",
|
|
1742
1742
|
"id": "random_numbers__random_two_bits_solution",
|
|
1743
|
-
"code": "namespace Kata {\n operation RandomTwoBits(): Int {\n return 2 * RandomBit() + RandomBit();\n }\n\n operation RandomBit() : Int {\n // Allocate single qubit.\n use q = Qubit();\n\n // Set qubit in superposition state.\n H(q);\n\n // Measuring the qubit and reset.\n let result = M(q);\n Reset(q);\n\n // Return integer value of result.\n if result == One {\n return 1;\n }\n return 0;\n }\n}\n"
|
|
1743
|
+
"code": "namespace Kata {\n operation RandomTwoBits() : Int {\n return 2 * RandomBit() + RandomBit();\n }\n\n operation RandomBit() : Int {\n // Allocate single qubit.\n use q = Qubit();\n\n // Set qubit in superposition state.\n H(q);\n\n // Measuring the qubit and reset.\n let result = M(q);\n Reset(q);\n\n // Return integer value of result.\n if result == One {\n return 1;\n }\n return 0;\n }\n}\n"
|
|
1744
1744
|
}
|
|
1745
1745
|
]
|
|
1746
1746
|
}
|
|
@@ -1771,7 +1771,7 @@ export default {
|
|
|
1771
1771
|
{
|
|
1772
1772
|
"type": "solution",
|
|
1773
1773
|
"id": "random_numbers__random_n_bits_solution",
|
|
1774
|
-
"code": "namespace Kata {\n operation RandomNBits(N: Int): Int {\n mutable result = 0;\n for i in 0..(N - 1) {\n set result = result * 2 + RandomBit();\n }\n return result;\n }\n\n operation RandomBit() : Int {\n // Allocate single qubit.\n use q = Qubit();\n\n // Set qubit in superposition state.\n H(q);\n\n // Measuring the qubit and reset.\n let result = M(q);\n Reset(q);\n\n // Return integer value of result.\n if result == One {\n return 1;\n }\n return 0;\n }\n}\n"
|
|
1774
|
+
"code": "namespace Kata {\n operation RandomNBits(N : Int) : Int {\n mutable result = 0;\n for i in 0..(N - 1) {\n set result = result * 2 + RandomBit();\n }\n return result;\n }\n\n operation RandomBit() : Int {\n // Allocate single qubit.\n use q = Qubit();\n\n // Set qubit in superposition state.\n H(q);\n\n // Measuring the qubit and reset.\n let result = M(q);\n Reset(q);\n\n // Return integer value of result.\n if result == One {\n return 1;\n }\n return 0;\n }\n}\n"
|
|
1775
1775
|
}
|
|
1776
1776
|
]
|
|
1777
1777
|
}
|
|
@@ -1802,7 +1802,7 @@ export default {
|
|
|
1802
1802
|
{
|
|
1803
1803
|
"type": "solution",
|
|
1804
1804
|
"id": "random_numbers__weighted_random_bit_solution",
|
|
1805
|
-
"code": "namespace Kata {\n open Microsoft.Quantum.Math;\n\n operation WeightedRandomBit(x : Double): Int {\n // Calculate theta value.\n let theta = 2.0 * ArcCos(Sqrt(x)); // (or) 2.0 * ArcSin(Sqrt(1.0 - x));\n\n // Allocate single qubit.\n use q = Qubit();\n\n // Set qubit in superposition state which aligns with given probabilities.\n Ry(theta, q);\n\n\n // Measuring state of qubit and reset.\n let result = M(q);\n Reset(q);\n\n // Reset qubit and return integer value of result.\n if result == One {\n return 1;\n }\n return 0;\n }\n\n}\n"
|
|
1805
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Math;\n\n operation WeightedRandomBit(x : Double) : Int {\n // Calculate theta value.\n let theta = 2.0 * ArcCos(Sqrt(x)); // (or) 2.0 * ArcSin(Sqrt(1.0 - x));\n\n // Allocate single qubit.\n use q = Qubit();\n\n // Set qubit in superposition state which aligns with given probabilities.\n Ry(theta, q);\n\n\n // Measuring state of qubit and reset.\n let result = M(q);\n Reset(q);\n\n // Reset qubit and return integer value of result.\n if result == One {\n return 1;\n }\n return 0;\n }\n\n}\n"
|
|
1806
1806
|
}
|
|
1807
1807
|
]
|
|
1808
1808
|
}
|
|
@@ -1833,7 +1833,7 @@ export default {
|
|
|
1833
1833
|
{
|
|
1834
1834
|
"type": "solution",
|
|
1835
1835
|
"id": "random_numbers__random_number_solution",
|
|
1836
|
-
"code": "namespace Kata {\n open Microsoft.Quantum.Math;\n\n operation RandomNumberInRange(min: Int, max: Int): Int {\n let nBits = BitSizeI(max - min);\n mutable output = 0
|
|
1836
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Math;\n\n operation RandomNumberInRange(min : Int, max : Int) : Int {\n let nBits = BitSizeI(max - min);\n mutable output = 0;\n repeat {\n set output = RandomNBits(nBits);\n } until output <= max - min;\n return output + min;\n }\n\n operation RandomNBits(N : Int) : Int {\n mutable result = 0;\n for i in 0..(N - 1) {\n set result = result * 2 + RandomBit();\n }\n return result;\n }\n\n operation RandomBit() : Int {\n // Allocate single qubit.\n use q = Qubit();\n\n // Set qubit in superposition state.\n H(q);\n\n // Measuring the qubit and reset.\n let result = M(q);\n Reset(q);\n\n // Return integer value of result.\n if result == One {\n return 1;\n }\n return 0;\n }\n}\n"
|
|
1837
1837
|
}
|
|
1838
1838
|
]
|
|
1839
1839
|
}
|
|
@@ -1901,7 +1901,7 @@ export default {
|
|
|
1901
1901
|
{
|
|
1902
1902
|
"type": "solution",
|
|
1903
1903
|
"id": "oracles__classical_oracles_solution",
|
|
1904
|
-
"code": "namespace Kata {\n open Microsoft.Quantum.Convert;\n\n function IsSeven(x: Bool[]): Bool {\n return BoolArrayAsInt(x) == 7;\n }\n}\n"
|
|
1904
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Convert;\n\n function IsSeven(x : Bool[]) : Bool {\n return BoolArrayAsInt(x) == 7;\n }\n}\n"
|
|
1905
1905
|
}
|
|
1906
1906
|
]
|
|
1907
1907
|
}
|
|
@@ -1931,7 +1931,7 @@ export default {
|
|
|
1931
1931
|
{
|
|
1932
1932
|
"type": "example",
|
|
1933
1933
|
"id": "oracles__phase_oracle_alt_bit",
|
|
1934
|
-
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n\n // This operation implements the oracle; we will learn how to implement oracles later in the kata\n operation AlternatingBitPattern_PhaseOracle(x: Qubit[]): Unit is Adj + Ctl {\n use q = Qubit();\n X(q);\n ApplyControlledOnBitString([false, true, false], Z, x, q);\n ApplyControlledOnBitString([true, false, true], Z, x, q);\n X(q);\n }\n\n @EntryPoint()\n operation PhaseOracle_Demo(): Unit {\n // Allocate 3 qubits in the |000⟩ state\n use q = Qubit[3];\n // Prepare an equal superposition of all basis states\n ApplyToEachA(H, q);\n\n // Print the current state of the system; notice the phases of each basis state\n Message(\"Starting state (equal superposition of all basis states):\");\n DumpMachine();\n\n // Apply the oracle\n AlternatingBitPattern_PhaseOracle(q);\n\n // Print the resulting state; notice which phases changed\n Message(\"State after applying the phase oracle:\");\n DumpMachine();\n\n // Reset our state back to all zeros for deallocation\n ResetAll(q);\n }\n
|
|
1934
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n\n // This operation implements the oracle; we will learn how to implement oracles later in the kata\n operation AlternatingBitPattern_PhaseOracle(x : Qubit[]) : Unit is Adj + Ctl {\n use q = Qubit();\n X(q);\n ApplyControlledOnBitString([false, true, false], Z, x, q);\n ApplyControlledOnBitString([true, false, true], Z, x, q);\n X(q);\n }\n\n @EntryPoint()\n operation PhaseOracle_Demo() : Unit {\n // Allocate 3 qubits in the |000⟩ state\n use q = Qubit[3];\n // Prepare an equal superposition of all basis states\n ApplyToEachA(H, q);\n\n // Print the current state of the system; notice the phases of each basis state\n Message(\"Starting state (equal superposition of all basis states):\");\n DumpMachine();\n\n // Apply the oracle\n AlternatingBitPattern_PhaseOracle(q);\n\n // Print the resulting state; notice which phases changed\n Message(\"State after applying the phase oracle:\");\n DumpMachine();\n\n // Reset our state back to all zeros for deallocation\n ResetAll(q);\n }\n\n}\n"
|
|
1935
1935
|
},
|
|
1936
1936
|
{
|
|
1937
1937
|
"type": "text-content",
|
|
@@ -1961,7 +1961,7 @@ export default {
|
|
|
1961
1961
|
{
|
|
1962
1962
|
"type": "solution",
|
|
1963
1963
|
"id": "oracles__phase_oracle_seven_solution",
|
|
1964
|
-
"code": "namespace Kata {\n open Microsoft.Quantum.Arrays;\n\n operation IsSeven_PhaseOracle(x: Qubit[]): Unit is Adj + Ctl {\n Controlled Z(Most(x), Tail(x));\n }\n}\n"
|
|
1964
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Arrays;\n\n operation IsSeven_PhaseOracle(x : Qubit[]) : Unit is Adj + Ctl {\n Controlled Z(Most(x), Tail(x));\n }\n}\n"
|
|
1965
1965
|
},
|
|
1966
1966
|
{
|
|
1967
1967
|
"type": "text-content",
|
|
@@ -1984,7 +1984,7 @@ export default {
|
|
|
1984
1984
|
{
|
|
1985
1985
|
"type": "example",
|
|
1986
1986
|
"id": "oracles__marking_oracle_alt_bit",
|
|
1987
|
-
"code": "namespace Kata {\n\n open Microsoft.Quantum.Diagnostics;\n\n // This operation implements the oracle; we will learn how to implement oracles later in the kata\n operation AlternatingBitPattern_MarkingOracle(x: Qubit[], y: Qubit) : Unit is Adj + Ctl {\n ApplyControlledOnBitString([false, true, false], X, x, y);\n ApplyControlledOnBitString([true, false, true], X, x, y);\n }\n\n @EntryPoint()\n operation MarkingOracle_Demo() : Unit {\n // Allocate the qubits in the |000⟩|0⟩ state\n use (x, y) = (Qubit[3], Qubit());\n // Prepare an equal superposition of all basis states in the input register\n ApplyToEachA(H, x);\n\n // Print the current state of the system; notice the amplitudes of each basis state\n Message(\"Starting state (equal superposition of all basis states ⊗ |0⟩):\");\n DumpMachine();\n\n // Apply the oracle\n AlternatingBitPattern_MarkingOracle(x, y);\n\n // Print the resulting state; notice which amplitudes changed\n Message(\"State after applying the marking oracle:\");\n DumpMachine();\n\n // Reset our state back to all zeros for deallocation\n ResetAll(x + [y]);\n }\n\n}\n"
|
|
1987
|
+
"code": "namespace Kata {\n\n open Microsoft.Quantum.Diagnostics;\n\n // This operation implements the oracle; we will learn how to implement oracles later in the kata\n operation AlternatingBitPattern_MarkingOracle(x : Qubit[], y : Qubit) : Unit is Adj + Ctl {\n ApplyControlledOnBitString([false, true, false], X, x, y);\n ApplyControlledOnBitString([true, false, true], X, x, y);\n }\n\n @EntryPoint()\n operation MarkingOracle_Demo() : Unit {\n // Allocate the qubits in the |000⟩|0⟩ state\n use (x, y) = (Qubit[3], Qubit());\n // Prepare an equal superposition of all basis states in the input register\n ApplyToEachA(H, x);\n\n // Print the current state of the system; notice the amplitudes of each basis state\n Message(\"Starting state (equal superposition of all basis states ⊗ |0⟩):\");\n DumpMachine();\n\n // Apply the oracle\n AlternatingBitPattern_MarkingOracle(x, y);\n\n // Print the resulting state; notice which amplitudes changed\n Message(\"State after applying the marking oracle:\");\n DumpMachine();\n\n // Reset our state back to all zeros for deallocation\n ResetAll(x + [y]);\n }\n\n}\n"
|
|
1988
1988
|
},
|
|
1989
1989
|
{
|
|
1990
1990
|
"type": "text-content",
|
|
@@ -2007,14 +2007,14 @@ export default {
|
|
|
2007
2007
|
"oracles__common.qs",
|
|
2008
2008
|
"oracles__marking_oracle_seven__verification.qs"
|
|
2009
2009
|
],
|
|
2010
|
-
"placeholderCode": "namespace Kata {\n operation IsSeven_MarkingOracle(x: Qubit[], y: Qubit): Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}\n",
|
|
2010
|
+
"placeholderCode": "namespace Kata {\n operation IsSeven_MarkingOracle(x : Qubit[], y : Qubit) : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}\n",
|
|
2011
2011
|
"explainedSolution": {
|
|
2012
2012
|
"type": "explained-solution",
|
|
2013
2013
|
"items": [
|
|
2014
2014
|
{
|
|
2015
2015
|
"type": "solution",
|
|
2016
2016
|
"id": "oracles__marking_oracle_seven_solution",
|
|
2017
|
-
"code": "namespace Kata {\n operation IsSeven_MarkingOracle(x: Qubit[], y: Qubit) : Unit is Adj + Ctl {\n Controlled X(x, y);\n }\n}\n"
|
|
2017
|
+
"code": "namespace Kata {\n operation IsSeven_MarkingOracle(x : Qubit[], y : Qubit) : Unit is Adj + Ctl {\n Controlled X(x, y);\n }\n}\n"
|
|
2018
2018
|
},
|
|
2019
2019
|
{
|
|
2020
2020
|
"type": "text-content",
|
|
@@ -2057,7 +2057,7 @@ export default {
|
|
|
2057
2057
|
{
|
|
2058
2058
|
"type": "solution",
|
|
2059
2059
|
"id": "oracles__marking_oracle_as_phase_solution",
|
|
2060
|
-
"code": "namespace Kata {\n operation ApplyMarkingOracleAsPhaseOracle(\n markingOracle: ((Qubit[], Qubit) => Unit is Adj + Ctl),\n qubits: Qubit[])\n : Unit is Adj + Ctl {\n use minus = Qubit();\n within {\n X(minus);\n H(minus);\n } apply {\n markingOracle(qubits, minus);\n }\n }\n}\n"
|
|
2060
|
+
"code": "namespace Kata {\n operation ApplyMarkingOracleAsPhaseOracle(\n markingOracle : ((Qubit[], Qubit) => Unit is Adj + Ctl),\n qubits : Qubit[])\n : Unit is Adj + Ctl {\n use minus = Qubit();\n within {\n X(minus);\n H(minus);\n } apply {\n markingOracle(qubits, minus);\n }\n }\n}\n"
|
|
2061
2061
|
}
|
|
2062
2062
|
]
|
|
2063
2063
|
}
|
|
@@ -2075,7 +2075,7 @@ export default {
|
|
|
2075
2075
|
{
|
|
2076
2076
|
"type": "example",
|
|
2077
2077
|
"id": "oracles__oracle_converter_demo",
|
|
2078
|
-
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Arrays;\n\n @EntryPoint()\n operation OracleConverterDemo () : Unit {\n // Allocate the qubits in the state |000⟩\n use register = Qubit[3];\n // Prepare an equal superposition state\n ApplyToEachA(H, register);\n\n Message(\"The equal superposition state:\");\n DumpMachine();\n\n // Apply the `IsSeven_PhaseOracle` from the task on implementing a phase oracle\n IsSeven_PhaseOracle(register);\n\n // Dump the state after application of the oracle\n Message(\"The state after applying the phase oracle IsSeven_PhaseOracle:\");\n DumpMachine();\n\n // Reset the qubits for deallocation\n ResetAll(register);\n\n // Prepare an equal superposition state again\n ApplyToEachA(H, register);\n\n // Apply the `IsSeven_MarkingOracle` from the task on implementing a marking oracle\n // as a phase oracle\n ApplyMarkingOracleAsPhaseOracle(IsSeven_MarkingOracle, register);\n\n // Dump the state after application of the oracle\n Message(\"The state after applying the converted marking oracle IsSeven_MarkingOracle:\");\n DumpMachine();\n\n // reset the qubits for deallocation\n ResetAll(register);\n }\n\n operation IsSeven_PhaseOracle(x : Qubit[]) : Unit is Adj + Ctl {\n Controlled Z(Most(x), Tail(x));\n }\n\n operation IsSeven_MarkingOracle(x: Qubit[], y: Qubit): Unit is Adj + Ctl {\n Controlled X(x, y);\n }\n\n operation ApplyMarkingOracleAsPhaseOracle(\n markingOracle: ((Qubit[], Qubit) => Unit is Adj + Ctl),\n qubits: Qubit[]) : Unit is Adj + Ctl {\n
|
|
2078
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Arrays;\n\n @EntryPoint()\n operation OracleConverterDemo () : Unit {\n // Allocate the qubits in the state |000⟩\n use register = Qubit[3];\n // Prepare an equal superposition state\n ApplyToEachA(H, register);\n\n Message(\"The equal superposition state:\");\n DumpMachine();\n\n // Apply the `IsSeven_PhaseOracle` from the task on implementing a phase oracle\n IsSeven_PhaseOracle(register);\n\n // Dump the state after application of the oracle\n Message(\"The state after applying the phase oracle IsSeven_PhaseOracle:\");\n DumpMachine();\n\n // Reset the qubits for deallocation\n ResetAll(register);\n\n // Prepare an equal superposition state again\n ApplyToEachA(H, register);\n\n // Apply the `IsSeven_MarkingOracle` from the task on implementing a marking oracle\n // as a phase oracle\n ApplyMarkingOracleAsPhaseOracle(IsSeven_MarkingOracle, register);\n\n // Dump the state after application of the oracle\n Message(\"The state after applying the converted marking oracle IsSeven_MarkingOracle:\");\n DumpMachine();\n\n // reset the qubits for deallocation\n ResetAll(register);\n }\n\n operation IsSeven_PhaseOracle(x : Qubit[]) : Unit is Adj + Ctl {\n Controlled Z(Most(x), Tail(x));\n }\n\n operation IsSeven_MarkingOracle(x : Qubit[], y : Qubit) : Unit is Adj + Ctl {\n Controlled X(x, y);\n }\n\n operation ApplyMarkingOracleAsPhaseOracle(\n markingOracle : ((Qubit[], Qubit) => Unit is Adj + Ctl),\n qubits : Qubit[]) : Unit is Adj + Ctl {\n\n use minus = Qubit();\n within {\n X(minus);\n H(minus);\n } apply {\n markingOracle(qubits, minus);\n }\n }\n}\n"
|
|
2079
2079
|
},
|
|
2080
2080
|
{
|
|
2081
2081
|
"type": "text-content",
|
|
@@ -2117,7 +2117,7 @@ export default {
|
|
|
2117
2117
|
{
|
|
2118
2118
|
"type": "solution",
|
|
2119
2119
|
"id": "oracles__or_oracle_solution",
|
|
2120
|
-
"code": "namespace Kata {\n operation Or_Oracle(x: Qubit[], y: Qubit): Unit is Adj + Ctl {\n X(y);\n ApplyControlledOnInt(0, X, x, y);\n }\n}\n"
|
|
2120
|
+
"code": "namespace Kata {\n operation Or_Oracle(x : Qubit[], y : Qubit) : Unit is Adj + Ctl {\n X(y);\n ApplyControlledOnInt(0, X, x, y);\n }\n}\n"
|
|
2121
2121
|
},
|
|
2122
2122
|
{
|
|
2123
2123
|
"type": "text-content",
|
|
@@ -2179,7 +2179,7 @@ export default {
|
|
|
2179
2179
|
{
|
|
2180
2180
|
"type": "solution",
|
|
2181
2181
|
"id": "oracles__or_but_kth_oracle_solution",
|
|
2182
|
-
"code": "namespace Kata {\n operation Or_Oracle(x: Qubit[], y: Qubit): Unit is Adj + Ctl {\n X(y);\n ApplyControlledOnInt(0, X, x, y);\n }\n\n operation OrOfBitsExceptKth_Oracle(x: Qubit[], k: Int): Unit is Adj + Ctl {\n use minus = Qubit();\n within {\n X(minus);\n H(minus);\n } apply {\n Or_Oracle(x[...k-1] + x[k+1...], minus);\n }\n }\n}\n"
|
|
2182
|
+
"code": "namespace Kata {\n operation Or_Oracle(x : Qubit[], y : Qubit) : Unit is Adj + Ctl {\n X(y);\n ApplyControlledOnInt(0, X, x, y);\n }\n\n operation OrOfBitsExceptKth_Oracle(x : Qubit[], k : Int) : Unit is Adj + Ctl {\n use minus = Qubit();\n within {\n X(minus);\n H(minus);\n } apply {\n Or_Oracle(x[...k-1] + x[k+1...], minus);\n }\n }\n}\n"
|
|
2183
2183
|
}
|
|
2184
2184
|
]
|
|
2185
2185
|
}
|
|
@@ -2205,7 +2205,7 @@ export default {
|
|
|
2205
2205
|
{
|
|
2206
2206
|
"type": "solution",
|
|
2207
2207
|
"id": "oracles__bit_pattern_oracle_solution",
|
|
2208
|
-
"code": "namespace Kata {\n operation ArbitraryBitPattern_Oracle(x: Qubit[], y: Qubit, pattern: Bool[])\n : Unit is Adj + Ctl {\n ApplyControlledOnBitString(pattern, X, x, y);\n }\n\n}\n"
|
|
2208
|
+
"code": "namespace Kata {\n operation ArbitraryBitPattern_Oracle(x : Qubit[], y : Qubit, pattern : Bool[])\n : Unit is Adj + Ctl {\n ApplyControlledOnBitString(pattern, X, x, y);\n }\n\n}\n"
|
|
2209
2209
|
}
|
|
2210
2210
|
]
|
|
2211
2211
|
}
|
|
@@ -2231,7 +2231,7 @@ export default {
|
|
|
2231
2231
|
{
|
|
2232
2232
|
"type": "solution",
|
|
2233
2233
|
"id": "oracles__bit_pattern_challenge_solution",
|
|
2234
|
-
"code": "namespace Kata {\n open Microsoft.Quantum.Arrays;\n\n operation ArbitraryBitPattern_Oracle_Challenge(\n x: Qubit[],\n pattern: Bool[])\n : Unit is Adj + Ctl {\n within {\n for i in IndexRange(x) {\n if not pattern[i] {\n X(x[i]);\n }\n }\n } apply {\n Controlled Z(Most(x), Tail(x));\n }\n }\n}\n"
|
|
2234
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Arrays;\n\n operation ArbitraryBitPattern_Oracle_Challenge(\n x : Qubit[],\n pattern : Bool[])\n : Unit is Adj + Ctl {\n within {\n for i in IndexRange(x) {\n if not pattern[i] {\n X(x[i]);\n }\n }\n } apply {\n Controlled Z(Most(x), Tail(x));\n }\n }\n}\n"
|
|
2235
2235
|
}
|
|
2236
2236
|
]
|
|
2237
2237
|
}
|
|
@@ -2250,14 +2250,14 @@ export default {
|
|
|
2250
2250
|
"oracles__common.qs",
|
|
2251
2251
|
"oracles__meeting_oracle__verification.qs"
|
|
2252
2252
|
],
|
|
2253
|
-
"placeholderCode": "namespace Kata {\n operation Meeting_Oracle(x: Qubit[], jasmine: Qubit[], y: Qubit)\n : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}\n",
|
|
2253
|
+
"placeholderCode": "namespace Kata {\n operation Meeting_Oracle(x : Qubit[], jasmine : Qubit[], y : Qubit)\n : Unit is Adj + Ctl {\n // Implement your solution here...\n\n }\n}\n",
|
|
2254
2254
|
"explainedSolution": {
|
|
2255
2255
|
"type": "explained-solution",
|
|
2256
2256
|
"items": [
|
|
2257
2257
|
{
|
|
2258
2258
|
"type": "solution",
|
|
2259
2259
|
"id": "oracles__meeting_oracle_solution",
|
|
2260
|
-
"code": "namespace Kata {\n open Microsoft.Quantum.Arrays;\n\n operation Or_Oracle(x: Qubit[], y: Qubit): Unit is Adj + Ctl {\n X(y);\n ApplyControlledOnInt(0, X, x, y);\n }\n\n operation Meeting_Oracle(x: Qubit[], jasmine: Qubit[], y: Qubit): Unit is Adj + Ctl {\n use q = Qubit[Length(x)];\n within {\n for i in IndexRange(q) {\n // flip q[i] if both x and jasmine are free on the given day\n X(x[i]);\n X(jasmine[i]);\n CCNOT(x[i], jasmine[i], q[i]);\n }\n } apply {\n Or_Oracle(q, y);\n }\n }\n}\n"
|
|
2260
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Arrays;\n\n operation Or_Oracle(x : Qubit[], y : Qubit) : Unit is Adj + Ctl {\n X(y);\n ApplyControlledOnInt(0, X, x, y);\n }\n\n operation Meeting_Oracle(x : Qubit[], jasmine : Qubit[], y : Qubit) : Unit is Adj + Ctl {\n use q = Qubit[Length(x)];\n within {\n for i in IndexRange(q) {\n // flip q[i] if both x and jasmine are free on the given day\n X(x[i]);\n X(jasmine[i]);\n CCNOT(x[i], jasmine[i], q[i]);\n }\n } apply {\n Or_Oracle(q, y);\n }\n }\n}\n"
|
|
2261
2261
|
}
|
|
2262
2262
|
]
|
|
2263
2263
|
}
|
|
@@ -2275,7 +2275,7 @@ export default {
|
|
|
2275
2275
|
{
|
|
2276
2276
|
"type": "example",
|
|
2277
2277
|
"id": "oracles__test_meeting_oracle",
|
|
2278
|
-
"code": "namespace Kata {\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Convert;\n\n // The classical function to perform the same computation\n function Meeting_Classical(x: Bool[], jasmine: Bool[]): Bool {\n for i in IndexRange(x) {\n if ((not x[i]) and (not jasmine[i])) {\n // They have a day that they can both meet\n return true;\n }\n }\n
|
|
2278
|
+
"code": "namespace Kata {\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Convert;\n\n // The classical function to perform the same computation\n function Meeting_Classical(x : Bool[], jasmine : Bool[]) : Bool {\n for i in IndexRange(x) {\n if ((not x[i]) and (not jasmine[i])) {\n // They have a day that they can both meet\n return true;\n }\n }\n\n // At least one of them is busy every day of the week\n return false;\n }\n\n operation Or_Oracle(x : Qubit[], y : Qubit) : Unit is Adj + Ctl {\n X(y);\n ApplyControlledOnInt(0, X, x, y);\n }\n\n operation Meeting_Oracle(x : Qubit[], jasmine : Qubit[], z : Qubit) : Unit is Adj + Ctl {\n use q = Qubit[Length(x)];\n within {\n for i in IndexRange(q) {\n // flip q[i] if both x and jasmine are free on the given day\n X(x[i]);\n X(jasmine[i]);\n CCNOT(x[i], jasmine[i], q[i]);\n }\n } apply {\n Or_Oracle(q, z);\n }\n }\n\n @EntryPoint()\n operation Test_Meeting_Oracle() : Unit {\n // There are 2^5 ways to arrange each of the schedules - let's try all of them\n for k in 0..((2^5)-1) {\n for j in 0..((2^5)-1) {\n // Convert your and Jasmine's schedules to bit arrays\n let binaryX = IntAsBoolArray(k, 5);\n let binaryJasmine = IntAsBoolArray(j, 5);\n\n // Calculate the function classically\n let classicalResult = Meeting_Classical(binaryX, binaryJasmine);\n\n // create a register of qubits so we can represent\n // your schedule, jasmine's schedule, and the output\n use (x, jasmine, target) = (Qubit[5], Qubit[5], Qubit());\n // Prepare the quantum schedules in basis states matching the binary schedules\n ApplyPauliFromBitString(PauliX, true, binaryX, x);\n ApplyPauliFromBitString(PauliX, true, binaryJasmine, jasmine);\n\n // Apply the quantum oracle\n Meeting_Oracle(x, jasmine, target);\n\n // Check that the result of the quantum algorithm matched that\n // of the classical algorithm\n if CheckZero(target) == classicalResult {\n Message($\"Failed on test case k = {k}, j = {j}. Classical result is not the same as target.\");\n }\n\n // Undo the preparation of basis states x and jasmine\n ApplyPauliFromBitString(PauliX, true, binaryX, x);\n ApplyPauliFromBitString(PauliX, true, binaryJasmine, jasmine);\n\n // Check that the oracle did not change its input states\n if not CheckAllZero(x) {\n Message($\"Failed on test case k = {k}, j = {j}. Input state of x changed.\");\n }\n if not CheckAllZero(jasmine) {\n Message($\"Failed on test case k = {k}, j = {j}. Input state of jasmine changed.\");\n }\n\n Reset(target);\n }\n }\n\n Message(\"Success!\");\n }\n\n}\n"
|
|
2279
2279
|
}
|
|
2280
2280
|
]
|
|
2281
2281
|
},
|
|
@@ -2297,19 +2297,19 @@ export default {
|
|
|
2297
2297
|
"globalCodeSources": [
|
|
2298
2298
|
{
|
|
2299
2299
|
"id": "KatasLibrary.qs",
|
|
2300
|
-
"code": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nnamespace Microsoft.Quantum.Katas {\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Intrinsic;\n\n /// # Summary\n /// Given two operations, checks whether they act identically for all input states.\n /// This operation is implemented by using the Choi–Jamiołkowski isomorphism.\n ///\n /// N.B. Investigate whether this can be done using just 1 control qubit (GitHub issue #535).\n operation CheckOperationsEquivalence(\n op : (Qubit[] => Unit is Adj + Ctl),\n reference : (Qubit[] => Unit is Adj + Ctl),\n inputSize: Int)\n : Bool {\n Fact(inputSize > 0, \"`inputSize` must be positive\");\n use (control, target) = (Qubit[inputSize], Qubit[inputSize]);\n within {\n // N.B. The order in which quantum registers are passed to this operation is important.\n EntangleRegisters(control, target);\n }\n apply {\n op(target);\n Adjoint reference(target);\n }\n\n let areEquivalent = CheckAllZero(control + target);\n ResetAll(control + target);\n areEquivalent\n }\n\n /// # Summary\n /// Given two operations, checks whether they act identically (including global phase) for all input states.\n /// This is done through controlled versions of the operations instead of plain ones which convert the global phase\n /// into a relative phase that can be detected.\n operation CheckOperationsEquivalenceStrict(\n op : (Qubit[] => Unit is Adj + Ctl),\n reference : (Qubit[] => Unit is Adj + Ctl),\n inputSize: Int)\n : Bool {\n Fact(inputSize > 0, \"`inputSize` must be positive\");\n let controlledOp = register => Controlled op(register[...0], register[1...]);\n let controlledReference = register => Controlled reference(register[...0], register[1...]);\n let areEquivalent = CheckOperationsEquivalence(controlledOp, controlledReference, inputSize + 1);\n areEquivalent\n }\n\n /// # Summary\n /// Given two operations, checks whether they act identically on the zero state |0〉 ⊗ |0〉 ⊗ ... ⊗ |0〉 composed of\n /// `inputSize` qubits.\n operation CheckOperationsEquivalenceOnZeroState(\n op : (Qubit[] => Unit is Adj + Ctl),\n reference : (Qubit[] => Unit is Adj + Ctl),\n inputSize: Int)\n : Bool {\n Fact(inputSize > 0, \"`inputSize` must be positive\");\n use target = Qubit[inputSize];\n op(target);\n Adjoint reference(target);\n let isCorrect = CheckAllZero(target);\n ResetAll(target);\n isCorrect\n }\n\n /// # Summary\n /// Given two operations, checks whether they act identically on the zero state |0〉 ⊗ |0〉 ⊗ ... ⊗ |0〉 composed of\n /// `inputSize` qubits.\n /// This operation introduces a control qubit to convert a global phase into a relative phase to be able to detect\n /// it.\n operation CheckOperationsEquivalenceOnZeroStateStrict(\n op : (Qubit[] => Unit is Adj + Ctl),\n reference : (Qubit[] => Unit is Adj + Ctl),\n inputSize: Int)\n : Bool {\n Fact(inputSize > 0, \"`inputSize` must be positive\");\n use control = Qubit();\n use target = Qubit[inputSize];\n within {\n H(control);\n }\n apply {\n Controlled op([control], target);\n Adjoint Controlled reference([control], target);\n }\n\n let isCorrect = CheckAllZero([control] + target);\n ResetAll([control] + target);\n isCorrect\n }\n\n /// # Summary\n /// Shows the effect a quantum operation has on the quantum state.\n operation ShowEffectOnQuantumState(targetRegister : Qubit[], op : (Qubit[] => Unit is Adj + Ctl)) : Unit {\n Message(\"Quantum state before applying the operation:\");\n DumpMachine();\n\n // Apply the operation, dump the simulator state and \"undo\" the operation by applying the adjoint.\n Message(\"Quantum state after applying the operation:\");\n op(targetRegister);\n DumpMachine();\n Adjoint op(targetRegister);\n }\n\n /// # Summary\n /// Shows the comparison of the quantum state between a specific operation and a reference operation.\n operation ShowQuantumStateComparison(\n targetRegister : Qubit[],\n op : (Qubit[] => Unit is Adj + Ctl),\n reference : (Qubit[] => Unit is Adj + Ctl))\n : Unit {\n Message(\"Initial quantum state:\");\n DumpMachine();\n\n // Apply the reference operation, dump the simulator state and \"undo\" the operation by applying the adjoint.\n reference(targetRegister);\n Message(\"Expected quantum state after applying the operation:\");\n DumpMachine();\n Adjoint reference(targetRegister);\n\n // Apply the specific operation, dump the simulator state and \"undo\" the operation by applying the adjoint.\n op(targetRegister);\n Message(\"Actual quantum state after applying the operation:\");\n DumpMachine();\n Adjoint op(targetRegister);\n }\n\n internal operation EntangleRegisters(\n control : Qubit[],\n target : Qubit[]) : Unit is Adj + Ctl {\n Fact(\n Length(control) == Length(target),\n $\"The length of qubit registers must be the same.\");\n\n for index in IndexRange(control) {\n H(control[index]);\n CNOT(control[index], target[index]);\n }\n }\n}\n"
|
|
2300
|
+
"code": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nnamespace Microsoft.Quantum.Katas {\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Intrinsic;\n\n /// # Summary\n /// Given two operations, checks whether they act identically for all input states.\n /// This operation is implemented by using the Choi–Jamiołkowski isomorphism.\n ///\n /// N.B. Investigate whether this can be done using just 1 control qubit (GitHub issue #535).\n operation CheckOperationsEquivalence(\n op : (Qubit[] => Unit is Adj + Ctl),\n reference : (Qubit[] => Unit is Adj + Ctl),\n inputSize : Int)\n : Bool {\n Fact(inputSize > 0, \"`inputSize` must be positive\");\n use (control, target) = (Qubit[inputSize], Qubit[inputSize]);\n within {\n // N.B. The order in which quantum registers are passed to this operation is important.\n EntangleRegisters(control, target);\n }\n apply {\n op(target);\n Adjoint reference(target);\n }\n\n let areEquivalent = CheckAllZero(control + target);\n ResetAll(control + target);\n areEquivalent\n }\n\n /// # Summary\n /// Given two operations, checks whether they act identically (including global phase) for all input states.\n /// This is done through controlled versions of the operations instead of plain ones which convert the global phase\n /// into a relative phase that can be detected.\n operation CheckOperationsEquivalenceStrict(\n op : (Qubit[] => Unit is Adj + Ctl),\n reference : (Qubit[] => Unit is Adj + Ctl),\n inputSize : Int)\n : Bool {\n Fact(inputSize > 0, \"`inputSize` must be positive\");\n let controlledOp = register => Controlled op(register[...0], register[1...]);\n let controlledReference = register => Controlled reference(register[...0], register[1...]);\n let areEquivalent = CheckOperationsEquivalence(controlledOp, controlledReference, inputSize + 1);\n areEquivalent\n }\n\n /// # Summary\n /// Given two operations, checks whether they act identically on the zero state |0〉 ⊗ |0〉 ⊗ ... ⊗ |0〉 composed of\n /// `inputSize` qubits.\n operation CheckOperationsEquivalenceOnZeroState(\n op : (Qubit[] => Unit is Adj + Ctl),\n reference : (Qubit[] => Unit is Adj + Ctl),\n inputSize : Int)\n : Bool {\n Fact(inputSize > 0, \"`inputSize` must be positive\");\n use target = Qubit[inputSize];\n op(target);\n Adjoint reference(target);\n let isCorrect = CheckAllZero(target);\n ResetAll(target);\n isCorrect\n }\n\n /// # Summary\n /// Given two operations, checks whether they act identically on the zero state |0〉 ⊗ |0〉 ⊗ ... ⊗ |0〉 composed of\n /// `inputSize` qubits.\n /// This operation introduces a control qubit to convert a global phase into a relative phase to be able to detect\n /// it.\n operation CheckOperationsEquivalenceOnZeroStateStrict(\n op : (Qubit[] => Unit is Adj + Ctl),\n reference : (Qubit[] => Unit is Adj + Ctl),\n inputSize : Int)\n : Bool {\n Fact(inputSize > 0, \"`inputSize` must be positive\");\n use control = Qubit();\n use target = Qubit[inputSize];\n within {\n H(control);\n }\n apply {\n Controlled op([control], target);\n Adjoint Controlled reference([control], target);\n }\n\n let isCorrect = CheckAllZero([control] + target);\n ResetAll([control] + target);\n isCorrect\n }\n\n /// # Summary\n /// Shows the effect a quantum operation has on the quantum state.\n operation ShowEffectOnQuantumState(targetRegister : Qubit[], op : (Qubit[] => Unit is Adj + Ctl)) : Unit {\n Message(\"Quantum state before applying the operation:\");\n DumpMachine();\n\n // Apply the operation, dump the simulator state and \"undo\" the operation by applying the adjoint.\n Message(\"Quantum state after applying the operation:\");\n op(targetRegister);\n DumpMachine();\n Adjoint op(targetRegister);\n }\n\n /// # Summary\n /// Shows the comparison of the quantum state between a specific operation and a reference operation.\n operation ShowQuantumStateComparison(\n targetRegister : Qubit[],\n op : (Qubit[] => Unit is Adj + Ctl),\n reference : (Qubit[] => Unit is Adj + Ctl))\n : Unit {\n Message(\"Initial quantum state:\");\n DumpMachine();\n\n // Apply the reference operation, dump the simulator state and \"undo\" the operation by applying the adjoint.\n reference(targetRegister);\n Message(\"Expected quantum state after applying the operation:\");\n DumpMachine();\n Adjoint reference(targetRegister);\n\n // Apply the specific operation, dump the simulator state and \"undo\" the operation by applying the adjoint.\n op(targetRegister);\n Message(\"Actual quantum state after applying the operation:\");\n DumpMachine();\n Adjoint op(targetRegister);\n }\n\n internal operation EntangleRegisters(\n control : Qubit[],\n target : Qubit[]) : Unit is Adj + Ctl {\n Fact(\n Length(control) == Length(target),\n $\"The length of qubit registers must be the same.\");\n\n for index in IndexRange(control) {\n H(control[index]);\n CNOT(control[index], target[index]);\n }\n }\n}\n"
|
|
2301
2301
|
},
|
|
2302
2302
|
{
|
|
2303
2303
|
"id": "getting_started__flip_qubit__Verification.qs",
|
|
2304
|
-
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Katas;\n\n operation FlipQubit(q : Qubit): Unit is Adj + Ctl {\n X(q);\n }\n\n operation CheckSolution() : Bool {\n let solution = register => Kata.FlipQubit(register[0]);\n let reference = register => FlipQubit(register[0]);\n let isCorrect = CheckOperationsEquivalence(solution, reference, 1);\n\n // Output different feedback to the user depending on whether the solution was correct.\n if isCorrect {\n Message(\"Correct!\");\n Message(\"Congratulations! You have solved your first exercise.\");\n } else {\n Message(\"Incorrect.\");\n Message(\"Look out for hints when your solution is incorrect.\");\n Message(\"Hint: examine the effect your solution has on the |0〉 state and compare it with the effect it \" +\n \"is expected to have.\");\n use target = Qubit[1]; // |0〉\n ShowQuantumStateComparison(target, solution, reference);\n ResetAll(target);\n }\n isCorrect\n }\n}\n"
|
|
2304
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Katas;\n\n operation FlipQubit(q : Qubit) : Unit is Adj + Ctl {\n X(q);\n }\n\n operation CheckSolution() : Bool {\n let solution = register => Kata.FlipQubit(register[0]);\n let reference = register => FlipQubit(register[0]);\n let isCorrect = CheckOperationsEquivalence(solution, reference, 1);\n\n // Output different feedback to the user depending on whether the solution was correct.\n if isCorrect {\n Message(\"Correct!\");\n Message(\"Congratulations! You have solved your first exercise.\");\n } else {\n Message(\"Incorrect.\");\n Message(\"Look out for hints when your solution is incorrect.\");\n Message(\"Hint: examine the effect your solution has on the |0〉 state and compare it with the effect it \" +\n \"is expected to have.\");\n use target = Qubit[1]; // |0〉\n ShowQuantumStateComparison(target, solution, reference);\n ResetAll(target);\n }\n isCorrect\n }\n}\n"
|
|
2305
2305
|
},
|
|
2306
2306
|
{
|
|
2307
2307
|
"id": "qubit__learn_single_qubit_state__Verification.qs",
|
|
2308
|
-
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Math;\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n use q = Qubit();\n\n // Prepare the state that will be passed to the solution.\n let angle = 0.5;\n Ry(angle, q);\n\n // Call the solution and get the answer.\n let (a, b) = Kata.LearnSingleQubitState(q);\n\n // Calculate the expected values based on the rotation angle.\n let (a_exp, b_exp) = (Cos(0.5 * angle), Sin(0.5 * angle));\n\n Reset(q);\n\n let isCorrect =\n (AbsD(a - a_exp) <= 0.001) and\n (AbsD(b - b_exp) <= 0.001);\n\n // Output different feedback to the user depending on whether the exercise was correct.\n if isCorrect {\n Message(\"All tests passed.\");\n } else {\n Message(\"At least one of the amplitudes was too far from the expected value.\");\n }\n\n isCorrect\n }\n}\n"
|
|
2308
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Math;\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n use q = Qubit();\n\n // Prepare the state that will be passed to the solution.\n let angle = 0.5;\n Ry(angle, q);\n\n // Call the solution and get the answer.\n let (a, b) = Kata.LearnSingleQubitState(q);\n\n // Calculate the expected values based on the rotation angle.\n let (a_exp, b_exp) = (Cos(0.5 * angle), Sin(0.5 * angle));\n\n Reset(q);\n\n let isCorrect =\n (AbsD(a - a_exp) <= 0.001) and\n (AbsD(b - b_exp) <= 0.001);\n\n // Output different feedback to the user depending on whether the exercise was correct.\n if isCorrect {\n Message(\"All tests passed.\");\n } else {\n Message(\"At least one of the amplitudes was too far from the expected value.\");\n }\n\n isCorrect\n }\n}\n"
|
|
2309
2309
|
},
|
|
2310
2310
|
{
|
|
2311
2311
|
"id": "qubit__learn_basis_state_amplitudes__Verification.qs",
|
|
2312
|
-
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Math;\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n use qs = Qubit[2];\n\n // Prepare the state that will be passed to the solution.\n H(qs[0]);\n ApplyControlledOnInt(0, Ry(1.0, _), [qs[0]], qs[1]);\n ApplyControlledOnInt(1, Ry(2.0, _), [qs[0]], qs[1]);\n\n // Call the solution and get the answer.\n let (x1, x2) = Kata.LearnBasisStateAmplitudes(qs);\n\n // Calculate the expected values based on the rotation angle.\n // We convert |00⟩ + |10⟩ to |0⟩ Ry(1.0)|0⟩ + |1⟩ Ry(2.0)|0⟩, so
|
|
2312
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Math;\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n use qs = Qubit[2];\n\n // Prepare the state that will be passed to the solution.\n H(qs[0]);\n ApplyControlledOnInt(0, Ry(1.0, _), [qs[0]], qs[1]);\n ApplyControlledOnInt(1, Ry(2.0, _), [qs[0]], qs[1]);\n\n // Call the solution and get the answer.\n let (x1, x2) = Kata.LearnBasisStateAmplitudes(qs);\n\n // Calculate the expected values based on the rotation angle.\n // We convert |00⟩ + |10⟩ to |0⟩ Ry(1.0)|0⟩ + |1⟩ Ry(2.0)|0⟩, so\n // * the amplitude of |1⟩ = |10⟩ is 1st amp of Ry(2.0)|0⟩\n // * the amplitude of |2⟩ = |01⟩ is 2nd amp of Ry(1.0)|0⟩\n let (x1_exp, x2_exp) = (\n 1.0/Sqrt(2.0) * Cos(0.5 * 2.0),\n 1.0/Sqrt(2.0) * Sin(0.5 * 1.0));\n\n let isCorrect =\n (AbsD(x1 - x1_exp) <= 0.001) and\n (AbsD(x2 - x2_exp) <= 0.001);\n\n ResetAll(qs);\n\n // Output different feedback to the user depending on whether the exercise was correct.\n if isCorrect {\n Message(\"All tests passed.\");\n } else {\n Message(\"One of the amplitudes was too far from the expected value.\");\n }\n\n isCorrect\n }\n}\n"
|
|
2313
2313
|
},
|
|
2314
2314
|
{
|
|
2315
2315
|
"id": "single_qubit_gates__y_gate__Verification.qs",
|
|
@@ -2341,7 +2341,7 @@ export default {
|
|
|
2341
2341
|
},
|
|
2342
2342
|
{
|
|
2343
2343
|
"id": "multi_qubit_systems__common.qs",
|
|
2344
|
-
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Diagnostics;\n\n operation AssertEqualOnZeroState(\n testImpl: (Qubit[] => Unit is Ctl),\n refImpl : (Qubit[] => Unit is Adj+Ctl)) : Bool {\n\n use qs = Qubit[3];\n within {\n H(qs[0]);\n }\n apply {\n // apply operation that needs to be tested\n Controlled testImpl([qs[0]], qs[1..2]);\n\n // apply adjoint reference operation\n Adjoint Controlled refImpl([qs[0]], qs[1..2]);\n }\n\n // Implementation is correct when all qubits end up in |0⟩ state\n let isCorrect = CheckAllZero(qs);\n if not isCorrect {\n Message(\"The prepared state is not the same as reference state.\");\n }\n ResetAll(qs);\n isCorrect\n }\n\n}"
|
|
2344
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Diagnostics;\n\n operation AssertEqualOnZeroState(\n testImpl : (Qubit[] => Unit is Ctl),\n refImpl : (Qubit[] => Unit is Adj+Ctl)) : Bool {\n\n use qs = Qubit[3];\n within {\n H(qs[0]);\n }\n apply {\n // apply operation that needs to be tested\n Controlled testImpl([qs[0]], qs[1..2]);\n\n // apply adjoint reference operation\n Adjoint Controlled refImpl([qs[0]], qs[1..2]);\n }\n\n // Implementation is correct when all qubits end up in |0⟩ state\n let isCorrect = CheckAllZero(qs);\n if not isCorrect {\n Message(\"The prepared state is not the same as reference state.\");\n }\n ResetAll(qs);\n isCorrect\n }\n\n}\n"
|
|
2345
2345
|
},
|
|
2346
2346
|
{
|
|
2347
2347
|
"id": "multi_qubit_systems__prepare_basis_state__verification.qs",
|
|
@@ -2349,15 +2349,15 @@ export default {
|
|
|
2349
2349
|
},
|
|
2350
2350
|
{
|
|
2351
2351
|
"id": "multi_qubit_systems__prepare_superposition__verification.qs",
|
|
2352
|
-
"code": "namespace Kata.Verification {\n operation PrepareSuperposition_Reference(qs : Qubit[]) : Unit is Adj + Ctl {\n X(qs[1]);\n H(qs[1]);\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n let isCorrect = AssertEqualOnZeroState(Kata.PrepareSuperposition, PrepareSuperposition_Reference);\n if isCorrect {\n Message(\"Correct!\");\n } else {\n Message(\"Incorrect.\");\n }\n return isCorrect;\n }\n}"
|
|
2352
|
+
"code": "namespace Kata.Verification {\n operation PrepareSuperposition_Reference(qs : Qubit[]) : Unit is Adj + Ctl {\n X(qs[1]);\n H(qs[1]);\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n let isCorrect = AssertEqualOnZeroState(Kata.PrepareSuperposition, PrepareSuperposition_Reference);\n if isCorrect {\n Message(\"Correct!\");\n } else {\n Message(\"Incorrect.\");\n }\n return isCorrect;\n }\n}\n"
|
|
2353
2353
|
},
|
|
2354
2354
|
{
|
|
2355
2355
|
"id": "multi_qubit_systems__prepare_with_real__verification.qs",
|
|
2356
|
-
"code": "namespace Kata.Verification {\n operation PrepareWithReal_Reference(qs : Qubit[]) : Unit is Adj + Ctl {\n H(qs[0]);\n X(qs[1]);\n H(qs[1]);\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n let isCorrect = AssertEqualOnZeroState(Kata.PrepareWithReal, PrepareWithReal_Reference);\n if isCorrect {\n Message(\"Correct!\");\n } else {\n Message(\"Incorrect.\");\n }\n return isCorrect;\n }\n}"
|
|
2356
|
+
"code": "namespace Kata.Verification {\n operation PrepareWithReal_Reference(qs : Qubit[]) : Unit is Adj + Ctl {\n H(qs[0]);\n X(qs[1]);\n H(qs[1]);\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n let isCorrect = AssertEqualOnZeroState(Kata.PrepareWithReal, PrepareWithReal_Reference);\n if isCorrect {\n Message(\"Correct!\");\n } else {\n Message(\"Incorrect.\");\n }\n return isCorrect;\n }\n}\n"
|
|
2357
2357
|
},
|
|
2358
2358
|
{
|
|
2359
2359
|
"id": "multi_qubit_systems__prepare_with_complex__verification.qs",
|
|
2360
|
-
"code": "namespace Kata.Verification {\n operation PrepareWithComplex_Reference(qs : Qubit[]) : Unit is Adj + Ctl {\n H(qs[0]);\n H(qs[1]);\n S(qs[0]);\n T(qs[1]);\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n let isCorrect = AssertEqualOnZeroState(Kata.PrepareWithComplex, PrepareWithComplex_Reference);\n if isCorrect {\n Message(\"Correct!\");\n } else {\n Message(\"Incorrect.\");\n }\n return isCorrect;\n }\n}"
|
|
2360
|
+
"code": "namespace Kata.Verification {\n operation PrepareWithComplex_Reference(qs : Qubit[]) : Unit is Adj + Ctl {\n H(qs[0]);\n H(qs[1]);\n S(qs[0]);\n T(qs[1]);\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n let isCorrect = AssertEqualOnZeroState(Kata.PrepareWithComplex, PrepareWithComplex_Reference);\n if isCorrect {\n Message(\"Correct!\");\n } else {\n Message(\"Incorrect.\");\n }\n return isCorrect;\n }\n}\n"
|
|
2361
2361
|
},
|
|
2362
2362
|
{
|
|
2363
2363
|
"id": "multi_qubit_gates__compound_gate__Verification.qs",
|
|
@@ -2381,7 +2381,7 @@ export default {
|
|
|
2381
2381
|
},
|
|
2382
2382
|
{
|
|
2383
2383
|
"id": "single_qubit_measurements__common.qs",
|
|
2384
|
-
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Random;\n\n // \"Framework\" operation for testing single-qubit tasks for distinguishing states of one qubit\n // with Bool return\n operation DistinguishTwoStates(\n statePrep: ((Qubit, Int) => Unit is Adj),\n testImpl : (Qubit => Bool),\n stateName : String[],\n checkFinalState : Bool) : Bool {\n\n let nTotal = 100;\n let nStates = 2;\n mutable misclassifications = Repeated(0, nStates);\n
|
|
2384
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Random;\n\n // \"Framework\" operation for testing single-qubit tasks for distinguishing states of one qubit\n // with Bool return\n operation DistinguishTwoStates(\n statePrep : ((Qubit, Int) => Unit is Adj),\n testImpl : (Qubit => Bool),\n stateName : String[],\n checkFinalState : Bool) : Bool {\n\n let nTotal = 100;\n let nStates = 2;\n mutable misclassifications = Repeated(0, nStates);\n\n use q = Qubit();\n for i in 1 .. nTotal {\n // get a random bit to define whether qubit will be in a state corresponding to true return (1) or to false one (0)\n // state = 0 false return\n // state = 1 true return\n let state = DrawRandomInt(0, 1);\n\n // do state prep: convert |0⟩ to outcome with false return or to outcome with true return depending on state\n statePrep(q, state);\n\n // get the solution's answer and verify if NOT a match, then differentiate what kind of mismatch\n let ans = testImpl(q);\n if ans != (state == 1) {\n set misclassifications w/= state <- misclassifications[state] + 1;\n }\n\n // If the final state is to be verified, check if it matches the measurement outcome\n if checkFinalState {\n Adjoint statePrep(q, state);\n Fact(CheckZero(q), \"Returned Bool value does not match the expected qubit state.\");\n } else {\n Reset(q);\n }\n }\n\n mutable totalMisclassifications = 0;\n for i in 0 .. nStates - 1 {\n if misclassifications[i] != 0 {\n set totalMisclassifications += misclassifications[i];\n Message($\"Misclassified {stateName[i]} as {stateName[1 - i]} in {misclassifications[i]} test runs.\");\n }\n }\n\n return totalMisclassifications == 0;\n }\n\n}\n"
|
|
2385
2385
|
},
|
|
2386
2386
|
{
|
|
2387
2387
|
"id": "single_qubit_measurements__distinguish_0_and_1__verification.qs",
|
|
@@ -2389,19 +2389,19 @@ export default {
|
|
|
2389
2389
|
},
|
|
2390
2390
|
{
|
|
2391
2391
|
"id": "single_qubit_measurements__distinguish_plus_and_minus__verification.qs",
|
|
2392
|
-
"code": "namespace Kata.Verification {\n\n // Distinguish |+❭ and |-❭ using Measure operation\n operation StatePrep_IsQubitMinus (q : Qubit, state : Int) : Unit is Adj {\n if state == 1 {\n // convert |0⟩ to |-⟩\n X(q);\n H(q);\n } else {\n // convert |0⟩ to |+⟩\n H(q);\n }\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n let isCorrect = DistinguishTwoStates(\n StatePrep_IsQubitMinus,\n Kata.IsQubitMinus,\n [\"|+⟩\", \"|-⟩\"],\n false);\n if isCorrect {\n Message(\"All tests passed.\");\n }\n isCorrect\n }\n\n}\n"
|
|
2392
|
+
"code": "namespace Kata.Verification {\n\n // Distinguish |+❭ and |-❭ using Measure operation\n operation StatePrep_IsQubitMinus (q : Qubit, state : Int) : Unit is Adj {\n if state == 1 {\n // convert |0⟩ to |-⟩\n X(q);\n H(q);\n } else {\n // convert |0⟩ to |+⟩\n H(q);\n }\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n let isCorrect = DistinguishTwoStates(\n StatePrep_IsQubitMinus,\n Kata.IsQubitMinus,\n [\"|+⟩\", \"|-⟩\"],\n false);\n if isCorrect {\n Message(\"All tests passed.\");\n }\n isCorrect\n }\n\n}\n"
|
|
2393
2393
|
},
|
|
2394
2394
|
{
|
|
2395
2395
|
"id": "single_qubit_measurements__distinguish_orthogonal_states_1__verification.qs",
|
|
2396
|
-
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Math;\n\n // Distinguish specific orthogonal states\n // |ψ₊⟩ = 0.6 * |0⟩ + 0.8 * |1⟩,\n // |ψ₋⟩ = -0.8 * |0⟩ + 0.6 * |1⟩.\n operation StatePrep_IsQubitPsiPlus(q: Qubit, state: Int): Unit is Adj {\n if state == 0 {\n // convert |0⟩ to |ψ₋⟩\n X(q);\n Ry(2.0 * ArcTan2(0.8, 0.6), q);\n } else {\n // convert |0⟩ to |ψ₊⟩\n Ry(2.0 * ArcTan2(0.8, 0.6), q);\n }\n }\n\n operation CheckSolution(): Bool {\n let isCorrect = DistinguishTwoStates(\n StatePrep_IsQubitPsiPlus,\n Kata.IsQubitPsiPlus
|
|
2396
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Math;\n\n // Distinguish specific orthogonal states\n // |ψ₊⟩ = 0.6 * |0⟩ + 0.8 * |1⟩,\n // |ψ₋⟩ = -0.8 * |0⟩ + 0.6 * |1⟩.\n operation StatePrep_IsQubitPsiPlus(q : Qubit, state : Int) : Unit is Adj {\n if state == 0 {\n // convert |0⟩ to |ψ₋⟩\n X(q);\n Ry(2.0 * ArcTan2(0.8, 0.6), q);\n } else {\n // convert |0⟩ to |ψ₊⟩\n Ry(2.0 * ArcTan2(0.8, 0.6), q);\n }\n }\n\n operation CheckSolution() : Bool {\n let isCorrect = DistinguishTwoStates(\n StatePrep_IsQubitPsiPlus,\n Kata.IsQubitPsiPlus,\n [\"|ψ₋⟩\", \"|ψ₊⟩\"],\n false);\n if isCorrect {\n Message(\"All tests passed.\");\n }\n isCorrect\n }\n\n}\n"
|
|
2397
2397
|
},
|
|
2398
2398
|
{
|
|
2399
2399
|
"id": "single_qubit_measurements__distinguish_orthogonal_states_2__verification.qs",
|
|
2400
|
-
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Math;\n\n // Distinguish states |A❭ and |B❭\n // |A⟩ = cos(alpha) * |0⟩ - i sin(alpha) * |1⟩,\n // |B⟩ = - i sin(alpha) * |0⟩ + cos(alpha) * |1⟩.\n operation StatePrep_IsQubitA(alpha: Double, q: Qubit, state: Int): Unit is Adj {\n if state == 0 {\n // convert |0⟩ to |B⟩\n X(q);\n Rx(2.0 * alpha, q);\n } else {\n // convert |0⟩ to |A⟩\n Rx(2.0 * alpha, q);\n }\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n for i in 0 .. 10 {\n let alpha = (PI() * IntAsDouble(i)) / 10.0;\n let isCorrect = DistinguishTwoStates(\n StatePrep_IsQubitA(alpha, _, _),\n Kata.IsQubitA(alpha, _)
|
|
2400
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Math;\n\n // Distinguish states |A❭ and |B❭\n // |A⟩ = cos(alpha) * |0⟩ - i sin(alpha) * |1⟩,\n // |B⟩ = - i sin(alpha) * |0⟩ + cos(alpha) * |1⟩.\n operation StatePrep_IsQubitA(alpha : Double, q : Qubit, state : Int) : Unit is Adj {\n if state == 0 {\n // convert |0⟩ to |B⟩\n X(q);\n Rx(2.0 * alpha, q);\n } else {\n // convert |0⟩ to |A⟩\n Rx(2.0 * alpha, q);\n }\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n for i in 0 .. 10 {\n let alpha = (PI() * IntAsDouble(i)) / 10.0;\n let isCorrect = DistinguishTwoStates(\n StatePrep_IsQubitA(alpha, _, _),\n Kata.IsQubitA(alpha, _),\n [$\"|B⟩ = -i sin({i}π/10)|0⟩ + cos({i}π/10)|1⟩\", $\"|A⟩ = cos({i}π/10)|0⟩ + i sin({i}π/10)|1⟩\"],\n false);\n if not isCorrect {\n return false;\n }\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2401
2401
|
},
|
|
2402
2402
|
{
|
|
2403
2403
|
"id": "single_qubit_measurements__a_b_basis_measurements__verification.qs",
|
|
2404
|
-
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Math;\n\n // Measure state in {|A❭, |B❭} basis\n // |A⟩ = cos(alpha) * |0⟩ - i sin(alpha) * |1⟩,\n // |B⟩ = - i sin(alpha) * |0⟩ + cos(alpha) * |1⟩.\n\n operation StatePrep_IsQubitA (alpha : Double, q : Qubit, state : Int) : Unit is Adj {\n if state == 0 {\n // convert |0⟩ to |B⟩\n X(q);\n Rx(2.0 * alpha, q);\n } else {\n // convert |0⟩ to |A⟩\n Rx(2.0 * alpha, q);\n }\n }\n\n // We can use the StatePrep_IsQubitA operation for the testing\n operation CheckSolution(): Bool {\n for i in 0 .. 10 {\n let alpha = (PI() * IntAsDouble(i)) / 10.0;\n let isCorrect = DistinguishTwoStates(\n StatePrep_IsQubitA(alpha, _, _)
|
|
2404
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Math;\n\n // Measure state in {|A❭, |B❭} basis\n // |A⟩ = cos(alpha) * |0⟩ - i sin(alpha) * |1⟩,\n // |B⟩ = - i sin(alpha) * |0⟩ + cos(alpha) * |1⟩.\n\n operation StatePrep_IsQubitA (alpha : Double, q : Qubit, state : Int) : Unit is Adj {\n if state == 0 {\n // convert |0⟩ to |B⟩\n X(q);\n Rx(2.0 * alpha, q);\n } else {\n // convert |0⟩ to |A⟩\n Rx(2.0 * alpha, q);\n }\n }\n\n // We can use the StatePrep_IsQubitA operation for the testing\n operation CheckSolution() : Bool {\n for i in 0 .. 10 {\n let alpha = (PI() * IntAsDouble(i)) / 10.0;\n let isCorrect = DistinguishTwoStates(\n StatePrep_IsQubitA(alpha, _, _),\n q => Kata.MeasureInABBasis(alpha, q) == Zero,\n [$\"|B⟩=(-i sin({i}π/10)|0⟩ + cos({i}π/10)|1⟩)\", $\"|A⟩=(cos({i}π/10)|0⟩ + i sin({i}π/10)|1⟩)\"],\n true);\n if not isCorrect {\n Message($\"Test failes for alpha={alpha}\");\n return false;\n }\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2405
2405
|
},
|
|
2406
2406
|
{
|
|
2407
2407
|
"id": "multi_qubit_measurements__full_measurements__verify.qs",
|
|
@@ -2409,23 +2409,23 @@ export default {
|
|
|
2409
2409
|
},
|
|
2410
2410
|
{
|
|
2411
2411
|
"id": "multi_qubit_measurements__common.qs",
|
|
2412
|
-
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Canon;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Math;\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Measurement;\n open Microsoft.Quantum.Random;\n\n // \"Framework\" operation for testing multi-qubit tasks for distinguishing states of an array of qubits\n // with Int return\n operation DistinguishStates_MultiQubit(\n nQubits: Int,\n nStates: Int,\n statePrep: ((Qubit[], Int, Double) => Unit is Adj),\n testImpl: (Qubit[] => Int),\n preserveState: Bool,\n stateNames: String[]): Bool {\n\n let nTotal = 100;\n // misclassifications will store the number of times state i has been classified as state j (dimension nStates^2)\n mutable misclassifications = [0, size = nStates * nStates];\n // unknownClassifications will store the number of times state i has been classified as some invalid state (index < 0 or >= nStates)\n mutable unknownClassifications = [0, size = nStates];\n
|
|
2412
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Canon;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Math;\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Measurement;\n open Microsoft.Quantum.Random;\n\n // \"Framework\" operation for testing multi-qubit tasks for distinguishing states of an array of qubits\n // with Int return\n operation DistinguishStates_MultiQubit(\n nQubits : Int,\n nStates : Int,\n statePrep : ((Qubit[], Int, Double) => Unit is Adj),\n testImpl : (Qubit[] => Int),\n preserveState : Bool,\n stateNames : String[]) : Bool {\n\n let nTotal = 100;\n // misclassifications will store the number of times state i has been classified as state j (dimension nStates^2)\n mutable misclassifications = [0, size = nStates * nStates];\n // unknownClassifications will store the number of times state i has been classified as some invalid state (index < 0 or >= nStates)\n mutable unknownClassifications = [0, size = nStates];\n\n use qs = Qubit[nQubits];\n for i in 1 .. nTotal {\n // get a random integer to define the state of the qubits\n let state = DrawRandomInt(0, nStates - 1);\n // get a random rotation angle to define the exact state of the qubits\n // for some exercises, this value might be a dummy variable which does not matter\n let alpha = DrawRandomDouble(0.0, 1.0) * PI();\n\n // do state prep: convert |0...0⟩ to outcome with return equal to state\n statePrep(qs, state, alpha);\n\n // get the solution's answer and verify that it's a match, if not, increase the exact mismatch count\n let ans = testImpl(qs);\n if ((ans >= 0) and (ans < nStates)) {\n // classification result is a valid state index - check if is it correct\n if ans != state {\n set misclassifications w/= ((state * nStates) + ans) <- (misclassifications[(state * nStates) + ans] + 1);\n }\n }\n else {\n // classification result is an invalid state index - file it separately\n set unknownClassifications w/= state <- (unknownClassifications[state] + 1);\n }\n\n if preserveState {\n // check that the state of the qubit after the operation is unchanged\n Adjoint statePrep(qs, state, alpha);\n if not CheckAllZero(qs) {\n Message(\"Test should preseve qubit state.\");\n ResetAll(qs);\n return false;\n }\n } else {\n // we're not checking the state of the qubit after the operation\n ResetAll(qs);\n }\n }\n ResetAll(qs);\n\n mutable totalMisclassifications = 0;\n for i in 0 .. nStates - 1 {\n for j in 0 .. nStates - 1 {\n if misclassifications[(i * nStates) + j] != 0 {\n set totalMisclassifications += misclassifications[i * nStates + j];\n Message($\"Misclassified {stateNames[i]} as {stateNames[j]} in {misclassifications[(i * nStates) + j]} test runs.\");\n }\n }\n if unknownClassifications[i] != 0 {\n set totalMisclassifications += unknownClassifications[i];\n Message($\"Misclassified {stateNames[i]} as Unknown State in {unknownClassifications[i]} test runs.\");\n }\n }\n totalMisclassifications == 0\n }\n}\n"
|
|
2413
2413
|
},
|
|
2414
2414
|
{
|
|
2415
2415
|
"id": "multi_qubit_measurements__partial_measurements_for_system__verify.qs",
|
|
2416
|
-
"code": "namespace Kata.Verification {\n\n // Distinguish orthogonal states using partial measurements\n operation StatePrep_IsPlusPlusMinus(qs: Qubit[], state: Int, dummyVar: Double): Unit is Adj {\n if state == 0 {\n // prepare the state |++-⟩\n H(qs[0]);\n H(qs[1]);\n X(qs[2]);\n H(qs[2]);\n } else {\n // prepare the state |---⟩\n X(qs[0]);\n H(qs[0]);\n X(qs[1]);\n H(qs[1]);\n X(qs[2]);\n H(qs[2]);\n }\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n return DistinguishStates_MultiQubit(\n 3,\n 2,\n StatePrep_IsPlusPlusMinus,\n Kata.IsPlusPlusMinus,\n false,\n [\"|++-⟩\", \"|---⟩\"]);\n }\n\n}\n"
|
|
2416
|
+
"code": "namespace Kata.Verification {\n\n // Distinguish orthogonal states using partial measurements\n operation StatePrep_IsPlusPlusMinus(qs : Qubit[], state : Int, dummyVar : Double) : Unit is Adj {\n if state == 0 {\n // prepare the state |++-⟩\n H(qs[0]);\n H(qs[1]);\n X(qs[2]);\n H(qs[2]);\n } else {\n // prepare the state |---⟩\n X(qs[0]);\n H(qs[0]);\n X(qs[1]);\n H(qs[1]);\n X(qs[2]);\n H(qs[2]);\n }\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n return DistinguishStates_MultiQubit(\n 3,\n 2,\n StatePrep_IsPlusPlusMinus,\n Kata.IsPlusPlusMinus,\n false,\n [\"|++-⟩\", \"|---⟩\"]);\n }\n\n}\n"
|
|
2417
2417
|
},
|
|
2418
2418
|
{
|
|
2419
2419
|
"id": "multi_qubit_measurements__state_modification__verify.qs",
|
|
2420
|
-
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Math;\n\n // State selection using partial measurements\n operation stateInitialize_StateSelction(alpha: Double, qs: Qubit[]): Unit {\n // Prepare the state to be input to the testImplementation\n // set the second qubit in a superposition a |0⟩ + b|1⟩\n // with a = cos alpha, b = sin alpha\n Ry(2.0 * alpha, qs[1])
|
|
2420
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Math;\n\n // State selection using partial measurements\n operation stateInitialize_StateSelction(alpha : Double, qs : Qubit[]) : Unit {\n // Prepare the state to be input to the testImplementation\n // set the second qubit in a superposition a |0⟩ + b|1⟩\n // with a = cos alpha, b = sin alpha\n Ry(2.0 * alpha, qs[1]);\n\n H(qs[0]);\n // Apply CX gate\n CX(qs[0], qs[1]);\n }\n\n operation statePrepare_StateSelction(alpha : Double, Choice : Int, qs : Qubit[]) : Unit is Adj {\n // The expected state of the second qubit for the exercise.\n\n // set the second qubit in a superposition a |0⟩ + b|1⟩\n // with a = cos alpha, b = sin alpha\n Ry(2.0 * alpha, qs[1]);\n if Choice == 1 {\n // if the Choice is 1, change the state to b|0⟩ + a|1⟩\n X(qs[1]);\n }\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n use qs = Qubit[2];\n for i in 0 .. 5 {\n let alpha = (PI() * IntAsDouble(i)) / 5.0;\n\n //for Choice = 0 and 1,\n for Choice in 0 .. 1 {\n // Prepare the state to be input to the testImplementation\n stateInitialize_StateSelction(alpha, qs);\n\n // operate testImplementation\n Kata.StateSelction(qs, Choice);\n // reset the first qubit, since its state does not matter\n Reset(qs[0]);\n\n // apply adjoint reference operation and check that the result is correct\n Adjoint statePrepare_StateSelction(alpha, Choice, qs);\n\n if not CheckAllZero(qs) {\n ResetAll(qs);\n return false;\n }\n ResetAll(qs);\n }\n }\n ResetAll(qs);\n true\n }\n\n}\n"
|
|
2421
2421
|
},
|
|
2422
2422
|
{
|
|
2423
2423
|
"id": "multi_qubit_measurements__state_preparation__verify.qs",
|
|
2424
|
-
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Math;\n\n // State preparation using partial measurements\n operation RefImpl_T4(qs: Qubit[]): Unit is Adj {\n // Rotate first qubit to (sqrt(2) |0⟩ + |1⟩) / sqrt(3)\n let theta = ArcSin(1.0 / Sqrt(3.0));\n Ry(2.0 * theta, qs[0]);\n\n // Split the state sqrt(2) |0⟩ ⊗ |0⟩ into |00⟩ + |01⟩\n ApplyControlledOnInt(0, H, [qs[0]], qs[1]);\n }\n\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n use qs = Qubit[2];\n\n // operate the test implementation\n Kata.PostSelection(qs);\n\n // apply adjoint reference operation and check that the result is |0⟩\n Adjoint RefImpl_T4(qs);\n let isCorrect = CheckAllZero(qs);\n ResetAll(qs);\n isCorrect\n }\n\n}\n"
|
|
2424
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Math;\n\n // State preparation using partial measurements\n operation RefImpl_T4(qs : Qubit[]) : Unit is Adj {\n // Rotate first qubit to (sqrt(2) |0⟩ + |1⟩) / sqrt(3)\n let theta = ArcSin(1.0 / Sqrt(3.0));\n Ry(2.0 * theta, qs[0]);\n\n // Split the state sqrt(2) |0⟩ ⊗ |0⟩ into |00⟩ + |01⟩\n ApplyControlledOnInt(0, H, [qs[0]], qs[1]);\n }\n\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n use qs = Qubit[2];\n\n // operate the test implementation\n Kata.PostSelection(qs);\n\n // apply adjoint reference operation and check that the result is |0⟩\n Adjoint RefImpl_T4(qs);\n let isCorrect = CheckAllZero(qs);\n ResetAll(qs);\n isCorrect\n }\n\n}\n"
|
|
2425
2425
|
},
|
|
2426
2426
|
{
|
|
2427
2427
|
"id": "multi_qubit_measurements__joint_measurements__verify.qs",
|
|
2428
|
-
"code": "namespace Kata.Verification {\n\n // Two qubit parity Measurement\n operation StatePrep_ParityMeasurement(qs: Qubit[], state: Int, alpha: Double): Unit is Adj {\n // prep cos(alpha) * |0..0⟩ + sin(alpha) * |1..1⟩\n Ry(2.0 * alpha, qs[0]);\n for i in 1 .. Length(qs) - 1 {\n CNOT(qs[0], qs[i]);\n }\n
|
|
2428
|
+
"code": "namespace Kata.Verification {\n\n // Two qubit parity Measurement\n operation StatePrep_ParityMeasurement(qs : Qubit[], state : Int, alpha : Double) : Unit is Adj {\n // prep cos(alpha) * |0..0⟩ + sin(alpha) * |1..1⟩\n Ry(2.0 * alpha, qs[0]);\n for i in 1 .. Length(qs) - 1 {\n CNOT(qs[0], qs[i]);\n }\n\n if state == 1 {\n // flip the state of the first half of the qubits\n for i in 0 .. Length(qs) / 2 - 1 {\n X(qs[i]);\n }\n }\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n return DistinguishStates_MultiQubit(\n 2,\n 2,\n StatePrep_ParityMeasurement,\n Kata.ParityMeasurement,\n true,\n [\"α|00⟩ + β|11⟩\", \"α|01⟩ + β|10⟩\"]);\n }\n}\n"
|
|
2429
2429
|
},
|
|
2430
2430
|
{
|
|
2431
2431
|
"id": "random_numbers__random_bit__verification.qs",
|
|
@@ -2437,19 +2437,19 @@ export default {
|
|
|
2437
2437
|
},
|
|
2438
2438
|
{
|
|
2439
2439
|
"id": "random_numbers__random_two_bits__verification.qs",
|
|
2440
|
-
"code": "namespace Kata.Verification {\n @EntryPoint()\n operation CheckSolution(): Bool {\n Message(\"Testing two random bits generation...\");\n let randomnessVerifier = () => CheckUniformDistribution(Kata.RandomTwoBits, 0, 3, 1000);\n let isCorrect = IsSufficientlyRandom(randomnessVerifier);\n if isCorrect {\n Message(\"All tests passed.\");\n }\n isCorrect\n }\n\n}\n"
|
|
2440
|
+
"code": "namespace Kata.Verification {\n @EntryPoint()\n operation CheckSolution() : Bool {\n Message(\"Testing two random bits generation...\");\n let randomnessVerifier = () => CheckUniformDistribution(Kata.RandomTwoBits, 0, 3, 1000);\n let isCorrect = IsSufficientlyRandom(randomnessVerifier);\n if isCorrect {\n Message(\"All tests passed.\");\n }\n isCorrect\n }\n\n}\n"
|
|
2441
2441
|
},
|
|
2442
2442
|
{
|
|
2443
2443
|
"id": "random_numbers__random_n_bits__verification.qs",
|
|
2444
|
-
"code": "namespace Kata.Verification {\n @EntryPoint()\n operation CheckSolution(): Bool {\n // Test random number generation for 1, 2, 3, 10 bits\n let testCases = [(1, 1000), (2, 1000), (3, 1000), (10, 10000)];\n for (N, runs) in testCases {\n Message($\"Testing N = {N}...\");\n let max = (1 <<< N) - 1;\n let randomnessVerifier = () => CheckUniformDistribution(() =>\n Kata.RandomNBits(N), 0, max, runs);\n let isCorrect = IsSufficientlyRandom(randomnessVerifier);\n if not isCorrect {\n return false;\n }\n Message($\"Test passed for N = {N}\");\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2444
|
+
"code": "namespace Kata.Verification {\n @EntryPoint()\n operation CheckSolution() : Bool {\n // Test random number generation for 1, 2, 3, 10 bits\n let testCases = [(1, 1000), (2, 1000), (3, 1000), (10, 10000)];\n for (N, runs) in testCases {\n Message($\"Testing N = {N}...\");\n let max = (1 <<< N) - 1;\n let randomnessVerifier = () => CheckUniformDistribution(() =>\n Kata.RandomNBits(N), 0, max, runs);\n let isCorrect = IsSufficientlyRandom(randomnessVerifier);\n if not isCorrect {\n return false;\n }\n Message($\"Test passed for N = {N}\");\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2445
2445
|
},
|
|
2446
2446
|
{
|
|
2447
2447
|
"id": "random_numbers__weighted_random_bit__verification.qs",
|
|
2448
|
-
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Math;\n open Microsoft.Quantum.Convert;\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n for x in [0.0, 0.25, 0.5, 0.75, 1.0] {\n Message($\"Testing generating zero with {x*100.0}% probability...\");\n let randomnessVerifier = () => CheckXPercentZero(() => Kata.WeightedRandomBit(x), x);\n let isCorrect = IsSufficientlyRandom(randomnessVerifier);\n if not isCorrect {\n return false;\n }\n Message($\"Test passed for generating zero with {x*100.0}% probability\");\n }\n Message(\"All tests passed.\");\n true\n }\n\n /// # Summary\n /// Helper operation that checks that the given RNG operation generates zero with x percent probability\n /// # Input\n /// ## op\n /// Random number generation operation to be tested.\n /// ## x\n /// Probability of generating zero\n operation CheckXPercentZero (op : (Unit => Int), x : Double) : Int {\n mutable oneCount = 0;\n let nRuns = 1000;\n for N in 1..nRuns {\n let val = op();\n if (val < 0 or val > 1) {\n Message($\"Unexpected number generated. Expected 0 or 1, instead generated {val}\");\n return 0x1;\n }\n set oneCount += val;\n }\n\n let zeroCount = nRuns - oneCount;\n let goalZeroCount = (x == 0.0) ? 0 | (x == 1.0) ? nRuns | Floor(x * IntAsDouble(nRuns));\n // We don't have tests with probabilities near 0.0 or 1.0, so for those the matching has to be exact\n if (goalZeroCount == 0 or goalZeroCount == nRuns) {\n if zeroCount != goalZeroCount {\n Message($\"Expected {x * 100.0}% 0's, instead got {zeroCount} 0's out of {nRuns}\");\n return 0x2;\n }\n } else {\n if zeroCount < goalZeroCount - 4 * nRuns / 100 {\n Message($\"Unexpectedly low number of 0's generated: expected around {x * IntAsDouble(nRuns)} 0's, got {zeroCount} out of {nRuns}\");\n return 0x3;\n } elif zeroCount > goalZeroCount + 4 * nRuns / 100 {\n Message($\"Unexpectedly high number of 0's generated: expected around {x * IntAsDouble(nRuns)} 0's, got {zeroCount} out of {nRuns}\");\n return 0x4;\n }\n }\n return 0x0;\n }\n\n}\n"
|
|
2448
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Math;\n open Microsoft.Quantum.Convert;\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n for x in [0.0, 0.25, 0.5, 0.75, 1.0] {\n Message($\"Testing generating zero with {x*100.0}% probability...\");\n let randomnessVerifier = () => CheckXPercentZero(() => Kata.WeightedRandomBit(x), x);\n let isCorrect = IsSufficientlyRandom(randomnessVerifier);\n if not isCorrect {\n return false;\n }\n Message($\"Test passed for generating zero with {x*100.0}% probability\");\n }\n Message(\"All tests passed.\");\n true\n }\n\n /// # Summary\n /// Helper operation that checks that the given RNG operation generates zero with x percent probability\n /// # Input\n /// ## op\n /// Random number generation operation to be tested.\n /// ## x\n /// Probability of generating zero\n operation CheckXPercentZero (op : (Unit => Int), x : Double) : Int {\n mutable oneCount = 0;\n let nRuns = 1000;\n for N in 1..nRuns {\n let val = op();\n if (val < 0 or val > 1) {\n Message($\"Unexpected number generated. Expected 0 or 1, instead generated {val}\");\n return 0x1;\n }\n set oneCount += val;\n }\n\n let zeroCount = nRuns - oneCount;\n let goalZeroCount = (x == 0.0) ? 0 | (x == 1.0) ? nRuns | Floor(x * IntAsDouble(nRuns));\n // We don't have tests with probabilities near 0.0 or 1.0, so for those the matching has to be exact\n if (goalZeroCount == 0 or goalZeroCount == nRuns) {\n if zeroCount != goalZeroCount {\n Message($\"Expected {x * 100.0}% 0's, instead got {zeroCount} 0's out of {nRuns}\");\n return 0x2;\n }\n } else {\n if zeroCount < goalZeroCount - 4 * nRuns / 100 {\n Message($\"Unexpectedly low number of 0's generated: expected around {x * IntAsDouble(nRuns)} 0's, got {zeroCount} out of {nRuns}\");\n return 0x3;\n } elif zeroCount > goalZeroCount + 4 * nRuns / 100 {\n Message($\"Unexpectedly high number of 0's generated: expected around {x * IntAsDouble(nRuns)} 0's, got {zeroCount} out of {nRuns}\");\n return 0x4;\n }\n }\n return 0x0;\n }\n\n}\n"
|
|
2449
2449
|
},
|
|
2450
2450
|
{
|
|
2451
2451
|
"id": "random_numbers__random_number__verification.qs",
|
|
2452
|
-
"code": "namespace Kata.Verification {\n @EntryPoint()\n operation CheckSolution(): Bool {\n let testCases = [(1, 3, 1000), (27, 312, 5000), (0, 3, 1000), (0, 1023, 10000)];\n for (min, max, runs) in testCases {\n Message($\"Testing for min = {min} and max = {max}...\");\n let randomnessVerifier = () => CheckUniformDistribution(() =>\n Kata.RandomNumberInRange(min, max), min, max, runs);\n let isCorrect = IsSufficientlyRandom(randomnessVerifier);\n if not isCorrect {\n return false;\n }\n\n Message($\"Test passed for min = {min} and max = {max}\");\n }\n Message(\"All tests passed.\");\n true\n }\n}\n"
|
|
2452
|
+
"code": "namespace Kata.Verification {\n @EntryPoint()\n operation CheckSolution() : Bool {\n let testCases = [(1, 3, 1000), (27, 312, 5000), (0, 3, 1000), (0, 1023, 10000)];\n for (min, max, runs) in testCases {\n Message($\"Testing for min = {min} and max = {max}...\");\n let randomnessVerifier = () => CheckUniformDistribution(() =>\n Kata.RandomNumberInRange(min, max), min, max, runs);\n let isCorrect = IsSufficientlyRandom(randomnessVerifier);\n if not isCorrect {\n return false;\n }\n\n Message($\"Test passed for min = {min} and max = {max}\");\n }\n Message(\"All tests passed.\");\n true\n }\n}\n"
|
|
2453
2453
|
},
|
|
2454
2454
|
{
|
|
2455
2455
|
"id": "oracles__common.qs",
|
|
@@ -2457,43 +2457,43 @@ export default {
|
|
|
2457
2457
|
},
|
|
2458
2458
|
{
|
|
2459
2459
|
"id": "oracles__classical_oracles__verification.qs",
|
|
2460
|
-
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Convert;\n\n function IsSeven_Reference(x: Bool[]): Bool {\n return BoolArrayAsInt(x) == 7;\n }\n\n @EntryPoint()\n function CheckSolution(): Bool {\n let N = 3;\n for k in 0..((2^N)-1) {\n let x = IntAsBoolArray(k, N);\n\n let actual = Kata.IsSeven(x);\n let expected = IsSeven_Reference(x);\n\n if actual != expected {\n Message($\"Failed on test case x = {x}: got {actual}, expected {expected}\");\n return false;\n }\n }\n Message(\"All tests passed.\");\n true\n }\n}\n"
|
|
2460
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Convert;\n\n function IsSeven_Reference(x : Bool[]) : Bool {\n return BoolArrayAsInt(x) == 7;\n }\n\n @EntryPoint()\n function CheckSolution() : Bool {\n let N = 3;\n for k in 0..((2^N)-1) {\n let x = IntAsBoolArray(k, N);\n\n let actual = Kata.IsSeven(x);\n let expected = IsSeven_Reference(x);\n\n if actual != expected {\n Message($\"Failed on test case x = {x}: got {actual}, expected {expected}\");\n return false;\n }\n }\n Message(\"All tests passed.\");\n true\n }\n}\n"
|
|
2461
2461
|
},
|
|
2462
2462
|
{
|
|
2463
2463
|
"id": "oracles__phase_oracle_seven__verification.qs",
|
|
2464
|
-
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Arrays;\n\n operation IsSeven_PhaseOracle_Reference(x : Qubit[]) : Unit is Adj + Ctl {\n Controlled Z(Most(x), Tail(x));\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n let N = 3;\n let isCorrect = CheckOperationsEqualReferenced(\n N,\n Kata.IsSeven_PhaseOracle,\n IsSeven_PhaseOracle_Reference);\n if isCorrect {\n Message(\"All tests passed.\");\n } else {\n Message(\"Test failed: Operation is not the same as the reference operation.\");\n }\n isCorrect\n }\n}\n"
|
|
2464
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Arrays;\n\n operation IsSeven_PhaseOracle_Reference(x : Qubit[]) : Unit is Adj + Ctl {\n Controlled Z(Most(x), Tail(x));\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n let N = 3;\n let isCorrect = CheckOperationsEqualReferenced(\n N,\n Kata.IsSeven_PhaseOracle,\n IsSeven_PhaseOracle_Reference);\n if isCorrect {\n Message(\"All tests passed.\");\n } else {\n Message(\"Test failed: Operation is not the same as the reference operation.\");\n }\n isCorrect\n }\n}\n"
|
|
2465
2465
|
},
|
|
2466
2466
|
{
|
|
2467
2467
|
"id": "oracles__marking_oracle_seven__verification.qs",
|
|
2468
|
-
"code": "namespace Kata.Verification {\n\n operation IsSeven_MarkingOracle_Reference(x: Qubit[], y: Qubit): Unit is Adj + Ctl {\n Controlled X(x, y);\n }\n\n // ------------------------------------------------------\n @EntryPoint()\n operation CheckSolution () : Bool {\n let isCorrect = CheckTwoOraclesAreEqual(\n 3..3,\n Kata.IsSeven_MarkingOracle,\n IsSeven_MarkingOracle_Reference);\n if isCorrect {\n Message(\"All tests passed.\");\n } else {\n Message(\"Test failed: Operation is not the same as the reference operation.\");\n }\n isCorrect\n }\n\n}\n"
|
|
2468
|
+
"code": "namespace Kata.Verification {\n\n operation IsSeven_MarkingOracle_Reference(x : Qubit[], y : Qubit) : Unit is Adj + Ctl {\n Controlled X(x, y);\n }\n\n // ------------------------------------------------------\n @EntryPoint()\n operation CheckSolution () : Bool {\n let isCorrect = CheckTwoOraclesAreEqual(\n 3..3,\n Kata.IsSeven_MarkingOracle,\n IsSeven_MarkingOracle_Reference);\n if isCorrect {\n Message(\"All tests passed.\");\n } else {\n Message(\"Test failed: Operation is not the same as the reference operation.\");\n }\n isCorrect\n }\n\n}\n"
|
|
2469
2469
|
},
|
|
2470
2470
|
{
|
|
2471
2471
|
"id": "oracles__marking_oracle_as_phase__verification.qs",
|
|
2472
|
-
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Convert;\n\n operation ApplyMarkingOracleAsPhaseOracle_Reference(\n markingOracle: ((Qubit[], Qubit) => Unit is Adj + Ctl),\n qubits: Qubit[]) : Unit is Adj + Ctl {\n
|
|
2472
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Convert;\n\n operation ApplyMarkingOracleAsPhaseOracle_Reference(\n markingOracle : ((Qubit[], Qubit) => Unit is Adj + Ctl),\n qubits : Qubit[]) : Unit is Adj + Ctl {\n\n use minus = Qubit();\n within {\n X(minus);\n H(minus);\n } apply {\n markingOracle(qubits, minus);\n }\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n for N in 1..5 {\n for k in 0..(2^N-1) {\n let pattern = IntAsBoolArray(k, N);\n\n let isCorrect = CheckOperationsEqualReferenced(\n N,\n qubits => Kata.ApplyMarkingOracleAsPhaseOracle(\n ApplyControlledOnBitString(pattern, X, _, _),\n qubits),\n qubits => ApplyMarkingOracleAsPhaseOracle_Reference(\n ApplyControlledOnBitString(pattern, X, _, _),\n qubits));\n if not isCorrect {\n Message($\"Failed on test pattern {pattern} for a bit pattern oracle.\");\n return false;\n }\n }\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2473
2473
|
},
|
|
2474
2474
|
{
|
|
2475
2475
|
"id": "oracles__or_oracle__verification.qs",
|
|
2476
|
-
"code": "namespace Kata.Verification {\n operation Or_Oracle_Reference(x: Qubit[], y: Qubit): Unit is Adj + Ctl {\n X(y);\n ApplyControlledOnInt(0, X, x, y);\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n let isCorrect = CheckTwoOraclesAreEqual(1..7, Kata.Or_Oracle, Or_Oracle_Reference);\n if (isCorrect) {\n Message(\"All tests passed.\");\n } else {\n Message(\"Test failed: Operation is not the same as the reference operation.\");\n }\n isCorrect\n }\n}\n"
|
|
2476
|
+
"code": "namespace Kata.Verification {\n operation Or_Oracle_Reference(x : Qubit[], y : Qubit) : Unit is Adj + Ctl {\n X(y);\n ApplyControlledOnInt(0, X, x, y);\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n let isCorrect = CheckTwoOraclesAreEqual(1..7, Kata.Or_Oracle, Or_Oracle_Reference);\n if (isCorrect) {\n Message(\"All tests passed.\");\n } else {\n Message(\"Test failed: Operation is not the same as the reference operation.\");\n }\n isCorrect\n }\n}\n"
|
|
2477
2477
|
},
|
|
2478
2478
|
{
|
|
2479
2479
|
"id": "oracles__kth_bit_oracle__verification.qs",
|
|
2480
|
-
"code": "namespace Kata.Verification {\n operation KthBit_Oracle_Reference(x: Qubit[], k: Int): Unit is Adj + Ctl {\n Z(x[k]);\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n for N in 1..5 {\n for k in 0..(N-1) {\n let isCorrect = CheckOperationsEqualReferenced(\n N,\n Kata.KthBit_Oracle(_, k),\n KthBit_Oracle_Reference(_, k));\n if not isCorrect {\n Message($\"Failed on test case for NumberOfQubits = {N}, k = {k}.\");\n return false;\n }\n }\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2480
|
+
"code": "namespace Kata.Verification {\n operation KthBit_Oracle_Reference(x : Qubit[], k : Int) : Unit is Adj + Ctl {\n Z(x[k]);\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n for N in 1..5 {\n for k in 0..(N-1) {\n let isCorrect = CheckOperationsEqualReferenced(\n N,\n Kata.KthBit_Oracle(_, k),\n KthBit_Oracle_Reference(_, k));\n if not isCorrect {\n Message($\"Failed on test case for NumberOfQubits = {N}, k = {k}.\");\n return false;\n }\n }\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2481
2481
|
},
|
|
2482
2482
|
{
|
|
2483
2483
|
"id": "oracles__or_but_kth_oracle__verification.qs",
|
|
2484
|
-
"code": "namespace Kata.Verification {\n\n operation Or_Oracle_Reference(x: Qubit[], y: Qubit): Unit is Adj + Ctl {\n X(y);\n ApplyControlledOnInt(0, X, x, y);\n }\n\n operation OrOfBitsExceptKth_Oracle_Reference(x: Qubit[], k: Int): Unit is Adj + Ctl {\n use minus = Qubit();\n within {\n X(minus);\n H(minus);\n } apply {\n Or_Oracle_Reference(x[...k-1] + x[k+1...], minus);\n }\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n for N in 1..5 {\n for k in 0..(N-1) {\n let isCorrect = CheckOperationsEqualReferenced(\n N,\n Kata.OrOfBitsExceptKth_Oracle(_, k),\n OrOfBitsExceptKth_Oracle_Reference(_, k));\n if not isCorrect {\n Message($\"Failed on test case for NumberOfQubits = {N}, k = {k}.\");\n return false;\n }\n }\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2484
|
+
"code": "namespace Kata.Verification {\n\n operation Or_Oracle_Reference(x : Qubit[], y : Qubit) : Unit is Adj + Ctl {\n X(y);\n ApplyControlledOnInt(0, X, x, y);\n }\n\n operation OrOfBitsExceptKth_Oracle_Reference(x : Qubit[], k : Int) : Unit is Adj + Ctl {\n use minus = Qubit();\n within {\n X(minus);\n H(minus);\n } apply {\n Or_Oracle_Reference(x[...k-1] + x[k+1...], minus);\n }\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n for N in 1..5 {\n for k in 0..(N-1) {\n let isCorrect = CheckOperationsEqualReferenced(\n N,\n Kata.OrOfBitsExceptKth_Oracle(_, k),\n OrOfBitsExceptKth_Oracle_Reference(_, k));\n if not isCorrect {\n Message($\"Failed on test case for NumberOfQubits = {N}, k = {k}.\");\n return false;\n }\n }\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2485
2485
|
},
|
|
2486
2486
|
{
|
|
2487
2487
|
"id": "oracles__bit_pattern_oracle__verification.qs",
|
|
2488
|
-
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Convert;\n\n operation ArbitraryBitPattern_Oracle_Reference(x: Qubit[], y: Qubit, pattern: Bool[]): Unit is Adj + Ctl {\n ApplyControlledOnBitString(pattern, X, x, y);\n }\n\n // ------------------------------------------------------\n @EntryPoint()\n operation CheckSolution(): Bool {\n for N in 1..4 {\n for k in 0..((2^N)-1) {\n let pattern = IntAsBoolArray(k, N);\n\n let isCorrect = CheckTwoOraclesAreEqual(\n N..N,\n Kata.ArbitraryBitPattern_Oracle(_, _, pattern),\n ArbitraryBitPattern_Oracle_Reference(_, _, pattern));\n if not isCorrect {\n Message($\"Failed on pattern {pattern}.\");\n return false;\n }\n }\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2488
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Convert;\n\n operation ArbitraryBitPattern_Oracle_Reference(x : Qubit[], y : Qubit, pattern : Bool[]) : Unit is Adj + Ctl {\n ApplyControlledOnBitString(pattern, X, x, y);\n }\n\n // ------------------------------------------------------\n @EntryPoint()\n operation CheckSolution() : Bool {\n for N in 1..4 {\n for k in 0..((2^N)-1) {\n let pattern = IntAsBoolArray(k, N);\n\n let isCorrect = CheckTwoOraclesAreEqual(\n N..N,\n Kata.ArbitraryBitPattern_Oracle(_, _, pattern),\n ArbitraryBitPattern_Oracle_Reference(_, _, pattern));\n if not isCorrect {\n Message($\"Failed on pattern {pattern}.\");\n return false;\n }\n }\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2489
2489
|
},
|
|
2490
2490
|
{
|
|
2491
2491
|
"id": "oracles__bit_pattern_challenge__verification.qs",
|
|
2492
|
-
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Arrays;\n\n operation ArbitraryBitPattern_Oracle_Challenge_Reference(x: Qubit[], pattern: Bool[]): Unit is Adj + Ctl {\n within {\n for i in IndexRange(x) {\n if not pattern[i] {\n X(x[i]);\n }\n }\n } apply {\n Controlled Z(Most(x), Tail(x));\n }\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n for N in 1..4 {\n for k in 0..((2^N)-1) {\n let pattern = IntAsBoolArray(k, N);\n\n let isCorrect = CheckOperationsEqualReferenced(\n N,\n Kata.ArbitraryBitPattern_Oracle_Challenge(_, pattern),\n ArbitraryBitPattern_Oracle_Challenge_Reference(_, pattern));\n if not isCorrect {\n Message($\"Failed on pattern {pattern}.\");\n return false;\n }\n }\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2492
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Arrays;\n\n operation ArbitraryBitPattern_Oracle_Challenge_Reference(x : Qubit[], pattern : Bool[]) : Unit is Adj + Ctl {\n within {\n for i in IndexRange(x) {\n if not pattern[i] {\n X(x[i]);\n }\n }\n } apply {\n Controlled Z(Most(x), Tail(x));\n }\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n for N in 1..4 {\n for k in 0..((2^N)-1) {\n let pattern = IntAsBoolArray(k, N);\n\n let isCorrect = CheckOperationsEqualReferenced(\n N,\n Kata.ArbitraryBitPattern_Oracle_Challenge(_, pattern),\n ArbitraryBitPattern_Oracle_Challenge_Reference(_, pattern));\n if not isCorrect {\n Message($\"Failed on pattern {pattern}.\");\n return false;\n }\n }\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2493
2493
|
},
|
|
2494
2494
|
{
|
|
2495
2495
|
"id": "oracles__meeting_oracle__verification.qs",
|
|
2496
|
-
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Convert;\n\n operation Or_Oracle_Reference(x: Qubit[], y: Qubit): Unit is Adj + Ctl {\n X(y);\n ApplyControlledOnInt(0, X, x, y);\n }\n\n operation Meeting_Oracle_Reference(x: Qubit[], jasmine: Qubit[], y: Qubit): Unit is Adj + Ctl {\n use q = Qubit[Length(x)];\n within {\n for i in IndexRange(q) {\n // flip q[i] if both x and jasmine are free on the given day\n X(x[i]);\n X(jasmine[i]);\n CCNOT(x[i], jasmine[i], q[i]);\n }\n } apply {\n Or_Oracle_Reference(q, y);\n }\n }\n\n @EntryPoint()\n operation CheckSolution(): Bool {\n for N in 1..4 {\n use jasmine = Qubit[N];\n for k in 0..(2^N-1) {\n let binaryJasmine = IntAsBoolArray(k, N);\n mutable isCorrect = false;\n within {\n ApplyPauliFromBitString(PauliX, true, binaryJasmine, jasmine);\n } apply {\n set isCorrect = CheckTwoOraclesAreEqual(\n 1..N,\n Kata.Meeting_Oracle(_, jasmine, _),\n Meeting_Oracle_Reference(_, jasmine, _));\n }\n if not isCorrect {\n Message($\"Failed on test case for N = {N}, k = {k}.\");\n return false;\n }\n }\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2496
|
+
"code": "namespace Kata.Verification {\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Convert;\n\n operation Or_Oracle_Reference(x : Qubit[], y : Qubit) : Unit is Adj + Ctl {\n X(y);\n ApplyControlledOnInt(0, X, x, y);\n }\n\n operation Meeting_Oracle_Reference(x : Qubit[], jasmine : Qubit[], y : Qubit) : Unit is Adj + Ctl {\n use q = Qubit[Length(x)];\n within {\n for i in IndexRange(q) {\n // flip q[i] if both x and jasmine are free on the given day\n X(x[i]);\n X(jasmine[i]);\n CCNOT(x[i], jasmine[i], q[i]);\n }\n } apply {\n Or_Oracle_Reference(q, y);\n }\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n for N in 1..4 {\n use jasmine = Qubit[N];\n for k in 0..(2^N-1) {\n let binaryJasmine = IntAsBoolArray(k, N);\n mutable isCorrect = false;\n within {\n ApplyPauliFromBitString(PauliX, true, binaryJasmine, jasmine);\n } apply {\n set isCorrect = CheckTwoOraclesAreEqual(\n 1..N,\n Kata.Meeting_Oracle(_, jasmine, _),\n Meeting_Oracle_Reference(_, jasmine, _));\n }\n if not isCorrect {\n Message($\"Failed on test case for N = {N}, k = {k}.\");\n return false;\n }\n }\n }\n Message(\"All tests passed.\");\n true\n }\n\n}\n"
|
|
2497
2497
|
}
|
|
2498
2498
|
]
|
|
2499
2499
|
};
|
|
@@ -2,7 +2,7 @@ export default [
|
|
|
2
2
|
{
|
|
3
3
|
"title": "Minimal",
|
|
4
4
|
"shots": 100,
|
|
5
|
-
"code": "/// # Sample\n/// Getting started\n///\n/// # Description\n/// This is a minimal Q# program that can be used to start writing Q# code.\nnamespace MyQuantumProgram {\n
|
|
5
|
+
"code": "/// # Sample\n/// Getting started\n///\n/// # Description\n/// This is a minimal Q# program that can be used to start writing Q# code.\nnamespace MyQuantumProgram {\n\n @EntryPoint()\n operation Main() : Result[] {\n // TODO: Write your Q# code here.\n return [];\n }\n}\n"
|
|
6
6
|
},
|
|
7
7
|
{
|
|
8
8
|
"title": "Superposition",
|
|
@@ -22,7 +22,7 @@ export default [
|
|
|
22
22
|
{
|
|
23
23
|
"title": "Teleportation",
|
|
24
24
|
"shots": 1,
|
|
25
|
-
"code": "/// # Sample\n/// Quantum Teleportation\n///\n/// # Description\n/// Quantum teleportation provides a way of moving a quantum state from one\n/// location to another without having to move physical particle(s) along with\n/// it. This is done with the help of previously shared quantum entanglement\n/// between the sending and the receiving locations, and classical\n/// communication.\n///\n/// This Q# program implements quantum teleportation.\nnamespace Sample {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Measurement;\n\n @EntryPoint()\n operation Main () : Result[] {\n // Allocate the message and target qubits.\n use (message, target) = (Qubit(), Qubit());\n\n // Use the `Teleport` operation to send different quantum states.\n let stateInitializerBasisTuples = [\n (\"|0〉\", I, PauliZ),\n (\"|1〉\", X, PauliZ),\n (\"|+〉\", SetToPlus, PauliX),\n (\"|-〉\", SetToMinus, PauliX)\n ];\n\n mutable results = [];\n for (state, initializer, basis) in stateInitializerBasisTuples {\n // Initialize the message and show its state using the `DumpMachine`\n // function.\n initializer(message);\n Message($\"Teleporting state {state}\");\n DumpMachine();\n\n // Teleport the message and show the quantum state after\n // teleportation.\n Teleport(message, target);\n Message($\"Received state {state}\");\n DumpMachine();\n\n // Measure target in the corresponding basis and reset the qubits to\n // continue teleporting more messages.\n let result = Measure([basis], [target]);\n set results += [result];\n ResetAll([message, target]);\n }\n\n return results;\n }\n\n /// # Summary\n /// Sends the state of one qubit to a target qubit by using teleportation.\n ///\n /// Notice that after calling Teleport, the state of `message` is collapsed.\n ///\n /// # Input\n /// ## message\n /// A qubit whose state we wish to send.\n /// ## target\n /// A qubit initially in the |0〉 state that we want to send\n /// the state of message to.\n operation Teleport(message : Qubit, target : Qubit) : Unit {\n // Allocate an auxiliary qubit.\n use auxiliary = Qubit();\n\n // Create some entanglement that we can use to send our message.\n H(auxiliary);\n CNOT(auxiliary, target);\n\n // Encode the message into the entangled pair.\n CNOT(message, auxiliary);\n H(message);\n\n // Measure the qubits to extract the classical data we need to decode\n // the message by applying the corrections on the target qubit\n // accordingly.\n if M(message) == One {\n Z(target);\n }\n if M(auxiliary) == One {\n X(target);\n }\n\n // Reset auxiliary qubit before releasing.\n Reset(auxiliary);\n }\n\n /// # Summary\n /// Sets a qubit in state |0⟩ to |+⟩.\n operation SetToPlus(q: Qubit) : Unit is Adj + Ctl {\n H(q);\n }\n\n /// # Summary\n /// Sets a qubit in state |0⟩ to |−⟩.\n operation SetToMinus(q: Qubit) : Unit is Adj + Ctl {\n X(q);\n H(q);\n }\n}\n"
|
|
25
|
+
"code": "/// # Sample\n/// Quantum Teleportation\n///\n/// # Description\n/// Quantum teleportation provides a way of moving a quantum state from one\n/// location to another without having to move physical particle(s) along with\n/// it. This is done with the help of previously shared quantum entanglement\n/// between the sending and the receiving locations, and classical\n/// communication.\n///\n/// This Q# program implements quantum teleportation.\nnamespace Sample {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Measurement;\n\n @EntryPoint()\n operation Main () : Result[] {\n // Allocate the message and target qubits.\n use (message, target) = (Qubit(), Qubit());\n\n // Use the `Teleport` operation to send different quantum states.\n let stateInitializerBasisTuples = [\n (\"|0〉\", I, PauliZ),\n (\"|1〉\", X, PauliZ),\n (\"|+〉\", SetToPlus, PauliX),\n (\"|-〉\", SetToMinus, PauliX)\n ];\n\n mutable results = [];\n for (state, initializer, basis) in stateInitializerBasisTuples {\n // Initialize the message and show its state using the `DumpMachine`\n // function.\n initializer(message);\n Message($\"Teleporting state {state}\");\n DumpMachine();\n\n // Teleport the message and show the quantum state after\n // teleportation.\n Teleport(message, target);\n Message($\"Received state {state}\");\n DumpMachine();\n\n // Measure target in the corresponding basis and reset the qubits to\n // continue teleporting more messages.\n let result = Measure([basis], [target]);\n set results += [result];\n ResetAll([message, target]);\n }\n\n return results;\n }\n\n /// # Summary\n /// Sends the state of one qubit to a target qubit by using teleportation.\n ///\n /// Notice that after calling Teleport, the state of `message` is collapsed.\n ///\n /// # Input\n /// ## message\n /// A qubit whose state we wish to send.\n /// ## target\n /// A qubit initially in the |0〉 state that we want to send\n /// the state of message to.\n operation Teleport(message : Qubit, target : Qubit) : Unit {\n // Allocate an auxiliary qubit.\n use auxiliary = Qubit();\n\n // Create some entanglement that we can use to send our message.\n H(auxiliary);\n CNOT(auxiliary, target);\n\n // Encode the message into the entangled pair.\n CNOT(message, auxiliary);\n H(message);\n\n // Measure the qubits to extract the classical data we need to decode\n // the message by applying the corrections on the target qubit\n // accordingly.\n if M(message) == One {\n Z(target);\n }\n if M(auxiliary) == One {\n X(target);\n }\n\n // Reset auxiliary qubit before releasing.\n Reset(auxiliary);\n }\n\n /// # Summary\n /// Sets a qubit in state |0⟩ to |+⟩.\n operation SetToPlus(q : Qubit) : Unit is Adj + Ctl {\n H(q);\n }\n\n /// # Summary\n /// Sets a qubit in state |0⟩ to |−⟩.\n operation SetToMinus(q : Qubit) : Unit is Adj + Ctl {\n X(q);\n H(q);\n }\n}\n"
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
"title": "Random Bit",
|
|
@@ -47,16 +47,16 @@ export default [
|
|
|
47
47
|
{
|
|
48
48
|
"title": "Grover's search",
|
|
49
49
|
"shots": 100,
|
|
50
|
-
"code": "/// # Sample\n/// Grover's search algorithm\n///\n/// # Description\n/// Grover's search algorithm is a quantum algorithm that finds with high\n/// probability the unique input to a black box function that produces a\n/// particular output value.\n///\n/// This Q# program implements the Grover's search algorithm.\nnamespace Sample {\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Math;\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Measurement;\n open Microsoft.Quantum.Diagnostics;\n\n @EntryPoint()\n operation Main() : Result[] {\n let nQubits = 5;\n\n // Grover's algorithm relies on performing a \"Grover iteration\" an\n // optimal number of times to maximize the probability of finding the\n // value we are searching for.\n // You can set the number iterations to a value lower than optimal to\n // intentionally reduce precision.\n let iterations = CalculateOptimalIterations(nQubits);\n Message($\"Number of iterations: {iterations}\");\n\n // Use Grover's algorithm to find a particular marked state.\n let results = GroverSearch(nQubits, iterations, ReflectAboutMarked);\n return results;\n }\n\n /// # Summary\n /// Implements Grover's algorithm, which searches all possible inputs to an\n /// operation to find a particular marked state.\n operation GroverSearch(\n nQubits: Int,\n iterations: Int,\n phaseOracle: Qubit[] => Unit): Result[] {\n\n use qubits = Qubit[nQubits];\n\n // Initialize a uniform superposition over all possible inputs.\n PrepareUniform(qubits);\n\n // The search itself consists of repeatedly reflecting about the marked\n // state and our start state, which we can write out in Q# as a for loop.\n for _ in 1..iterations {\n phaseOracle(qubits);\n ReflectAboutUniform(qubits);\n }\n\n // Measure and return the answer.\n return MResetEachZ(qubits);\n }\n\n /// # Summary\n /// Returns the optimal number of Grover iterations needed to find a marked\n /// item, given the number of qubits in a register.\n function CalculateOptimalIterations(nQubits : Int) : Int {\n let nItems = 1 <<< nQubits; // 2^nQubits\n let angle = ArcSin(1. / Sqrt(IntAsDouble(nItems)));\n let iterations = Round(0.25 * PI() / angle - 0.5);\n return iterations;\n }\n\n /// # Summary\n /// Reflects about the basis state marked by alternating zeros and ones.\n /// This operation defines what input we are trying to find in the search.\n operation ReflectAboutMarked(inputQubits : Qubit[]) : Unit {\n Message(\"Reflecting about marked state...\");\n use outputQubit = Qubit();\n within {\n // We initialize the outputQubit to (|0⟩ - |1⟩) / √2, so that\n // toggling it results in a (-1) phase.\n X(outputQubit);\n H(outputQubit);\n // Flip the outputQubit for marked states.\n // Here, we get the state with alternating 0s and 1s by using the X\n // operation on every other qubit.\n for q in inputQubits[...2...] {\n X(q);\n }\n } apply {\n Controlled X(inputQubits, outputQubit);\n }\n }\n\n /// # Summary\n /// Given a register in the all-zeros state, prepares a uniform\n /// superposition over all basis states.\n operation PrepareUniform(inputQubits : Qubit[]): Unit is Adj + Ctl {\n for q in inputQubits {\n H(q);\n }\n }\n\n /// # Summary\n /// Reflects about the all-ones state.\n operation ReflectAboutAllOnes(inputQubits : Qubit[]): Unit {\n Controlled Z(Most(inputQubits), Tail(inputQubits));\n }\n\n /// # Summary\n /// Reflects about the uniform superposition state.\n operation ReflectAboutUniform(inputQubits : Qubit[]): Unit {\n within {\n // Transform the uniform superposition to all-zero.\n Adjoint PrepareUniform(inputQubits);\n // Transform the all-zero state to all-ones\n for q in inputQubits {\n X(q);\n }\n } apply {\n // Now that we've transformed the uniform superposition to the\n // all-ones state, reflect about the all-ones state, then let the\n // within/apply block transform us back.\n ReflectAboutAllOnes(inputQubits);\n }\n }\n}\n"
|
|
50
|
+
"code": "/// # Sample\n/// Grover's search algorithm\n///\n/// # Description\n/// Grover's search algorithm is a quantum algorithm that finds with high\n/// probability the unique input to a black box function that produces a\n/// particular output value.\n///\n/// This Q# program implements the Grover's search algorithm.\nnamespace Sample {\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Math;\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Measurement;\n open Microsoft.Quantum.Diagnostics;\n\n @EntryPoint()\n operation Main() : Result[] {\n let nQubits = 5;\n\n // Grover's algorithm relies on performing a \"Grover iteration\" an\n // optimal number of times to maximize the probability of finding the\n // value we are searching for.\n // You can set the number iterations to a value lower than optimal to\n // intentionally reduce precision.\n let iterations = CalculateOptimalIterations(nQubits);\n Message($\"Number of iterations: {iterations}\");\n\n // Use Grover's algorithm to find a particular marked state.\n let results = GroverSearch(nQubits, iterations, ReflectAboutMarked);\n return results;\n }\n\n /// # Summary\n /// Implements Grover's algorithm, which searches all possible inputs to an\n /// operation to find a particular marked state.\n operation GroverSearch(\n nQubits : Int,\n iterations : Int,\n phaseOracle : Qubit[] => Unit) : Result[] {\n\n use qubits = Qubit[nQubits];\n\n // Initialize a uniform superposition over all possible inputs.\n PrepareUniform(qubits);\n\n // The search itself consists of repeatedly reflecting about the marked\n // state and our start state, which we can write out in Q# as a for loop.\n for _ in 1..iterations {\n phaseOracle(qubits);\n ReflectAboutUniform(qubits);\n }\n\n // Measure and return the answer.\n return MResetEachZ(qubits);\n }\n\n /// # Summary\n /// Returns the optimal number of Grover iterations needed to find a marked\n /// item, given the number of qubits in a register.\n function CalculateOptimalIterations(nQubits : Int) : Int {\n let nItems = 1 <<< nQubits; // 2^nQubits\n let angle = ArcSin(1. / Sqrt(IntAsDouble(nItems)));\n let iterations = Round(0.25 * PI() / angle - 0.5);\n return iterations;\n }\n\n /// # Summary\n /// Reflects about the basis state marked by alternating zeros and ones.\n /// This operation defines what input we are trying to find in the search.\n operation ReflectAboutMarked(inputQubits : Qubit[]) : Unit {\n Message(\"Reflecting about marked state...\");\n use outputQubit = Qubit();\n within {\n // We initialize the outputQubit to (|0⟩ - |1⟩) / √2, so that\n // toggling it results in a (-1) phase.\n X(outputQubit);\n H(outputQubit);\n // Flip the outputQubit for marked states.\n // Here, we get the state with alternating 0s and 1s by using the X\n // operation on every other qubit.\n for q in inputQubits[...2...] {\n X(q);\n }\n } apply {\n Controlled X(inputQubits, outputQubit);\n }\n }\n\n /// # Summary\n /// Given a register in the all-zeros state, prepares a uniform\n /// superposition over all basis states.\n operation PrepareUniform(inputQubits : Qubit[]) : Unit is Adj + Ctl {\n for q in inputQubits {\n H(q);\n }\n }\n\n /// # Summary\n /// Reflects about the all-ones state.\n operation ReflectAboutAllOnes(inputQubits : Qubit[]) : Unit {\n Controlled Z(Most(inputQubits), Tail(inputQubits));\n }\n\n /// # Summary\n /// Reflects about the uniform superposition state.\n operation ReflectAboutUniform(inputQubits : Qubit[]) : Unit {\n within {\n // Transform the uniform superposition to all-zero.\n Adjoint PrepareUniform(inputQubits);\n // Transform the all-zero state to all-ones\n for q in inputQubits {\n X(q);\n }\n } apply {\n // Now that we've transformed the uniform superposition to the\n // all-ones state, reflect about the all-ones state, then let the\n // within/apply block transform us back.\n ReflectAboutAllOnes(inputQubits);\n }\n }\n}\n"
|
|
51
51
|
},
|
|
52
52
|
{
|
|
53
53
|
"title": "Hidden shift",
|
|
54
54
|
"shots": 1,
|
|
55
|
-
"code": "/// # Sample\n/// Hidden shift\n///\n/// # Description\n/// There is a family of problems known as hidden shift problems, in which it\n/// is given that two Boolean functions 𝑓 and 𝑔 satisfy the relation\n/// 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠) for all 𝑥\n/// where 𝑠 is a hidden bit string that we would like to find.\n///\n/// This Q# program implements an algorithm to solve the hidden shift problem.\nnamespace Sample {\n open Microsoft.Quantum.Arithmetic;\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Measurement;\n\n @EntryPoint()\n operation Main(): Int[] {\n let nQubits = 10;\n\n // Consider the case of finding a hidden shift 𝑠 between two Boolean\n // functions 𝑓(𝑥) and 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠).\n // This problem can be solved on a quantum computer with one call to\n // each of 𝑓 and 𝑔 in the special case that both functions are bent;\n // that is, that they are as far from linear as possible.\n\n // Here, we find the hidden shift for various pairs of bent functions.\n let shifts = [170, 512, 999];\n mutable hiddenShifts = [];\n for shift in shifts {\n let hiddenShiftBitString = FindHiddenShift(\n BentFunction,\n register => ShiftedBentFunction(shift, register),\n nQubits);\n let hiddenShift = ResultArrayAsInt(hiddenShiftBitString);\n Fact(\n hiddenShift == shift,\n $\"Found shift {hiddenShift}, but expected {shift}.\");\n Message($\"Found {shift} successfully!\");\n set hiddenShifts += [hiddenShift];\n }\n\n return hiddenShifts;\n }\n\n /// # Summary\n /// Implements a correlation-based algorithm to solve the hidden shift\n /// problem for bent functions.\n ///\n /// # Description\n /// Implements a solution for the hidden shift problem, which is to identify\n /// an unknown shift 𝑠 of the arguments of two Boolean functions 𝑓 and 𝑔\n /// that are promised to satisfy the relation 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠) for all 𝑥.\n ///\n /// 𝑓 and 𝑔 are assumed to be bent functions. A Boolean function is bent if\n /// it is as far from linear as possible. In particular, bent functions have\n /// flat Fourier (Walsh–Hadamard) spectra.\n ///\n /// In this case, the Roetteler algorithm (see References, below) uses\n /// black-box oracles for 𝑓^* and 𝑔, where 𝑓^* is the dual bent function to\n /// 𝑓, and computes the hidden shift 𝑠 between 𝑓 and 𝑔.\n ///\n /// # Input\n /// ## Ufstar\n /// A quantum operation that implements\n /// $U_f^*: |𝑥〉 ↦ (-1)^{f^*(x)} |𝑥〉$,\n /// where $f^*$ is a Boolean function, 𝑥 is an $n$ bit register\n /// ## Ug\n /// A quantum operation that implements\n /// $U_g:|𝑥〉 ↦ (-1)^{g(x)} |𝑥〉$,\n /// where 𝑔 is a Boolean function that is shifted by unknown\n /// 𝑠 from 𝑓, and 𝑥 is an $n$ bit register.\n /// ## n\n /// The number of bits of the input register |𝑥〉.\n ///\n /// # Output\n /// An array of type `Result[]` which encodes the bit representation\n /// of the hidden shift.\n ///\n /// # References\n /// - [*Martin Roetteler*,\n /// Proc. SODA 2010, ACM, pp. 448-457, 2010]\n /// (https://doi.org/10.1137/1.9781611973075.37)\n operation FindHiddenShift (\n Ufstar : (Qubit[] => Unit),\n Ug : (Qubit[] => Unit),\n n: Int)\n : Result[] {\n // We allocate n clean qubits. Note that the function Ufstar and Ug are\n // unitary operations on n qubits defined via phase encoding.\n use qubits = Qubit[n];\n\n // First, a Hadamard transform is applied to each of the qubits.\n ApplyToEach(H, qubits);\n\n // We now apply the shifted function Ug to the n qubits, computing\n // |x〉 -> (-1)^{g(x)} |x〉.\n Ug(qubits);\n\n within {\n // A Hadamard transform is applied to each of the n qubits.\n ApplyToEachA(H, qubits);\n } apply {\n // we now apply the dual function of the unshifted function, i.e.,\n // Ufstar, to the n qubits, computing |x〉 -> (-1)^{fstar(x)} |x〉.\n Ufstar(qubits);\n }\n\n // Measure the n qubits and reset them to zero so that they can be\n // safely deallocated at the end of the block.\n return ForEach(MResetZ, qubits);\n }\n\n /// # Summary\n /// Implements an oracle for a bent function constructed from the inner\n /// product of Boolean functions.\n ///\n /// # Description\n /// This operation defines the Boolean function IP(x_0, ..., x_{n-1}) which\n /// is computed into the phase, i.e., a diagonal operator that maps\n /// |x〉 -> (-1)^{IP(x)} |x〉, where x stands for x=(x_0, ..., x_{n-1}) and all\n /// the x_i are binary. The IP function is defined as\n /// IP(y, z) = y_0 z_0 + y_1 z_1 + ... y_{u-1} z_{u-1} where\n /// y = (y_0, ..., y_{u-1}) and z = (z_0, ..., z_{u-1}) are two bit vectors\n /// of length u. Notice that the function IP is a Boolean function on n = 2u\n /// bits. IP is a special case of bent function. These are functions for\n /// which the Walsh-Hadamard transform is perfectly flat (in absolute\n /// value).\n /// Because of this flatness, the Walsh-Hadamard spectrum of any bent\n /// function defines a +1/-1 function, i.e., gives rise to another Boolean\n /// function, called the dual bent function. Moreover, for the case of the\n /// IP function it can be shown that IP is equal to its own dual bent\n /// function.\n ///\n /// # Remarks\n /// Notice that a diagonal operator implementing IP between 2 variables y_0\n /// and z_0 is nothing but the AND function between those variables, i.e.,\n /// in phase encoding it is computed by a Controlled-Z gate.\n /// Extending this to an XOR of the AND of more variables, as required in\n /// the definition of the IP function can then be accomplished by applying\n /// several Controlled-Z gates between the respective inputs.\n operation BentFunction(register : Qubit[]) : Unit {\n Fact(Length(register) % 2 == 0, \"Length of register must be even.\");\n let u = Length(register) / 2;\n let xs = register[0 .. u - 1];\n let ys = register[u...];\n for index in 0..u-1 {\n CZ(xs[index], ys[index]);\n }\n }\n\n /// # Summary\n /// Implements a shifted bend function 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠).\n ///\n /// # Description\n /// For the hidden shift problem we need another function g which is related\n /// to IP via g(x) = IP(x + s), i.e., we have to shift the argument of the\n /// IP function by a given shift. Notice that the '+' operation here is the\n /// Boolean addition, i.e., a bit-wise operation. Notice further, that in\n /// general a diagonal operation |x〉 -> (-1)^{f(x)} can be turned into a\n /// shifted version by applying a bit flip to the |x〉 register first, then\n /// applying the diagonal operation, and then undoing the bit flips to the\n /// |x〉 register. We use this principle to define shifted versions of the IP\n /// operation.\n operation ShiftedBentFunction(shift: Int, register: Qubit[]) : Unit {\n Fact(Length(register) % 2 == 0, \"Length of register must be even.\");\n let u = Length(register) / 2;\n within {\n // Flips the bits in shift.\n ApplyXorInPlace(shift, register);\n } apply {\n // Compute the IP function into the phase.\n BentFunction(register);\n }\n }\n}\n"
|
|
55
|
+
"code": "/// # Sample\n/// Hidden shift\n///\n/// # Description\n/// There is a family of problems known as hidden shift problems, in which it\n/// is given that two Boolean functions 𝑓 and 𝑔 satisfy the relation\n/// 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠) for all 𝑥\n/// where 𝑠 is a hidden bit string that we would like to find.\n///\n/// This Q# program implements an algorithm to solve the hidden shift problem.\nnamespace Sample {\n open Microsoft.Quantum.Arithmetic;\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Measurement;\n\n @EntryPoint()\n operation Main() : Int[] {\n let nQubits = 10;\n\n // Consider the case of finding a hidden shift 𝑠 between two Boolean\n // functions 𝑓(𝑥) and 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠).\n // This problem can be solved on a quantum computer with one call to\n // each of 𝑓 and 𝑔 in the special case that both functions are bent;\n // that is, that they are as far from linear as possible.\n\n // Here, we find the hidden shift for various pairs of bent functions.\n let shifts = [170, 512, 999];\n mutable hiddenShifts = [];\n for shift in shifts {\n let hiddenShiftBitString = FindHiddenShift(\n BentFunction,\n register => ShiftedBentFunction(shift, register),\n nQubits);\n let hiddenShift = ResultArrayAsInt(hiddenShiftBitString);\n Fact(\n hiddenShift == shift,\n $\"Found shift {hiddenShift}, but expected {shift}.\");\n Message($\"Found {shift} successfully!\");\n set hiddenShifts += [hiddenShift];\n }\n\n return hiddenShifts;\n }\n\n /// # Summary\n /// Implements a correlation-based algorithm to solve the hidden shift\n /// problem for bent functions.\n ///\n /// # Description\n /// Implements a solution for the hidden shift problem, which is to identify\n /// an unknown shift 𝑠 of the arguments of two Boolean functions 𝑓 and 𝑔\n /// that are promised to satisfy the relation 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠) for all 𝑥.\n ///\n /// 𝑓 and 𝑔 are assumed to be bent functions. A Boolean function is bent if\n /// it is as far from linear as possible. In particular, bent functions have\n /// flat Fourier (Walsh–Hadamard) spectra.\n ///\n /// In this case, the Roetteler algorithm (see References, below) uses\n /// black-box oracles for 𝑓^* and 𝑔, where 𝑓^* is the dual bent function to\n /// 𝑓, and computes the hidden shift 𝑠 between 𝑓 and 𝑔.\n ///\n /// # Input\n /// ## Ufstar\n /// A quantum operation that implements\n /// $U_f^*: |𝑥〉 ↦ (-1)^{f^*(x)} |𝑥〉$,\n /// where $f^*$ is a Boolean function, 𝑥 is an $n$ bit register\n /// ## Ug\n /// A quantum operation that implements\n /// $U_g:|𝑥〉 ↦ (-1)^{g(x)} |𝑥〉$,\n /// where 𝑔 is a Boolean function that is shifted by unknown\n /// 𝑠 from 𝑓, and 𝑥 is an $n$ bit register.\n /// ## n\n /// The number of bits of the input register |𝑥〉.\n ///\n /// # Output\n /// An array of type `Result[]` which encodes the bit representation\n /// of the hidden shift.\n ///\n /// # References\n /// - [*Martin Roetteler*,\n /// Proc. SODA 2010, ACM, pp. 448-457, 2010]\n /// (https://doi.org/10.1137/1.9781611973075.37)\n operation FindHiddenShift (\n Ufstar : (Qubit[] => Unit),\n Ug : (Qubit[] => Unit),\n n : Int)\n : Result[] {\n // We allocate n clean qubits. Note that the function Ufstar and Ug are\n // unitary operations on n qubits defined via phase encoding.\n use qubits = Qubit[n];\n\n // First, a Hadamard transform is applied to each of the qubits.\n ApplyToEach(H, qubits);\n\n // We now apply the shifted function Ug to the n qubits, computing\n // |x〉 -> (-1)^{g(x)} |x〉.\n Ug(qubits);\n\n within {\n // A Hadamard transform is applied to each of the n qubits.\n ApplyToEachA(H, qubits);\n } apply {\n // we now apply the dual function of the unshifted function, i.e.,\n // Ufstar, to the n qubits, computing |x〉 -> (-1)^{fstar(x)} |x〉.\n Ufstar(qubits);\n }\n\n // Measure the n qubits and reset them to zero so that they can be\n // safely deallocated at the end of the block.\n return ForEach(MResetZ, qubits);\n }\n\n /// # Summary\n /// Implements an oracle for a bent function constructed from the inner\n /// product of Boolean functions.\n ///\n /// # Description\n /// This operation defines the Boolean function IP(x_0, ..., x_{n-1}) which\n /// is computed into the phase, i.e., a diagonal operator that maps\n /// |x〉 -> (-1)^{IP(x)} |x〉, where x stands for x=(x_0, ..., x_{n-1}) and all\n /// the x_i are binary. The IP function is defined as\n /// IP(y, z) = y_0 z_0 + y_1 z_1 + ... y_{u-1} z_{u-1} where\n /// y = (y_0, ..., y_{u-1}) and z = (z_0, ..., z_{u-1}) are two bit vectors\n /// of length u. Notice that the function IP is a Boolean function on n = 2u\n /// bits. IP is a special case of bent function. These are functions for\n /// which the Walsh-Hadamard transform is perfectly flat (in absolute\n /// value).\n /// Because of this flatness, the Walsh-Hadamard spectrum of any bent\n /// function defines a +1/-1 function, i.e., gives rise to another Boolean\n /// function, called the dual bent function. Moreover, for the case of the\n /// IP function it can be shown that IP is equal to its own dual bent\n /// function.\n ///\n /// # Remarks\n /// Notice that a diagonal operator implementing IP between 2 variables y_0\n /// and z_0 is nothing but the AND function between those variables, i.e.,\n /// in phase encoding it is computed by a Controlled-Z gate.\n /// Extending this to an XOR of the AND of more variables, as required in\n /// the definition of the IP function can then be accomplished by applying\n /// several Controlled-Z gates between the respective inputs.\n operation BentFunction(register : Qubit[]) : Unit {\n Fact(Length(register) % 2 == 0, \"Length of register must be even.\");\n let u = Length(register) / 2;\n let xs = register[0 .. u - 1];\n let ys = register[u...];\n for index in 0..u-1 {\n CZ(xs[index], ys[index]);\n }\n }\n\n /// # Summary\n /// Implements a shifted bend function 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠).\n ///\n /// # Description\n /// For the hidden shift problem we need another function g which is related\n /// to IP via g(x) = IP(x + s), i.e., we have to shift the argument of the\n /// IP function by a given shift. Notice that the '+' operation here is the\n /// Boolean addition, i.e., a bit-wise operation. Notice further, that in\n /// general a diagonal operation |x〉 -> (-1)^{f(x)} can be turned into a\n /// shifted version by applying a bit flip to the |x〉 register first, then\n /// applying the diagonal operation, and then undoing the bit flips to the\n /// |x〉 register. We use this principle to define shifted versions of the IP\n /// operation.\n operation ShiftedBentFunction(shift : Int, register : Qubit[]) : Unit {\n Fact(Length(register) % 2 == 0, \"Length of register must be even.\");\n let u = Length(register) / 2;\n within {\n // Flips the bits in shift.\n ApplyXorInPlace(shift, register);\n } apply {\n // Compute the IP function into the phase.\n BentFunction(register);\n }\n }\n}\n"
|
|
56
56
|
},
|
|
57
57
|
{
|
|
58
58
|
"title": "Shor",
|
|
59
59
|
"shots": 1,
|
|
60
|
-
"code": "/// # Sample\n/// Shor's algorithm\n///\n/// # Description\n/// Shor's algorithm is a quantum algorithm for finding the prime factors of an\n/// integer.\n///\n/// This Q# program implements Shor's algorithm.\nnamespace Sample {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Random;\n open Microsoft.Quantum.Math;\n open Microsoft.Quantum.Arithmetic;\n open Microsoft.Quantum.Arrays;\n\n @EntryPoint()\n operation Main() : (Int, Int) {\n let n = 143; // 11*13;\n // You can try these other examples for a lengthier computation.\n // let n = 16837; // = 113*149\n // let n = 22499; // = 149*151\n\n // Use Shor's algorithm to factor a semiprime integer.\n let (a, b) = FactorSemiprimeInteger(n);\n Message($\"Found factorization {n} = {a} * {b} \");\n return (a, b);\n }\n\n /// # Summary\n /// Uses Shor's algorithm to factor an input number.\n ///\n /// # Input\n /// ## number\n /// A semiprime integer to be factored.\n ///\n /// # Output\n /// Pair of numbers p > 1 and q > 1 such that p⋅q = `number`\n operation FactorSemiprimeInteger(number : Int) : (Int, Int) {\n // First check the most trivial case (the provided number is even).\n if number % 2 == 0 {\n Message(\"An even number has been given; 2 is a factor.\");\n return (number / 2, 2);\n }\n // These mutables will keep track of whether we found the factors, and\n // if so, what they are. The default value for the factors is (1,1).\n mutable foundFactors = false;\n mutable factors = (1, 1);\n mutable attempt = 1;\n repeat {\n Message($\"*** Factorizing {number}, attempt {attempt}.\");\n // Try to guess a number co-prime to `number` by getting a random\n // integer in the interval [1, number-1]\n let generator = DrawRandomInt(1, number - 1);\n\n // Check if the random integer is indeed co-prime.\n // If true use Quantum algorithm for Period finding.\n if GreatestCommonDivisorI(generator, number) == 1 {\n Message($\"Estimating period of {generator}.\");\n\n // Call Quantum Period finding algorithm for\n // `generator` mod `number`.\n let period = EstimatePeriod(generator, number);\n\n // Set the flag and factors values if the continued\n // fractions classical algorithm succeeds.\n set (foundFactors, factors) =\n MaybeFactorsFromPeriod(number, generator, period);\n }\n // In this case, we guessed a divisor by accident.\n else {\n // Find divisor.\n let gcd = GreatestCommonDivisorI(number, generator);\n Message($\"We have guessed a divisor {gcd} by accident. \" + \n \"No quantum computation was done.\");\n\n // Set the flag `foundFactors` to true, indicating that we\n // succeeded in finding factors.\n set foundFactors = true;\n set factors = (gcd, number / gcd);\n }\n set attempt = attempt+1;\n if (attempt > 100) {\n fail \"Failed to find factors: too many attempts!\";\n }\n }\n until foundFactors\n fixup {\n Message(\"The estimated period did not yield a valid factor. \" + \n \"Trying again.\");\n }\n\n // Return the factorization\n return factors;\n }\n\n /// # Summary\n /// Tries to find the factors of `modulus` given a `period` and `generator`.\n ///\n /// # Input\n /// ## modulus\n /// The modulus which defines the residue ring Z mod `modulus` in which the\n /// multiplicative order of `generator` is being estimated.\n /// ## generator\n /// The unsigned integer multiplicative order (period) of which is being\n /// estimated. Must be co-prime to `modulus`.\n /// ## period\n /// The estimated period (multiplicative order) of the generator mod\n /// `modulus`.\n ///\n /// # Output\n /// A tuple of a flag indicating whether factors were found successfully,\n /// and a pair of integers representing the factors that were found.\n /// Note that the second output is only meaningful when the first output is\n /// `true`.\n function MaybeFactorsFromPeriod(\n modulus : Int,\n generator : Int,\n period : Int)\n : (Bool, (Int, Int)) {\n\n // Period finding reduces to factoring only if period is even\n if period % 2 == 0 {\n // Compute `generator` ^ `period/2` mod `number`.\n let halfPower = ExpModI(generator, period / 2, modulus);\n\n // If we are unlucky, halfPower is just -1 mod N, which is a trivial\n // case and not useful for factoring.\n if halfPower != modulus - 1 {\n // When the halfPower is not -1 mod N, halfPower-1 or\n // halfPower+1 share non-trivial divisor with `number`. Find it.\n let factor = MaxI(\n GreatestCommonDivisorI(halfPower - 1, modulus),\n GreatestCommonDivisorI(halfPower + 1, modulus)\n );\n\n // Add a flag that we found the factors, and return computed\n // non-trivial factors.\n Message($\"Found factor={factor}\");\n return (true, (factor, modulus / factor));\n } else {\n // Return a flag indicating we hit a trivial case and didn't get\n // any factors.\n Message($\"Found trivial factors.\");\n return (false, (1, 1));\n }\n } else {\n // When period is odd we have to pick another generator to estimate\n // period of and start over.\n Message($\"Estimated period {period} was odd, trying again.\");\n return (false, (1, 1));\n }\n }\n\n /// # Summary\n /// Find the period of a number from an input frequency.\n ///\n /// # Input\n /// ## modulus\n /// The modulus which defines the residue ring Z mod `modulus` in which the\n /// multiplicative order of `generator` is being estimated.\n /// ## frequencyEstimate\n /// The frequency that we want to convert to a period.\n /// ## bitsPrecision\n /// Number of bits of precision with which we need to estimate s/r to\n /// recover period r using continued fractions algorithm.\n /// ## currentDivisor\n /// The divisor of the generator period found so far.\n ///\n /// # Output\n /// The period as calculated from the estimated frequency via the continued\n /// fractions algorithm.\n function PeriodFromFrequency(\n modulus : Int,\n frequencyEstimate : Int,\n bitsPrecision : Int,\n currentDivisor : Int)\n : Int {\n // Now we use the ContinuedFractionConvergentI function to recover s/r\n // from dyadic fraction k/2^bitsPrecision.\n let (numerator, period) = ContinuedFractionConvergentI(\n (frequencyEstimate, 2 ^ bitsPrecision),\n modulus);\n\n // ContinuedFractionConvergentI does not guarantee the signs of the\n // numerator and denominator. Here we make sure that both are positive\n // using AbsI.\n let (numeratorAbs, periodAbs) = (AbsI(numerator), AbsI(period));\n\n // Compute and return the newly found divisor.\n let period =\n (periodAbs * currentDivisor) /\n GreatestCommonDivisorI(currentDivisor, periodAbs);\n Message($\"Found period={period}\");\n return period;\n }\n\n /// # Summary\n /// Finds a multiplicative order of the generator in the residue ring Z mod\n /// `modulus`.\n ///\n /// # Input\n /// ## generator\n /// The unsigned integer multiplicative order (period) of which is being\n /// estimated. Must be co-prime to `modulus`.\n /// ## modulus\n /// The modulus which defines the residue ring Z mod `modulus` in which the\n /// multiplicative order of `generator` is being estimated.\n ///\n /// # Output\n /// The period (multiplicative order) of the generator mod `modulus`\n operation EstimatePeriod(generator : Int, modulus : Int) : Int {\n // Here we check that the inputs to the EstimatePeriod operation are\n // valid.\n Fact(\n GreatestCommonDivisorI(generator, modulus) == 1,\n \"`generator` and `modulus` must be co-prime\");\n\n // Number of bits in the modulus with respect to which we are estimating\n // the period.\n let bitsize = BitSizeI(modulus);\n\n // The EstimatePeriod operation estimates the period r by finding an\n // approximation k/2^(bits precision) to a fraction s/r, where s is some\n // integer. Note that if s and r have common divisors we will end up\n // recovering a divisor of r and not r itself.\n\n // Number of bits of precision with which we need to estimate s/r to\n // recover period r, using continued fractions algorithm.\n let bitsPrecision = 2 * bitsize + 1;\n\n // Current estimate for the frequency of the form s/r.\n let frequencyEstimate = EstimateFrequency(generator, modulus, bitsize);\n if frequencyEstimate != 0 {\n return PeriodFromFrequency(\n modulus, frequencyEstimate, bitsPrecision, 1);\n }\n else {\n Message(\"The estimated frequency was 0, trying again.\");\n return 1;\n }\n }\n\n /// # Summary\n /// Estimates the frequency of a generator in the residue ring Z mod\n /// `modulus`.\n ///\n /// # Input\n /// ## generator\n /// The unsigned integer multiplicative order (period) of which is being\n /// estimated. Must be co-prime to `modulus`.\n /// ## modulus\n /// The modulus which defines the residue ring Z mod `modulus` in which the\n /// multiplicative order of `generator` is being estimated.\n /// ## bitsize\n /// Number of bits needed to represent the modulus.\n ///\n /// # Output\n /// The numerator k of dyadic fraction k/2^bitsPrecision approximating s/r.\n operation EstimateFrequency(generator : Int,modulus : Int, bitsize : Int)\n : Int {\n mutable frequencyEstimate = 0;\n let bitsPrecision = 2 * bitsize + 1;\n Message($\"Estimating frequency with bitsPrecision={bitsPrecision}.\");\n\n // Allocate qubits for the superposition of eigenstates of the oracle\n // that is used in period finding.\n use eigenstateRegister = Qubit[bitsize];\n\n // Initialize eigenstateRegister to 1, which is a superposition of the\n // eigenstates we are estimating the phases of.\n // We are interpreting the register as encoding an unsigned integer in\n // little-endian format.\n ApplyXorInPlace(1, eigenstateRegister);\n\n // Use phase estimation with a semiclassical Fourier transform to\n // estimate the frequency.\n use c = Qubit();\n for idx in bitsPrecision-1..-1..0 {\n H(c);\n Controlled ApplyOrderFindingOracle(\n [c],\n (generator, modulus, 1 <<< idx, eigenstateRegister));\n R1Frac(frequencyEstimate, bitsPrecision-1-idx, c);\n H(c);\n if M(c) == One {\n X(c); // Reset\n set frequencyEstimate += 1 <<< (bitsPrecision-1-idx);\n }\n }\n\n // Return all the qubits used for oracle's eigenstate back to 0 state\n // using ResetAll.\n ResetAll(eigenstateRegister);\n Message($\"Estimated frequency={frequencyEstimate}\");\n return frequencyEstimate;\n }\n\n /// # Summary\n /// Interprets `target` as encoding unsigned little-endian integer k and\n /// performs transformation |k⟩ ↦ |gᵖ⋅k mod N ⟩ where p is `power`, g is \n /// `generator` and N is `modulus`.\n ///\n /// # Input\n /// ## generator\n /// The unsigned integer multiplicative order (period) of which is being\n /// estimated. Must be co-prime to `modulus`.\n /// ## modulus\n /// The modulus which defines the residue ring Z mod `modulus` in which the\n /// multiplicative order of `generator` is being estimated.\n /// ## power\n /// Power of `generator` by which `target` is multiplied.\n /// ## target\n /// Register interpreted as little-endian which is multiplied by given power\n /// of the generator. The multiplication is performed modulo `modulus`.\n operation ApplyOrderFindingOracle(\n generator : Int,\n modulus : Int,\n power : Int,\n target : Qubit[])\n : Unit is Adj + Ctl {\n // Check that the parameters satisfy the requirements.\n Fact(\n GreatestCommonDivisorI(generator, modulus) == 1,\n \"`generator` and `modulus` must be co-prime\");\n\n // The oracle we use for order finding implements |x⟩ ↦ |x⋅a mod N⟩.\n // We also use `ExpModI` to compute a by which x must be multiplied.\n // Also note that we interpret target as unsigned integer in\n // little-endian fromat.\n ModularMultiplyByConstant(\n modulus,\n ExpModI(generator, power, modulus),\n target);\n }\n\n //\n // Arithmetic helper functions to implement order-finding oracle.\n //\n\n /// # Summary\n /// Returns the number of trailing zeroes of a number.\n ///\n /// ## Example\n /// let zeroes = NTrailingZeroes(21); // NTrailingZeroes(0b1101) = 0\n /// let zeroes = NTrailingZeroes(20); // NTrailingZeroes(0b1100) = 2\n function NTrailingZeroes(number : Int) : Int {\n Fact(number != 0, \"NTrailingZeroes: number cannot be 0.\");\n mutable nZeroes = 0;\n mutable copy = number;\n while (copy % 2 == 0) {\n set nZeroes += 1;\n set copy /= 2;\n }\n return nZeroes;\n }\n\n /// # Summary\n /// Performs modular in-place multiplication by a classical constant.\n ///\n /// # Description\n /// Given the classical constants `c` and `modulus`, and an input quantum\n /// register |𝑦⟩ in little-endian format, this operation computes \n /// `(c*x) % modulus` into |𝑦⟩.\n ///\n /// # Input\n /// ## modulus\n /// Modulus to use for modular multiplication\n /// ## c\n /// Constant by which to multiply |𝑦⟩\n /// ## y\n /// Quantum register of target\n operation ModularMultiplyByConstant(modulus : Int, c : Int, y : Qubit[])\n : Unit is Adj + Ctl {\n use qs = Qubit[Length(y)];\n for idx in IndexRange(y) {\n let shiftedC = (c <<< idx) % modulus;\n Controlled ModularAddConstant(\n [y[idx]],\n (modulus, shiftedC, qs));\n }\n for idx in IndexRange(y) {\n SWAP(y[idx], qs[idx]);\n }\n let invC = InverseModI(c, modulus);\n for idx in IndexRange(y) {\n let shiftedC = (invC <<< idx) % modulus;\n Controlled ModularAddConstant(\n [y[idx]],\n (modulus, modulus - shiftedC, qs));\n }\n }\n\n /// # Summary\n /// Performs modular in-place addition of a classical constant into a\n /// quantum register.\n ///\n /// # Description\n /// Given the classical constants `c` and `modulus`, and an input quantum\n /// register |𝑦⟩ in little-endian format, this operation computes\n /// `(x+c) % modulus` into |𝑦⟩.\n ///\n /// # Input\n /// ## modulus\n /// Modulus to use for modular addition\n /// ## c\n /// Constant to add to |𝑦⟩\n /// ## y\n /// Quantum register of target\n operation ModularAddConstant(modulus : Int, c : Int, y : Qubit[])\n : Unit is Adj + Ctl {\n body (...) {\n Controlled ModularAddConstant([], (modulus, c, y));\n }\n controlled (ctrls, ...) {\n // We apply a custom strategy to control this operation instead of\n // letting the compiler create the controlled variant for us in\n // which the `Controlled` functor would be distributed over each\n // operation in the body.\n //\n // Here we can use some scratch memory to save ensure that at most\n // one control qubit is used for costly operations such as\n // `AddConstant` and `CompareGreaterThenOrEqualConstant`.\n if Length(ctrls) >= 2 {\n use control = Qubit();\n within {\n Controlled X(ctrls, control);\n } apply {\n Controlled ModularAddConstant(\n [control],\n (modulus, c, y));\n }\n } else {\n use carry = Qubit();\n Controlled AddConstant(\n ctrls, (c, y + [carry]));\n Controlled Adjoint AddConstant(\n ctrls, (modulus, y + [carry]));\n Controlled AddConstant(\n [carry], (modulus, y));\n Controlled CompareGreaterThanOrEqualConstant(\n ctrls, (c, y, carry));\n }\n }\n }\n\n /// # Summary\n /// Performs in-place addition of a constant into a quantum register.\n ///\n /// # Description\n /// Given a non-empty quantum register |𝑦⟩ of length 𝑛+1 and a positive\n // constant 𝑐 < 2ⁿ, computes |𝑦 + c⟩ into |𝑦⟩.\n ///\n /// # Input\n /// ## c\n /// Constant number to add to |𝑦⟩.\n /// ## y\n /// Quantum register of second summand and target; must not be empty.\n operation AddConstant(c : Int, y : Qubit[]): Unit is Adj + Ctl {\n // We are using this version instead of the library version that is\n // based on Fourier angles to show an advantage of sparse simulation\n // in this sample.\n let n = Length(y);\n Fact(n > 0, \"Bit width must be at least 1\");\n Fact(c >= 0, \"constant must not be negative\");\n Fact(c < 2^n, \"constant must be smaller than {2^n)}\");\n if c != 0 {\n // If c has j trailing zeroes than the j least significant bits of y\n // won't be affected by the addition and can therefore be ignored by\n // applying the addition only to the other qubits and shifting c\n // accordingly.\n let j = NTrailingZeroes(c);\n use x = Qubit[n - j];\n within {\n ApplyXorInPlace(c >>> j, x);\n } apply {\n AddI(x, y[j...]);\n }\n }\n }\n\n /// # Summary\n /// Performs greater-than-or-equals comparison to a constant.\n ///\n /// # Description\n /// Toggles output qubit `target` if and only if input register `x` is\n /// greater than or equal to `c`.\n ///\n /// # Input\n /// ## c\n /// Constant value for comparison.\n /// ## x\n /// Quantum register to compare against.\n /// ## target\n /// Target qubit for comparison result.\n ///\n /// # Reference\n /// This construction is described in [Lemma 3, arXiv:2201.10200]\n operation CompareGreaterThanOrEqualConstant(\n c : Int,\n x : Qubit[],\n target : Qubit)\n : Unit is Adj+Ctl {\n let bitWidth = Length(x);\n if c == 0 {\n X(target);\n } elif c >= (2^bitWidth) {\n // do nothing\n } elif c == (2^(bitWidth - 1)) {\n CNOT(Tail(x), target);\n } else {\n // normalize constant\n let l = NTrailingZeroes(c);\n let cNormalized = c >>> l;\n let xNormalized = x[l...];\n let bitWidthNormalized = Length(xNormalized);\n use qs = Qubit[bitWidthNormalized - 1];\n let cs1 = [Head(xNormalized)] + Most(qs);\n Fact(Length(cs1) == Length(qs),\n \"Arrays should be of the same length.\");\n within {\n for i in 0..Length(cs1)-1 {\n let op =\n cNormalized &&& (1 <<< (i+1)) != 0 ?\n ApplyAnd | ApplyOr;\n op(cs1[i], xNormalized[i+1], qs[i]);\n }\n } apply {\n CNOT(Tail(qs), target);\n }\n }\n }\n\n /// # Summary\n /// Inverts a given target qubit if and only if both control qubits are in\n /// the 1 state, using measurement to perform the adjoint operation.\n ///\n /// # Description\n /// Inverts `target` if and only if both controls are 1, but assumes that\n /// `target` is in state 0. The operation has T-count 4, T-depth 2 and\n /// requires no helper qubit, and may therefore be preferable to a CCNOT\n /// operation, if `target` is known to be 0.\n /// The adjoint of this operation is measurement based and requires no T\n /// gates.\n /// Although the Toffoli gate (CCNOT) will perform faster in in simulations,\n /// this version has lower T gate requirements.\n ///\n /// # Input\n /// ## control1\n /// First control qubit\n /// ## control2\n /// Second control qubit\n /// ## target\n /// Target auxiliary qubit; must be in state 0\n ///\n /// # References\n /// - Cody Jones: \"Novel constructions for the fault-tolerant\n /// Toffoli gate\",\n /// Phys. Rev. A 87, 022328, 2013\n /// [arXiv:1212.5069](https://arxiv.org/abs/1212.5069)\n /// doi:10.1103/PhysRevA.87.022328\n /// - Craig Gidney: \"Halving the cost of quantum addition\",\n /// Quantum 2, page 74, 2018\n /// [arXiv:1709.06648](https://arxiv.org/abs/1709.06648)\n /// doi:10.1103/PhysRevA.85.044302\n /// - Mathias Soeken: \"Quantum Oracle Circuits and the Christmas\n /// Tree Pattern\",\n /// [Blog article from December 19, 2019](https://msoeken.github.io/blog_qac.html)\n /// (note: explains the multiple controlled construction)\n operation ApplyAnd(control1 : Qubit, control2 : Qubit, target : Qubit)\n : Unit is Adj {\n body (...) {\n H(target);\n T(target);\n CNOT(control1, target);\n CNOT(control2, target);\n within {\n CNOT(target, control1);\n CNOT(target, control2);\n }\n apply {\n Adjoint T(control1);\n Adjoint T(control2);\n T(target);\n }\n H(target);\n S(target);\n }\n adjoint (...) {\n H(target);\n if (M(target) == One) {\n X(target);\n CZ(control1, control2);\n }\n }\n }\n\n /// # Summary\n /// Applies X to the target if any of the controls are 1.\n operation ApplyOr(control1 : Qubit, control2 : Qubit, target : Qubit)\n : Unit is Adj {\n within {\n ApplyToEachA(X, [control1, control2]);\n } apply {\n ApplyAnd(control1, control2, target);\n X(target);\n }\n }\n}\n"
|
|
60
|
+
"code": "/// # Sample\n/// Shor's algorithm\n///\n/// # Description\n/// Shor's algorithm is a quantum algorithm for finding the prime factors of an\n/// integer.\n///\n/// This Q# program implements Shor's algorithm.\nnamespace Sample {\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Random;\n open Microsoft.Quantum.Math;\n open Microsoft.Quantum.Arithmetic;\n open Microsoft.Quantum.Arrays;\n\n @EntryPoint()\n operation Main() : (Int, Int) {\n let n = 143; // 11*13;\n // You can try these other examples for a lengthier computation.\n // let n = 16837; // = 113*149\n // let n = 22499; // = 149*151\n\n // Use Shor's algorithm to factor a semiprime integer.\n let (a, b) = FactorSemiprimeInteger(n);\n Message($\"Found factorization {n} = {a} * {b} \");\n return (a, b);\n }\n\n /// # Summary\n /// Uses Shor's algorithm to factor an input number.\n ///\n /// # Input\n /// ## number\n /// A semiprime integer to be factored.\n ///\n /// # Output\n /// Pair of numbers p > 1 and q > 1 such that p⋅q = `number`\n operation FactorSemiprimeInteger(number : Int) : (Int, Int) {\n // First check the most trivial case (the provided number is even).\n if number % 2 == 0 {\n Message(\"An even number has been given; 2 is a factor.\");\n return (number / 2, 2);\n }\n // These mutables will keep track of whether we found the factors, and\n // if so, what they are. The default value for the factors is (1,1).\n mutable foundFactors = false;\n mutable factors = (1, 1);\n mutable attempt = 1;\n repeat {\n Message($\"*** Factorizing {number}, attempt {attempt}.\");\n // Try to guess a number co-prime to `number` by getting a random\n // integer in the interval [1, number-1]\n let generator = DrawRandomInt(1, number - 1);\n\n // Check if the random integer is indeed co-prime.\n // If true use Quantum algorithm for Period finding.\n if GreatestCommonDivisorI(generator, number) == 1 {\n Message($\"Estimating period of {generator}.\");\n\n // Call Quantum Period finding algorithm for\n // `generator` mod `number`.\n let period = EstimatePeriod(generator, number);\n\n // Set the flag and factors values if the continued\n // fractions classical algorithm succeeds.\n set (foundFactors, factors) =\n MaybeFactorsFromPeriod(number, generator, period);\n }\n // In this case, we guessed a divisor by accident.\n else {\n // Find divisor.\n let gcd = GreatestCommonDivisorI(number, generator);\n Message($\"We have guessed a divisor {gcd} by accident. \" +\n \"No quantum computation was done.\");\n\n // Set the flag `foundFactors` to true, indicating that we\n // succeeded in finding factors.\n set foundFactors = true;\n set factors = (gcd, number / gcd);\n }\n set attempt = attempt+1;\n if (attempt > 100) {\n fail \"Failed to find factors: too many attempts!\";\n }\n }\n until foundFactors\n fixup {\n Message(\"The estimated period did not yield a valid factor. \" +\n \"Trying again.\");\n }\n\n // Return the factorization\n return factors;\n }\n\n /// # Summary\n /// Tries to find the factors of `modulus` given a `period` and `generator`.\n ///\n /// # Input\n /// ## modulus\n /// The modulus which defines the residue ring Z mod `modulus` in which the\n /// multiplicative order of `generator` is being estimated.\n /// ## generator\n /// The unsigned integer multiplicative order (period) of which is being\n /// estimated. Must be co-prime to `modulus`.\n /// ## period\n /// The estimated period (multiplicative order) of the generator mod\n /// `modulus`.\n ///\n /// # Output\n /// A tuple of a flag indicating whether factors were found successfully,\n /// and a pair of integers representing the factors that were found.\n /// Note that the second output is only meaningful when the first output is\n /// `true`.\n function MaybeFactorsFromPeriod(\n modulus : Int,\n generator : Int,\n period : Int)\n : (Bool, (Int, Int)) {\n\n // Period finding reduces to factoring only if period is even\n if period % 2 == 0 {\n // Compute `generator` ^ `period/2` mod `number`.\n let halfPower = ExpModI(generator, period / 2, modulus);\n\n // If we are unlucky, halfPower is just -1 mod N, which is a trivial\n // case and not useful for factoring.\n if halfPower != modulus - 1 {\n // When the halfPower is not -1 mod N, halfPower-1 or\n // halfPower+1 share non-trivial divisor with `number`. Find it.\n let factor = MaxI(\n GreatestCommonDivisorI(halfPower - 1, modulus),\n GreatestCommonDivisorI(halfPower + 1, modulus)\n );\n\n // Add a flag that we found the factors, and return computed\n // non-trivial factors.\n Message($\"Found factor={factor}\");\n return (true, (factor, modulus / factor));\n } else {\n // Return a flag indicating we hit a trivial case and didn't get\n // any factors.\n Message($\"Found trivial factors.\");\n return (false, (1, 1));\n }\n } else {\n // When period is odd we have to pick another generator to estimate\n // period of and start over.\n Message($\"Estimated period {period} was odd, trying again.\");\n return (false, (1, 1));\n }\n }\n\n /// # Summary\n /// Find the period of a number from an input frequency.\n ///\n /// # Input\n /// ## modulus\n /// The modulus which defines the residue ring Z mod `modulus` in which the\n /// multiplicative order of `generator` is being estimated.\n /// ## frequencyEstimate\n /// The frequency that we want to convert to a period.\n /// ## bitsPrecision\n /// Number of bits of precision with which we need to estimate s/r to\n /// recover period r using continued fractions algorithm.\n /// ## currentDivisor\n /// The divisor of the generator period found so far.\n ///\n /// # Output\n /// The period as calculated from the estimated frequency via the continued\n /// fractions algorithm.\n function PeriodFromFrequency(\n modulus : Int,\n frequencyEstimate : Int,\n bitsPrecision : Int,\n currentDivisor : Int)\n : Int {\n // Now we use the ContinuedFractionConvergentI function to recover s/r\n // from dyadic fraction k/2^bitsPrecision.\n let (numerator, period) = ContinuedFractionConvergentI(\n (frequencyEstimate, 2 ^ bitsPrecision),\n modulus);\n\n // ContinuedFractionConvergentI does not guarantee the signs of the\n // numerator and denominator. Here we make sure that both are positive\n // using AbsI.\n let (numeratorAbs, periodAbs) = (AbsI(numerator), AbsI(period));\n\n // Compute and return the newly found divisor.\n let period =\n (periodAbs * currentDivisor) /\n GreatestCommonDivisorI(currentDivisor, periodAbs);\n Message($\"Found period={period}\");\n return period;\n }\n\n /// # Summary\n /// Finds a multiplicative order of the generator in the residue ring Z mod\n /// `modulus`.\n ///\n /// # Input\n /// ## generator\n /// The unsigned integer multiplicative order (period) of which is being\n /// estimated. Must be co-prime to `modulus`.\n /// ## modulus\n /// The modulus which defines the residue ring Z mod `modulus` in which the\n /// multiplicative order of `generator` is being estimated.\n ///\n /// # Output\n /// The period (multiplicative order) of the generator mod `modulus`\n operation EstimatePeriod(generator : Int, modulus : Int) : Int {\n // Here we check that the inputs to the EstimatePeriod operation are\n // valid.\n Fact(\n GreatestCommonDivisorI(generator, modulus) == 1,\n \"`generator` and `modulus` must be co-prime\");\n\n // Number of bits in the modulus with respect to which we are estimating\n // the period.\n let bitsize = BitSizeI(modulus);\n\n // The EstimatePeriod operation estimates the period r by finding an\n // approximation k/2^(bits precision) to a fraction s/r, where s is some\n // integer. Note that if s and r have common divisors we will end up\n // recovering a divisor of r and not r itself.\n\n // Number of bits of precision with which we need to estimate s/r to\n // recover period r, using continued fractions algorithm.\n let bitsPrecision = 2 * bitsize + 1;\n\n // Current estimate for the frequency of the form s/r.\n let frequencyEstimate = EstimateFrequency(generator, modulus, bitsize);\n if frequencyEstimate != 0 {\n return PeriodFromFrequency(\n modulus, frequencyEstimate, bitsPrecision, 1);\n }\n else {\n Message(\"The estimated frequency was 0, trying again.\");\n return 1;\n }\n }\n\n /// # Summary\n /// Estimates the frequency of a generator in the residue ring Z mod\n /// `modulus`.\n ///\n /// # Input\n /// ## generator\n /// The unsigned integer multiplicative order (period) of which is being\n /// estimated. Must be co-prime to `modulus`.\n /// ## modulus\n /// The modulus which defines the residue ring Z mod `modulus` in which the\n /// multiplicative order of `generator` is being estimated.\n /// ## bitsize\n /// Number of bits needed to represent the modulus.\n ///\n /// # Output\n /// The numerator k of dyadic fraction k/2^bitsPrecision approximating s/r.\n operation EstimateFrequency(generator : Int,modulus : Int, bitsize : Int)\n : Int {\n mutable frequencyEstimate = 0;\n let bitsPrecision = 2 * bitsize + 1;\n Message($\"Estimating frequency with bitsPrecision={bitsPrecision}.\");\n\n // Allocate qubits for the superposition of eigenstates of the oracle\n // that is used in period finding.\n use eigenstateRegister = Qubit[bitsize];\n\n // Initialize eigenstateRegister to 1, which is a superposition of the\n // eigenstates we are estimating the phases of.\n // We are interpreting the register as encoding an unsigned integer in\n // little-endian format.\n ApplyXorInPlace(1, eigenstateRegister);\n\n // Use phase estimation with a semiclassical Fourier transform to\n // estimate the frequency.\n use c = Qubit();\n for idx in bitsPrecision-1..-1..0 {\n H(c);\n Controlled ApplyOrderFindingOracle(\n [c],\n (generator, modulus, 1 <<< idx, eigenstateRegister));\n R1Frac(frequencyEstimate, bitsPrecision-1-idx, c);\n H(c);\n if M(c) == One {\n X(c); // Reset\n set frequencyEstimate += 1 <<< (bitsPrecision-1-idx);\n }\n }\n\n // Return all the qubits used for oracle's eigenstate back to 0 state\n // using ResetAll.\n ResetAll(eigenstateRegister);\n Message($\"Estimated frequency={frequencyEstimate}\");\n return frequencyEstimate;\n }\n\n /// # Summary\n /// Interprets `target` as encoding unsigned little-endian integer k and\n /// performs transformation |k⟩ ↦ |gᵖ⋅k mod N ⟩ where p is `power`, g is\n /// `generator` and N is `modulus`.\n ///\n /// # Input\n /// ## generator\n /// The unsigned integer multiplicative order (period) of which is being\n /// estimated. Must be co-prime to `modulus`.\n /// ## modulus\n /// The modulus which defines the residue ring Z mod `modulus` in which the\n /// multiplicative order of `generator` is being estimated.\n /// ## power\n /// Power of `generator` by which `target` is multiplied.\n /// ## target\n /// Register interpreted as little-endian which is multiplied by given power\n /// of the generator. The multiplication is performed modulo `modulus`.\n operation ApplyOrderFindingOracle(\n generator : Int,\n modulus : Int,\n power : Int,\n target : Qubit[])\n : Unit is Adj + Ctl {\n // Check that the parameters satisfy the requirements.\n Fact(\n GreatestCommonDivisorI(generator, modulus) == 1,\n \"`generator` and `modulus` must be co-prime\");\n\n // The oracle we use for order finding implements |x⟩ ↦ |x⋅a mod N⟩.\n // We also use `ExpModI` to compute a by which x must be multiplied.\n // Also note that we interpret target as unsigned integer in\n // little-endian fromat.\n ModularMultiplyByConstant(\n modulus,\n ExpModI(generator, power, modulus),\n target);\n }\n\n //\n // Arithmetic helper functions to implement order-finding oracle.\n //\n\n /// # Summary\n /// Returns the number of trailing zeroes of a number.\n ///\n /// ## Example\n /// let zeroes = NTrailingZeroes(21); // NTrailingZeroes(0b1101) = 0\n /// let zeroes = NTrailingZeroes(20); // NTrailingZeroes(0b1100) = 2\n function NTrailingZeroes(number : Int) : Int {\n Fact(number != 0, \"NTrailingZeroes: number cannot be 0.\");\n mutable nZeroes = 0;\n mutable copy = number;\n while (copy % 2 == 0) {\n set nZeroes += 1;\n set copy /= 2;\n }\n return nZeroes;\n }\n\n /// # Summary\n /// Performs modular in-place multiplication by a classical constant.\n ///\n /// # Description\n /// Given the classical constants `c` and `modulus`, and an input quantum\n /// register |𝑦⟩ in little-endian format, this operation computes\n /// `(c*x) % modulus` into |𝑦⟩.\n ///\n /// # Input\n /// ## modulus\n /// Modulus to use for modular multiplication\n /// ## c\n /// Constant by which to multiply |𝑦⟩\n /// ## y\n /// Quantum register of target\n operation ModularMultiplyByConstant(modulus : Int, c : Int, y : Qubit[])\n : Unit is Adj + Ctl {\n use qs = Qubit[Length(y)];\n for idx in IndexRange(y) {\n let shiftedC = (c <<< idx) % modulus;\n Controlled ModularAddConstant(\n [y[idx]],\n (modulus, shiftedC, qs));\n }\n for idx in IndexRange(y) {\n SWAP(y[idx], qs[idx]);\n }\n let invC = InverseModI(c, modulus);\n for idx in IndexRange(y) {\n let shiftedC = (invC <<< idx) % modulus;\n Controlled ModularAddConstant(\n [y[idx]],\n (modulus, modulus - shiftedC, qs));\n }\n }\n\n /// # Summary\n /// Performs modular in-place addition of a classical constant into a\n /// quantum register.\n ///\n /// # Description\n /// Given the classical constants `c` and `modulus`, and an input quantum\n /// register |𝑦⟩ in little-endian format, this operation computes\n /// `(x+c) % modulus` into |𝑦⟩.\n ///\n /// # Input\n /// ## modulus\n /// Modulus to use for modular addition\n /// ## c\n /// Constant to add to |𝑦⟩\n /// ## y\n /// Quantum register of target\n operation ModularAddConstant(modulus : Int, c : Int, y : Qubit[])\n : Unit is Adj + Ctl {\n body (...) {\n Controlled ModularAddConstant([], (modulus, c, y));\n }\n controlled (ctrls, ...) {\n // We apply a custom strategy to control this operation instead of\n // letting the compiler create the controlled variant for us in\n // which the `Controlled` functor would be distributed over each\n // operation in the body.\n //\n // Here we can use some scratch memory to save ensure that at most\n // one control qubit is used for costly operations such as\n // `AddConstant` and `CompareGreaterThenOrEqualConstant`.\n if Length(ctrls) >= 2 {\n use control = Qubit();\n within {\n Controlled X(ctrls, control);\n } apply {\n Controlled ModularAddConstant(\n [control],\n (modulus, c, y));\n }\n } else {\n use carry = Qubit();\n Controlled AddConstant(\n ctrls, (c, y + [carry]));\n Controlled Adjoint AddConstant(\n ctrls, (modulus, y + [carry]));\n Controlled AddConstant(\n [carry], (modulus, y));\n Controlled CompareGreaterThanOrEqualConstant(\n ctrls, (c, y, carry));\n }\n }\n }\n\n /// # Summary\n /// Performs in-place addition of a constant into a quantum register.\n ///\n /// # Description\n /// Given a non-empty quantum register |𝑦⟩ of length 𝑛+1 and a positive\n // constant 𝑐 < 2ⁿ, computes |𝑦 + c⟩ into |𝑦⟩.\n ///\n /// # Input\n /// ## c\n /// Constant number to add to |𝑦⟩.\n /// ## y\n /// Quantum register of second summand and target; must not be empty.\n operation AddConstant(c : Int, y : Qubit[]) : Unit is Adj + Ctl {\n // We are using this version instead of the library version that is\n // based on Fourier angles to show an advantage of sparse simulation\n // in this sample.\n let n = Length(y);\n Fact(n > 0, \"Bit width must be at least 1\");\n Fact(c >= 0, \"constant must not be negative\");\n Fact(c < 2^n, \"constant must be smaller than {2^n)}\");\n if c != 0 {\n // If c has j trailing zeroes than the j least significant bits of y\n // won't be affected by the addition and can therefore be ignored by\n // applying the addition only to the other qubits and shifting c\n // accordingly.\n let j = NTrailingZeroes(c);\n use x = Qubit[n - j];\n within {\n ApplyXorInPlace(c >>> j, x);\n } apply {\n AddI(x, y[j...]);\n }\n }\n }\n\n /// # Summary\n /// Performs greater-than-or-equals comparison to a constant.\n ///\n /// # Description\n /// Toggles output qubit `target` if and only if input register `x` is\n /// greater than or equal to `c`.\n ///\n /// # Input\n /// ## c\n /// Constant value for comparison.\n /// ## x\n /// Quantum register to compare against.\n /// ## target\n /// Target qubit for comparison result.\n ///\n /// # Reference\n /// This construction is described in [Lemma 3, arXiv:2201.10200]\n operation CompareGreaterThanOrEqualConstant(\n c : Int,\n x : Qubit[],\n target : Qubit)\n : Unit is Adj+Ctl {\n let bitWidth = Length(x);\n if c == 0 {\n X(target);\n } elif c >= (2^bitWidth) {\n // do nothing\n } elif c == (2^(bitWidth - 1)) {\n CNOT(Tail(x), target);\n } else {\n // normalize constant\n let l = NTrailingZeroes(c);\n let cNormalized = c >>> l;\n let xNormalized = x[l...];\n let bitWidthNormalized = Length(xNormalized);\n use qs = Qubit[bitWidthNormalized - 1];\n let cs1 = [Head(xNormalized)] + Most(qs);\n Fact(Length(cs1) == Length(qs),\n \"Arrays should be of the same length.\");\n within {\n for i in 0..Length(cs1)-1 {\n let op =\n cNormalized &&& (1 <<< (i+1)) != 0 ?\n ApplyAnd | ApplyOr;\n op(cs1[i], xNormalized[i+1], qs[i]);\n }\n } apply {\n CNOT(Tail(qs), target);\n }\n }\n }\n\n /// # Summary\n /// Inverts a given target qubit if and only if both control qubits are in\n /// the 1 state, using measurement to perform the adjoint operation.\n ///\n /// # Description\n /// Inverts `target` if and only if both controls are 1, but assumes that\n /// `target` is in state 0. The operation has T-count 4, T-depth 2 and\n /// requires no helper qubit, and may therefore be preferable to a CCNOT\n /// operation, if `target` is known to be 0.\n /// The adjoint of this operation is measurement based and requires no T\n /// gates.\n /// Although the Toffoli gate (CCNOT) will perform faster in in simulations,\n /// this version has lower T gate requirements.\n ///\n /// # Input\n /// ## control1\n /// First control qubit\n /// ## control2\n /// Second control qubit\n /// ## target\n /// Target auxiliary qubit; must be in state 0\n ///\n /// # References\n /// - Cody Jones: \"Novel constructions for the fault-tolerant\n /// Toffoli gate\",\n /// Phys. Rev. A 87, 022328, 2013\n /// [arXiv:1212.5069](https://arxiv.org/abs/1212.5069)\n /// doi:10.1103/PhysRevA.87.022328\n /// - Craig Gidney: \"Halving the cost of quantum addition\",\n /// Quantum 2, page 74, 2018\n /// [arXiv:1709.06648](https://arxiv.org/abs/1709.06648)\n /// doi:10.1103/PhysRevA.85.044302\n /// - Mathias Soeken: \"Quantum Oracle Circuits and the Christmas\n /// Tree Pattern\",\n /// [Blog article from December 19, 2019](https://msoeken.github.io/blog_qac.html)\n /// (note: explains the multiple controlled construction)\n operation ApplyAnd(control1 : Qubit, control2 : Qubit, target : Qubit)\n : Unit is Adj {\n body (...) {\n H(target);\n T(target);\n CNOT(control1, target);\n CNOT(control2, target);\n within {\n CNOT(target, control1);\n CNOT(target, control2);\n }\n apply {\n Adjoint T(control1);\n Adjoint T(control2);\n T(target);\n }\n H(target);\n S(target);\n }\n adjoint (...) {\n H(target);\n if (M(target) == One) {\n X(target);\n CZ(control1, control2);\n }\n }\n }\n\n /// # Summary\n /// Applies X to the target if any of the controls are 1.\n operation ApplyOr(control1 : Qubit, control2 : Qubit, target : Qubit)\n : Unit is Adj {\n within {\n ApplyToEachA(X, [control1, control2]);\n } apply {\n ApplyAnd(control1, control2, target);\n X(target);\n }\n }\n}\n"
|
|
61
61
|
}
|
|
62
62
|
];
|
|
Binary file
|
package/lib/web/qsc_wasm_bg.wasm
CHANGED
|
Binary file
|