Replace rarely used operation wrappers with lambda expressions (#848)

This commit is contained in:
Mariia Mykhailova 2022-10-28 01:29:43 -07:00 коммит произвёл GitHub
Родитель 0b5628f58b
Коммит b325de7f61
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 37 добавлений и 88 удалений

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

@ -44,17 +44,17 @@ namespace Quantum.Kata.DistinguishUnitaries {
// check the constraint on the number of allowed calls to the unitary
// note that a unitary can be implemented as Controlled on |1⟩, so we need to count variants as well
if (maxCalls > 0) {
if maxCalls > 0 {
let actualCalls = GetOracleCallsCount(unitaries[actualIndex]) +
GetOracleCallsCount(Adjoint unitaries[actualIndex]) +
GetOracleCallsCount(Controlled unitaries[actualIndex]);
if (actualCalls > maxCalls) {
if actualCalls > maxCalls {
fail $"You are allowed to do at most {maxCalls} calls, and you did {actualCalls}";
}
}
if (returnedIndex != actualIndex) {
if (returnedIndex < 0 or returnedIndex >= nUnitaries) {
if returnedIndex != actualIndex {
if returnedIndex < 0 or returnedIndex >= nUnitaries {
set unknownClassifications w/= actualIndex <- unknownClassifications[actualIndex] + 1;
} else {
let index = actualIndex * nUnitaries + returnedIndex;
@ -67,12 +67,12 @@ namespace Quantum.Kata.DistinguishUnitaries {
for i in 0 .. nUnitaries - 1 {
for j in 0 .. nUnitaries - 1 {
let misclassifiedIasJ = wrongClassifications[(i * nUnitaries) + j];
if (misclassifiedIasJ != 0) {
if misclassifiedIasJ != 0 {
set totalMisclassifications += misclassifiedIasJ;
Message($"Misclassified {i} as {j} in {misclassifiedIasJ} test runs.");
}
}
if (unknownClassifications[i] != 0) {
if unknownClassifications[i] != 0 {
set totalMisclassifications += unknownClassifications[i];
Message($"Misclassified {i} as unknown unitary in {unknownClassifications[i]} test runs.");
}
@ -83,13 +83,9 @@ namespace Quantum.Kata.DistinguishUnitaries {
// ------------------------------------------------------
// A pair of helper wrappers used to differentiate the unitary we pass as an argument from gates used normally
internal operation SingleQubitGateWrapper<'UInput> (unitary : ('UInput => Unit is Adj+Ctl), input : 'UInput) : Unit is Adj+Ctl {
unitary(input);
}
internal function SingleQubitGateAsUnitary<'UInput> (unitary : ('UInput => Unit is Adj+Ctl)) : ('UInput => Unit is Adj+Ctl) {
return SingleQubitGateWrapper(unitary, _);
// A helper operation used to differentiate the unitary we pass as an argument from gates used normally
internal function SingleQubitGateAsUnitary<'UInput> (unitary : 'UInput => Unit is Adj+Ctl) : 'UInput => Unit is Adj+Ctl {
return input => unitary(input);
}
@Test("Microsoft.Quantum.Katas.CounterSimulator")
@ -182,50 +178,26 @@ namespace Quantum.Kata.DistinguishUnitaries {
// Part II. Multi-Qubit Gates
//////////////////////////////////////////////////////////////////
operation IXWrapper (qs : Qubit[]) : Unit is Adj+Ctl {
Fact(Length(qs) == 2, "This unitary can only be applied to arrays of length 2.");
X(qs[1]);
}
operation CNOTWrapper (qs : Qubit[]) : Unit is Adj+Ctl {
Fact(Length(qs) == 2, "This unitary can only be applied to arrays of length 2.");
CNOT(qs[0], qs[1]);
}
@Test("Microsoft.Quantum.Katas.CounterSimulator")
operation T201_DistinguishIXfromCNOT () : Unit {
DistinguishUnitaries_Framework([IXWrapper, CNOTWrapper], DistinguishIXfromCNOT, 1);
DistinguishUnitaries_Framework([qs => X(qs[1]), qs => CNOT(qs[0], qs[1])], DistinguishIXfromCNOT, 1);
}
// ------------------------------------------------------
operation ReverseCNOTWrapper (qs : Qubit[]) : Unit is Adj+Ctl {
Fact(Length(qs) == 2, "This unitary can only be applied to arrays of length 2.");
CNOT(qs[1], qs[0]);
}
@Test("Microsoft.Quantum.Katas.CounterSimulator")
operation T202_CNOTDirection () : Unit {
DistinguishUnitaries_Framework([CNOTWrapper, ReverseCNOTWrapper], CNOTDirection, 1);
DistinguishUnitaries_Framework([qs => CNOT(qs[0], qs[1]), qs => CNOT(qs[1], qs[0])], CNOTDirection, 1);
}
// ------------------------------------------------------
operation SWAPWrapper (qs : Qubit[]) : Unit is Adj+Ctl {
Fact(Length(qs) == 2, "This unitary can only be applied to arrays of length 2.");
SWAP(qs[1], qs[0]);
}
@Test("Microsoft.Quantum.Katas.CounterSimulator")
operation T203_DistinguishCNOTfromSWAP () : Unit {
DistinguishUnitaries_Framework([CNOTWrapper, SWAPWrapper], DistinguishCNOTfromSWAP, 1);
DistinguishUnitaries_Framework([qs => CNOT(qs[0], qs[1]), qs => SWAP(qs[0], qs[1])], DistinguishCNOTfromSWAP, 1);
}
// ------------------------------------------------------
operation IdentityWrapper (qs : Qubit[]) : Unit is Adj+Ctl {
Fact(Length(qs) == 2, "This unitary can only be applied to arrays of length 2.");
}
@Test("Microsoft.Quantum.Katas.CounterSimulator")
operation T204_DistinguishTwoQubitUnitaries () : Unit {
DistinguishUnitaries_Framework([IdentityWrapper, CNOTWrapper, ReverseCNOTWrapper, SWAPWrapper], DistinguishTwoQubitUnitaries, 2);
DistinguishUnitaries_Framework([NoOp, qs => CNOT(qs[0], qs[1]), qs => CNOT(qs[1], qs[0]), qs => SWAP(qs[0], qs[1])], DistinguishTwoQubitUnitaries, 2);
}
}

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

@ -218,11 +218,6 @@ namespace Quantum.Kata.GraphColoring {
// ------------------------------------------------------
operation QubitArrayWrapperOperation (op : ((Qubit[], Qubit) => Unit is Adj), qs : Qubit[]) : Unit is Adj {
op(Most(qs), Tail(qs));
}
operation AssertOracleRecognizesColoring (
V : Int,
edges : (Int, Int)[],
@ -526,13 +521,9 @@ namespace Quantum.Kata.GraphColoring {
}
function BoolAsInt (a : Bool) : Int {
return a ? 1 | 0;
}
function IsVertexColoringTriangleFree_Wrapper (V : Int, edges: (Int, Int)[], colors: Int) : Bool {
let colorBools = IntAsBoolArray(colors, Length(edges));
let colorBits = Mapped(BoolAsInt, colorBools);
let colorBits = Mapped(a -> a ? 1 | 0, colorBools);
return IsVertexColoringTriangleFree_Reference(V, edges, colorBits);
}

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

@ -139,13 +139,10 @@ namespace Quantum.Kata.MagicSquareGame {
return pairs;
}
operation ControlledWrapper (op : (Qubit[] => Unit is Adj+Ctl), qs : Qubit[]) : Unit is Adj+Ctl {
Controlled op([Head(qs)], Rest(qs));
}
operation AssertOperationsEqualWithPhase (N : Int, op1 : (Qubit[] => Unit is Adj+Ctl), op2 : (Qubit[] => Unit is Adj+Ctl)) : Unit {
// To check that the operations don't introduce a phase, compare their controlled versions
AssertOperationsEqualReferenced(N + 1, ControlledWrapper(op1, _), ControlledWrapper(op2, _));
AssertOperationsEqualReferenced(N + 1,
qs => Controlled op1([Head(qs)], Rest(qs)),
qs => Controlled op2([Head(qs)], Rest(qs)));
}
// Helper function to checks that each pair of operations in the array commutes (i.e., AB = BA)

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

@ -70,16 +70,13 @@ namespace Quantum.Kata.DeutschJozsaAlgorithm {
// Part II. Single-bit problem
//////////////////////////////////////////////////////////////////
// We need to compare phase oracles as their controlled versions to account for the global phase.
operation ControlledWrapper (qs : Qubit[], phaseOracle : (Qubit => Unit is Adj + Ctl)) : Unit is Adj + Ctl {
Controlled phaseOracle([qs[0]], qs[1]);
}
// Exercise 3.
@Test("QuantumSimulator")
operation T3_PhaseOracle_OneMinusX () : Unit {
AssertOperationsEqualReferenced(2, ControlledWrapper(_, PhaseOracle_OneMinusX),
ControlledWrapper(_, PhaseOracle_OneMinusX_Reference));
// We need to compare phase oracles as their controlled versions to account for the global phase.
AssertOperationsEqualReferenced(2,
qs => Controlled PhaseOracle_OneMinusX([qs[0]], qs[1]),
qs => Controlled PhaseOracle_OneMinusX_Reference([qs[0]], qs[1]));
}

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

@ -10,7 +10,7 @@
"Building upon those ideas, this tutorial will introduce you to measurements done on multi-qubit systems, and how to implement such measurements in Q#. \n",
"This will include measuring a single qubit in a multi-qubit system, as well as measuring multiple qubits simultaneously. \n",
"\n",
"We recommend to go through the [tutorial that introduces single qubit system measurements](../SingleQubitSystemMeasurements/SingleQubitSystemMeasurements.ipynb) before starting this one.\n",
"We recommend to go through the [tutorial that introduces single-qubit system measurements](../SingleQubitSystemMeasurements/SingleQubitSystemMeasurements.ipynb) before starting this one.\n",
"$\\renewcommand{\\ket}[1]{\\left\\lvert#1\\right\\rangle}$\n",
"$\\renewcommand{\\bra}[1]{\\left\\langle#1\\right\\rvert}$"
]
@ -61,7 +61,7 @@
"</table>\n",
" \n",
" \n",
"> Similar to measurements in single qubit systems, the assumption of normalization of the original wave function is required in order to ensure that the sum of all the outcome probabilities is 1."
"> Similar to measurements in single-qubit systems, the assumption of normalization of the original wave function is required in order to ensure that the sum of all the outcome probabilities is 1."
]
},
{
@ -250,7 +250,7 @@
"where $\\mathbb{1}_{n-m}$ is the identity operator over the remaining $(n-m)$ qubits. \n",
"> The symbol $\\otimes$ represents the tensor product or the Kronecker product of two matrices. It is different from the usual matrix multiplication (see the [Linear Algebra tutorial](../LinearAlgebra/LinearAlgebra.ipynb#Tensor-Product) for a refresher). In the current context, $|b_i\\rangle \\langle b_i| \\otimes \\mathbb{1}_{n-m}$ simply means that the operator $|b_i\\rangle \\langle b_i|$ acts only on the $m$ qubits being measured, while the effect of $P_i$ on the remaining qubits is $\\mathbb{1}_{n-m}$, i.e., the identity operator. \n",
"\n",
"Analogous to the case for measurements for single qubit systems, the rules for partial measurement probabilities and outcomes can be summarized as follows:\n",
"Analogous to the case for measurements for single-qubit systems, the rules for partial measurement probabilities and outcomes can be summarized as follows:\n",
"- When a measurement is done, one of these projectors is chosen randomly. The probability of choosing projector $P_i$ is $\\big|P_i|\\psi\\rangle\\big|^2$.\n",
"- If the projector $P_i$ is chosen, the measurement outcome is $b_i$, and the state of the system after the measurement is given by\n",
"$$\n",
@ -781,7 +781,7 @@
"file_extension": ".qs",
"mimetype": "text/x-qsharp",
"name": "qsharp",
"version": "0.14"
"version": "0.24"
}
},
"nbformat": 4,

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

@ -8,7 +8,7 @@
"\n",
"This tutorial introduces you to measurements done on single-qubit systems. The concept of a measurement is a central part of quantum mechanics, as well as quantum algorithms. Single-qubit measurements, as their name implies are measurements on single qubits. The outcomes of a measurement in quantum mechanics are probabilistic, and in general, change the state of the qubit depending on the outcome of the measurement. \n",
"\n",
"We recommend to go through the [tutorial that introduces single qubit gates](../SingleQubitGates/SingleQubitGates.ipynb) before starting this one.\n",
"We recommend to go through the [tutorial that introduces single-qubit gates](../SingleQubitGates/SingleQubitGates.ipynb) before starting this one.\n",
"\n",
"This tutorial covers the following topics:\n",
"\n",
@ -73,7 +73,7 @@
"\n",
"If this qubit is measured in the computational basis, what are the outcome probabilities?\n",
"\n",
"*Can't come up with a solution? See the explained solution in the [Single Qubit System Measurements Workbook](./Workbook_SingleQubitSystemMeasurements.ipynb#Exercise-1:-The-probability-outcomes-for-a-specific-state).*\n"
"*Can't come up with a solution? See the explained solution in the [Single-Qubit System Measurements Workbook](./Workbook_SingleQubitSystemMeasurements.ipynb#Exercise-1:-The-probability-outcomes-for-a-specific-state).*\n"
]
},
{
@ -223,7 +223,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"*Can't come up with a solution? See the explained solution in the [Single Qubit System Measurements Workbook](./Workbook_SingleQubitSystemMeasurements.ipynb#Exercise-2:-Distinguish-$|0\\rangle$-and-$|1\\rangle$).*"
"*Can't come up with a solution? See the explained solution in the [Single-Qubit System Measurements Workbook](./Workbook_SingleQubitSystemMeasurements.ipynb#Exercise-2:-Distinguish-$|0\\rangle$-and-$|1\\rangle$).*"
]
},
{
@ -278,7 +278,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"*Can't come up with a solution? See the explained solution in the [Single Qubit System Measurements Workbook](./Workbook_SingleQubitSystemMeasurements.ipynb#Exercise-3:-Distinguish-$|+\\rangle$-and-$|-\\rangle$-using-the-Measure-operation).*"
"*Can't come up with a solution? See the explained solution in the [Single-Qubit System Measurements Workbook](./Workbook_SingleQubitSystemMeasurements.ipynb#Exercise-3:-Distinguish-$|+\\rangle$-and-$|-\\rangle$-using-the-Measure-operation).*"
]
},
{
@ -414,7 +414,7 @@
"<li>What are the outcome probabilities of measuring a qubit in the $0.6\\ket{0} + 0.8 \\ket{1}$ state in the Pauli Y basis, i.e., the $\\{ \\ket i, \\ket{-i}\\}$ basis?</li>\n",
"</ol> \n",
"\n",
"*Can't come up with a solution? See the explained solution in the [Single Qubit Measurement Tutorial Workbook](./Workbook_SingleQubitSystemMeasurements.ipynb#Exercise-4:-The-outcome-probabilities-for-a-measurement-in-a-specified-basis).*"
"*Can't come up with a solution? See the explained solution in the [Single-Qubit Measurement Tutorial Workbook](./Workbook_SingleQubitSystemMeasurements.ipynb#Exercise-4:-The-outcome-probabilities-for-a-measurement-in-a-specified-basis).*"
]
},
{
@ -454,7 +454,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"*Can't come up with a solution? See the explained solution in the [Single Qubit Measurement Tutorial Workbook](./Workbook_SingleQubitSystemMeasurements.ipynb#Exercise-5:-Distinguishing-orthogonal-states---1).*"
"*Can't come up with a solution? See the explained solution in the [Single-Qubit Measurement Tutorial Workbook](./Workbook_SingleQubitSystemMeasurements.ipynb#Exercise-5:-Distinguishing-orthogonal-states---1).*"
]
},
{
@ -495,7 +495,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"*Can't come up with a solution? See the explained solution in the [Single Qubit Measurement Tutorial Workbook](./Workbook_SingleQubitSystemMeasurements.ipynb#Exercise-6:-Distinguishing-orthogonal-states---2).*"
"*Can't come up with a solution? See the explained solution in the [Single-Qubit Measurement Tutorial Workbook](./Workbook_SingleQubitSystemMeasurements.ipynb#Exercise-6:-Distinguishing-orthogonal-states---2).*"
]
},
{
@ -536,7 +536,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"*Can't come up with a solution? See the explained solution in the [Single Qubit Measurement Tutorial Workbook](./Workbook_SingleQubitSystemMeasurements.ipynb#Exercise-7:-Measurement-in-the-$\\ket-A$,-$\\ket-B$-basis).*"
"*Can't come up with a solution? See the explained solution in the [Single-Qubit Measurement Tutorial Workbook](./Workbook_SingleQubitSystemMeasurements.ipynb#Exercise-7:-Measurement-in-the-$\\ket-A$,-$\\ket-B$-basis).*"
]
},
{
@ -546,7 +546,7 @@
"## Conclusion\n",
"\n",
"Congratulations! You have learned enough to try solving the first part of the [Measurements kata](../../Measurements/Measurements.ipynb). \n",
"When you are done with that, you can continue to the next tutorials in the series to learn about measurements for multi-qubit systems (coming soon...)"
"When you are done with that, you can continue to the next tutorial in the series to learn about [measurements for multi-qubit systems](../MultiQubitSystemMeasurements/MultiQubitSystemMeasurements.ipynb)."
]
}
],
@ -560,7 +560,7 @@
"file_extension": ".qs",
"mimetype": "text/x-qsharp",
"name": "qsharp",
"version": "0.14"
"version": "0.24"
}
},
"nbformat": 4,

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

@ -158,21 +158,13 @@ namespace Quantum.Kata.SingleQubitSystemMeasurements {
// |A⟩ = cos(alpha) * |0⟩ - i sin(alpha) * |1⟩,
// |B⟩ = - i sin(alpha) * |0⟩ + cos(alpha) * |1⟩.
// Wrapper function to convert the Result output of MeasureInABBasis to a bool type
operation IsResultZero( MeasurementOperation : (Qubit => Result), givenQubit : Qubit) : Bool {
mutable isZero = false;
if (MeasurementOperation(givenQubit) == Zero) {
set isZero = true;
}
return isZero;
}
// We can use the StatePrep_IsQubitA operation for the testing
@Test("QuantumSimulator")
operation T7_MeasureInABBasis () : Unit {
for i in 0 .. 10 {
let alpha = (PI() * IntAsDouble(i)) / 10.0;
DistinguishTwoStates(StatePrep_IsQubitA(alpha, _, _), IsResultZero(MeasureInABBasis(alpha, _),_),
DistinguishTwoStates(StatePrep_IsQubitA(alpha, _, _),
q => MeasureInABBasis(alpha, q) == Zero, // IsResultZero(MeasureInABBasis(alpha, _),_),
[$"|B⟩=(-i sin({i}π/10)|0⟩ + cos({i}π/10)|1⟩)", $"|A⟩=(cos({i}π/10)|0⟩ + i sin({i}π/10)|1⟩)"], true);
}
}