Add Oracles tutorial (#572)
This commit is contained in:
Родитель
5eb28be678
Коммит
e8d95f7cba
|
@ -57,6 +57,7 @@ RUN cd ${HOME} && \
|
|||
./scripts/prebuild-kata.sh tutorials/LinearAlgebra LinearAlgebra.ipynb && \
|
||||
./scripts/prebuild-kata.sh tutorials/MultiQubitGates MultiQubitGates.ipynb && \
|
||||
./scripts/prebuild-kata.sh tutorials/MultiQubitSystems MultiQubitSystems.ipynb && \
|
||||
./scripts/prebuild-kata.sh tutorials/Oracles Oracles.ipynb && \
|
||||
./scripts/prebuild-kata.sh tutorials/Qubit Qubit.ipynb && \
|
||||
./scripts/prebuild-kata.sh tutorials/RandomNumberGeneration RandomNumberGenerationTutorial.ipynb && \
|
||||
./scripts/prebuild-kata.sh tutorials/SingleQubitGates SingleQubitGates.ipynb && \
|
||||
|
|
|
@ -72,6 +72,8 @@ Here is the learning path we suggest you to follow if you are starting to learn
|
|||
|
||||
#### Quantum Oracles and Simple Oracle Algorithms
|
||||
|
||||
* **[Quantum oracles (tutorial)](./tutorials/Oracles/)**.
|
||||
Learn to implement classical functions as equivalent quantum oracles.
|
||||
* **[Exploring Deutsch–Jozsa algorithm (tutorial)](./tutorials/ExploringDeutschJozsaAlgorithm/)**.
|
||||
Learn to implement classical functions and equivalent quantum oracles, and compare the quantum
|
||||
solution to the Deutsch–Jozsa problem to a classical one.
|
||||
|
|
|
@ -62,6 +62,8 @@
|
|||
"\n",
|
||||
"#### Quantum Oracles and Simple Oracle Algorithms\n",
|
||||
"\n",
|
||||
"* **[Quantum oracles (tutorial)](./tutorials/Oracles/Oracles.ipynb)**.\n",
|
||||
" Learn to implement classical functions as equivalent quantum oracles. \n",
|
||||
"* **[Exploring Deutsch–Jozsa algorithm (tutorial)](./tutorials/ExploringDeutschJozsaAlgorithm/DeutschJozsaAlgorithmTutorial.ipynb)**.\n",
|
||||
" Learn to implement classical functions and equivalent quantum oracles, \n",
|
||||
" and compare the quantum solution to the Deutsch–Jozsa problem to a classical one.\n",
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{"dump.basisStateLabelingConvention":"Bitstring"}
|
|
@ -0,0 +1,21 @@
|
|||
<Project Sdk="Microsoft.Quantum.Sdk/0.13.20102604">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<RootNamespace>Quantum.Kata.Oracles</RootNamespace>
|
||||
<IQSharpLoadAutomatically>true</IQSharpLoadAutomatically>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Quantum.Katas" Version="0.13.20102604" />
|
||||
<PackageReference Include="Microsoft.Quantum.Xunit" Version="0.13.20102604" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="README.md" />
|
||||
</ItemGroup>
|
||||
</Project>
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,25 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30804.86
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Oracles", "Oracles.csproj", "{4C62ABA8-D7FE-466F-9E49-A1E1BDC5A387}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{4C62ABA8-D7FE-466F-9E49-A1E1BDC5A387}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4C62ABA8-D7FE-466F-9E49-A1E1BDC5A387}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4C62ABA8-D7FE-466F-9E49-A1E1BDC5A387}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4C62ABA8-D7FE-466F-9E49-A1E1BDC5A387}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {92226B5B-64F1-4622-8DF1-36BB95C384FB}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,9 @@
|
|||
# Welcome!
|
||||
|
||||
This folder contains a Notebook tutorial on quantum oracles - a fundamental concept for many quantum algorithms.
|
||||
|
||||
You can run the tutorial online [here](https://mybinder.org/v2/gh/Microsoft/QuantumKatas/main?filepath=tutorials/Oracles/Oracles.ipynb). Alternatively, you can install Jupyter and Q# on your machine, as described [here](https://docs.microsoft.com/quantum/install-guide/jupyter), and run the tutorial locally by navigating to this folder and starting the notebook from the command line using the following command:
|
||||
|
||||
jupyter notebook Oracles.ipynb
|
||||
|
||||
The Q# project in this folder contains the back-end of the tutorial and is not designed for direct use.
|
|
@ -0,0 +1,127 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// This file contains reference solutions to all tasks.
|
||||
// The tasks themselves can be found in Tasks.qs file.
|
||||
// We recommend that you try to solve the tasks yourself first,
|
||||
// but feel free to look up the solution if you get stuck.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace Quantum.Kata.Oracles {
|
||||
|
||||
open Microsoft.Quantum.Arrays;
|
||||
open Microsoft.Quantum.Canon;
|
||||
open Microsoft.Quantum.Convert;
|
||||
open Microsoft.Quantum.Diagnostics;
|
||||
open Microsoft.Quantum.Intrinsic;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Part I. Introduction to Quantum Oracles
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// Task 1.1.
|
||||
function IsSeven_Reference (x : Bool[]) : Bool {
|
||||
return BoolArrayAsInt(x) == 7;
|
||||
}
|
||||
|
||||
// Task 1.2.
|
||||
operation IsSeven_PhaseOracle_Reference (x : Qubit[]) : Unit is Adj + Ctl {
|
||||
Controlled Z(Most(x), Tail(x));
|
||||
}
|
||||
|
||||
// Task 1.3.
|
||||
operation IsSeven_MarkingOracle_Reference (x : Qubit[], y : Qubit) : Unit is Adj + Ctl {
|
||||
Controlled X(x, y);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Part II. Phase Kickback
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// Task 2.1.
|
||||
operation ApplyMarkingOracleAsPhaseOracle_Reference (markingOracle : ((Qubit[], Qubit) => Unit is Adj + Ctl), qubits : Qubit[]) : Unit is Adj + Ctl {
|
||||
using (minus = Qubit()) {
|
||||
within {
|
||||
X(minus);
|
||||
H(minus);
|
||||
} apply {
|
||||
markingOracle(qubits, minus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Oracle_Converter_Reference (markingOracle : ((Qubit[], Qubit) => Unit is Adj + Ctl)) : (Qubit[] => Unit is Adj + Ctl) {
|
||||
return ApplyMarkingOracleAsPhaseOracle_Reference(markingOracle, _);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Part III. Implementing Quantum Oracles
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// Task 3.1.
|
||||
operation Or_Oracle_Reference (x : Qubit[], y : Qubit) : Unit is Adj + Ctl {
|
||||
X(y);
|
||||
(ControlledOnInt(0, X))(x, y);
|
||||
}
|
||||
|
||||
// Task 3.2.
|
||||
operation KthBit_Oracle_Reference (x : Qubit[], k : Int) : Unit is Adj + Ctl {
|
||||
Z(x[k]);
|
||||
}
|
||||
|
||||
// Task 3.3.
|
||||
operation OrOfBitsExceptKth_Oracle_Reference (x : Qubit[], k : Int) : Unit is Adj + Ctl {
|
||||
using (minus = Qubit()) {
|
||||
within {
|
||||
X(minus);
|
||||
H(minus);
|
||||
} apply {
|
||||
Or_Oracle_Reference(x[...k-1] + x[k+1...], minus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Part IV. More Oracles! Implementation and Testing
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// Task 4.1.
|
||||
operation ArbitraryBitPattern_Oracle_Reference (x : Qubit[], y : Qubit, pattern : Bool[]) : Unit is Adj + Ctl {
|
||||
let PatternOracle = ControlledOnBitString(pattern, X);
|
||||
PatternOracle(x, y);
|
||||
}
|
||||
|
||||
// Task 4.2.
|
||||
operation ArbitraryBitPattern_Oracle_Challenge_Reference (x : Qubit[], pattern : Bool[]) : Unit is Adj + Ctl {
|
||||
within {
|
||||
for (i in IndexRange(x)) {
|
||||
if (not pattern[i]) {
|
||||
X(x[i]);
|
||||
}
|
||||
}
|
||||
} apply {
|
||||
Controlled Z(Most(x), Tail(x));
|
||||
}
|
||||
}
|
||||
|
||||
// Task 4.3.
|
||||
operation Meeting_Oracle_Reference (x : Qubit[], jasmine : Qubit[], z : Qubit) : Unit is Adj + Ctl {
|
||||
using (q = Qubit[Length(x)]) {
|
||||
within {
|
||||
for (i in IndexRange(q)) {
|
||||
// flip q[i] if both x and jasmine are free on the given day
|
||||
X(x[i]);
|
||||
X(jasmine[i]);
|
||||
CCNOT(x[i], jasmine[i], q[i]);
|
||||
}
|
||||
} apply {
|
||||
Or_Oracle_Reference(q, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// This file is a back end for the tasks in Quantum Oracles tutorial.
|
||||
// We strongly recommend to use the Notebook version of the tutorial
|
||||
// to enjoy the full experience.
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace Quantum.Kata.Oracles {
|
||||
|
||||
open Microsoft.Quantum.Canon;
|
||||
open Microsoft.Quantum.Diagnostics;
|
||||
open Microsoft.Quantum.Intrinsic;
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Part I. Introduction to Quantum Oracles
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// Task 1.1.
|
||||
function IsSeven (x : Bool[]) : Bool {
|
||||
// ...
|
||||
return false;
|
||||
}
|
||||
|
||||
// Task 1.2.
|
||||
operation IsSeven_PhaseOracle (x : Qubit[]) : Unit is Adj + Ctl {
|
||||
// ...
|
||||
}
|
||||
|
||||
// Task 1.3.
|
||||
operation IsSeven_MarkingOracle (x : Qubit[], y : Qubit) : Unit is Adj + Ctl {
|
||||
// ...
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Part II. Phase Kickback
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// Task 2.1.
|
||||
operation ApplyMarkingOracleAsPhaseOracle (markingOracle : ((Qubit[], Qubit) => Unit is Adj + Ctl), qubits : Qubit[]) : Unit is Adj + Ctl {
|
||||
// ...
|
||||
}
|
||||
|
||||
function Oracle_Converter (markingOracle : ((Qubit[], Qubit) => Unit is Adj + Ctl)) : (Qubit[] => Unit is Adj + Ctl) {
|
||||
return ApplyMarkingOracleAsPhaseOracle(markingOracle, _);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Part III. Implementing Quantum Oracles
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// Task 3.1.
|
||||
operation Or_Oracle (x : Qubit[], y : Qubit) : Unit is Adj + Ctl {
|
||||
// ...
|
||||
}
|
||||
|
||||
// Task 3.2.
|
||||
operation KthBit_Oracle (x : Qubit[], k : Int) : Unit is Adj + Ctl {
|
||||
// ...
|
||||
}
|
||||
|
||||
// Task 3.3
|
||||
operation OrOfBitsExceptKth_Oracle (x : Qubit[], k : Int) : Unit is Adj + Ctl {
|
||||
// ...
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Part IV. More Oracles! Implementation and Testing
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// Task 4.1.
|
||||
operation ArbitraryBitPattern_Oracle (x : Qubit[], y : Qubit, pattern : Bool[]) : Unit is Adj + Ctl {
|
||||
// ...
|
||||
}
|
||||
|
||||
// Task 4.2.
|
||||
operation ArbitraryBitPattern_Oracle_Challenge (x : Qubit[], pattern : Bool[]) : Unit is Adj + Ctl {
|
||||
// ...
|
||||
}
|
||||
|
||||
// Task 4.3.
|
||||
operation Meeting_Oracle (x : Qubit[], jasmine : Qubit[], z : Qubit) : Unit is Adj + Ctl {
|
||||
// ...
|
||||
}
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// This file contains testing harness for all tasks.
|
||||
// You should not modify anything in this file.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace Quantum.Kata.Oracles {
|
||||
|
||||
open Microsoft.Quantum.Canon;
|
||||
open Microsoft.Quantum.Convert;
|
||||
open Microsoft.Quantum.Diagnostics;
|
||||
open Microsoft.Quantum.Intrinsic;
|
||||
|
||||
open Quantum.Kata.Utils;
|
||||
|
||||
// ------------------------------------------------------
|
||||
// Helper functions
|
||||
operation ApplyOracle (qs : Qubit[], oracle : ((Qubit[], Qubit) => Unit is Adj + Ctl)) : Unit is Adj + Ctl {
|
||||
let N = Length(qs);
|
||||
oracle(qs[0 .. N - 2], qs[N - 1]);
|
||||
}
|
||||
|
||||
operation AssertTwoOraclesAreEqual (nQubits : Range,
|
||||
oracle1 : ((Qubit[], Qubit) => Unit is Adj + Ctl),
|
||||
oracle2 : ((Qubit[], Qubit) => Unit is Adj + Ctl)) : Unit {
|
||||
let sol = ApplyOracle(_, oracle1);
|
||||
let refSol = ApplyOracle(_, oracle2);
|
||||
|
||||
for (i in nQubits) {
|
||||
AssertOperationsEqualReferenced(i + 1, sol, refSol);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
@Test("QuantumSimulator")
|
||||
function T11_IsSeven_ClassicalOracle () : Unit {
|
||||
let N = 3;
|
||||
for (k in 0..((2^N)-1)) {
|
||||
let x = IntAsBoolArray(k, N);
|
||||
|
||||
let actual = IsSeven(x);
|
||||
let expected = IsSeven_Reference(x);
|
||||
|
||||
Fact(actual == expected, $" Failed on test case x = {x}: got {actual}, expected {expected}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
@Test("QuantumSimulator")
|
||||
operation T12_IsSeven_PhaseOracle () : Unit {
|
||||
let N = 3;
|
||||
within {
|
||||
AllowAtMostNQubits(2*N, "You are not allowed to allocate extra qubits");
|
||||
} apply {
|
||||
AssertOperationsEqualReferenced(N, IsSeven_PhaseOracle, IsSeven_PhaseOracle_Reference);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
@Test("QuantumSimulator")
|
||||
operation T13_IsSeven_MarkingOracle () : Unit {
|
||||
AssertTwoOraclesAreEqual(3..3, IsSeven_MarkingOracle, IsSeven_MarkingOracle_Reference);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
@Test("QuantumSimulator")
|
||||
operation T21_ApplyMarkingOracleAsPhaseOracle () : Unit {
|
||||
for (N in 1..5) {
|
||||
for (k in 0..(2^N-1)) {
|
||||
let pattern = IntAsBoolArray(k, N);
|
||||
|
||||
AssertOperationsEqualReferenced(N,
|
||||
Oracle_Converter(ArbitraryBitPattern_Oracle_Reference(_, _, pattern)),
|
||||
Oracle_Converter_Reference(ArbitraryBitPattern_Oracle_Reference(_, _, pattern)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
@Test("QuantumSimulator")
|
||||
operation T31_Or_Oracle () : Unit {
|
||||
AssertTwoOraclesAreEqual(1..10, Or_Oracle, Or_Oracle_Reference);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
@Test("QuantumSimulator")
|
||||
operation T32_KthBit_Oracle () : Unit {
|
||||
for (N in 1..5) {
|
||||
for (k in 0..(N-1)) {
|
||||
within {
|
||||
AllowAtMostNQubits(2*N, "You are not allowed to allocate extra qubits");
|
||||
} apply {
|
||||
AssertOperationsEqualReferenced(N,
|
||||
KthBit_Oracle(_, k),
|
||||
KthBit_Oracle_Reference(_, k));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
@Test("QuantumSimulator")
|
||||
operation T33_OrOfBitsExceptKth_Oracle () : Unit {
|
||||
for (N in 1..5) {
|
||||
for (k in 0..(N-1)) {
|
||||
AssertOperationsEqualReferenced(N,
|
||||
OrOfBitsExceptKth_Oracle(_, k),
|
||||
OrOfBitsExceptKth_Oracle_Reference(_, k));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
@Test("QuantumSimulator")
|
||||
operation T41_ArbitraryBitPattern_Oracle () : Unit {
|
||||
for (N in 1..4) {
|
||||
for (k in 0..((2^N)-1)) {
|
||||
let pattern = IntAsBoolArray(k, N);
|
||||
|
||||
AssertTwoOraclesAreEqual(N..N, ArbitraryBitPattern_Oracle(_, _, pattern),
|
||||
ArbitraryBitPattern_Oracle_Reference(_, _, pattern));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
@Test("QuantumSimulator")
|
||||
operation T42_ArbitraryBitPattern_Oracle_Challenge () : Unit {
|
||||
for (N in 1..4) {
|
||||
for (k in 0..((2^N)-1)) {
|
||||
let pattern = IntAsBoolArray(k, N);
|
||||
|
||||
within {
|
||||
AllowAtMostNQubits(2*N, "You are not allowed to allocate extra qubits");
|
||||
} apply {
|
||||
AssertOperationsEqualReferenced(N,
|
||||
ArbitraryBitPattern_Oracle_Challenge(_, pattern),
|
||||
ArbitraryBitPattern_Oracle_Challenge_Reference(_, pattern));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
@Test("QuantumSimulator")
|
||||
operation T43_Meeting_Oracle () : Unit {
|
||||
for (N in 1..4) {
|
||||
using (jasmine = Qubit[N]) {
|
||||
for (k in 0..(2^N-1)) {
|
||||
let binaryJasmine = IntAsBoolArray(k, N);
|
||||
|
||||
within {
|
||||
ApplyPauliFromBitString(PauliX, true, binaryJasmine, jasmine);
|
||||
} apply {
|
||||
AssertTwoOraclesAreEqual(1..N, Meeting_Oracle(_, jasmine, _),
|
||||
Meeting_Oracle_Reference(_, jasmine, _));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче