Update the tutorial for Hopper x1 Seattle

* Update QDK to version 0.5
* Switch the algorithm from marking oracle to phase-flipping oracle
* Improve usability
This commit is contained in:
Mariia Mykhailova 2019-03-12 20:41:42 -07:00
Родитель 2cd98e9d05
Коммит e1d9d4a647
5 изменённых файлов: 50 добавлений и 16 удалений

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

@ -8,25 +8,26 @@
namespace Quantum.DeutschJozsaAlgorithm {
open Microsoft.Quantum.Primitive;
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Extensions.Diagnostics;
// Inputs:
// 1) the number of qubits N in the input register for the function f
// 2) a quantum operation which implements the oracle |x⟩|y⟩ -> |x⟩|y ⊕ f(x)⟩, where
// x is N-qubit input register, y is 1-qubit answer register, and f is a Boolean function
// 2) a quantum operation which implements the phase-flipping oracle |x⟩ -> (-1)ᶠ⁽ˣ⁾ |x⟩,
// where x is an N-qubit input register, and f is a Boolean function
// You are guaranteed that the function f implemented by the oracle is either
// constant (returns 0 on all inputs or 1 on all inputs) or
// balanced (returns 0 on exactly one half of the input domain and 1 on the other half).
// Return:
// true if the function f is constant
// false if the function f is balanced
operation DeutschJozsaAlgorithm (N : Int, oracle : ((Qubit[], Qubit) => Unit)) : Bool {
operation DeutschJozsaAlgorithm (N : Int, oracle : (Qubit[] => Unit)) : Bool {
// Create a boolean variable for storing the return value.
// You'll need to update it later, so it has to be declared as mutable.
mutable isConstant = true;
// Allocate an array of N qubits for the input register x and a qubit for the answer register y.
using ((x, y) = (Qubit[N], Qubit())) {
// Allocate an array of N qubits for the input register x.
using (x = Qubit[N]) {
// Newly allocated qubits start in the |0⟩ state.
// The first step is to prepare the qubits in the required state before calling the oracle.
// Each qubit of the input register has to be in the |+⟩ state.
@ -34,22 +35,23 @@ namespace Quantum.DeutschJozsaAlgorithm {
// You can use the library function ApplyToEach to apply a gate to each qubit of a register;
// the first argument is the name of the gate to be applied, and the second argument is the name of the register.
// The answer register has to be in the |-⟩ state.
// A qubit can be transformed from the |0⟩ state to the |-⟩ state by applying an X gate followed by an H gate.
// To apply a gate to a qubit, type the name of the gate followed by the name of the qubit in round brackets.
// Apply the oracle to the input register and the answer register.
// The syntax is the same as for applying a gate.
// Apply the oracle to the input register.
// The syntax is the same as for applying any function or operation.
// Apply a Hadamard gate to each qubit of the input register again.
// Measure each qubit of the input register in the computational basis using the M operation.
// You can use a for loop to iterate over the range of indexes 0..N-1.
// If any of the measurement results is One, the function implemented by the oracle is balanced.
// Note that you can't return the answer in the middle of a loop,
// you have to update the variable isConstant using the "set" keyword.
// Before releasing the qubits make sure they are all in the |0⟩ state.
// Before releasing the qubits make sure they are all in the |0⟩ state
// (otherwise you'll get a ReleasedQubitsAreNotInZeroState exception).
// You can use the library operation Reset which measures a qubit and applies a correction if necessary.
// The library operation ResetAll does the same for a register of qubits.

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

@ -7,7 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Quantum.Canon" Version="0.3.1810.2508-preview" />
<PackageReference Include="Microsoft.Quantum.Development.Kit" Version="0.3.1810.2508-preview" />
<PackageReference Include="Microsoft.Quantum.Canon" Version="0.5.1902.2802" />
<PackageReference Include="Microsoft.Quantum.Development.Kit" Version="0.5.1902.2802" />
</ItemGroup>
</Project>

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

@ -23,6 +23,8 @@ namespace Quantum.DeutschJozsaAlgorithm
catch (System.Exception e) {
System.Console.WriteLine("Exception: " + e.InnerException.Message);
}
System.Console.WriteLine("Press any key to continue...");
System.Console.ReadKey();
}
}
}

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

@ -107,4 +107,30 @@ namespace Quantum.DeutschJozsaAlgorithm {
adjoint invert;
}
// ------------------------------------------------------------------------------------------
// helper functions to convert a marking oracle, as defined above, to a phase oracle, as used in the algorithm
operation MarkingToPhaseOracleImpl (markingOracle : ((Qubit[], Qubit) => Unit), register : Qubit[]) : Unit {
body (...) {
using (target = Qubit()) {
// Put the target into the |-⟩ state
X(target);
H(target);
// Apply the marking oracle; since the target is in the |-⟩ state,
// flipping the target if the register satisfies the oracle condition will apply a -1 factor to the state
markingOracle(register, target);
// Put the target back into |0⟩ so we can return it
H(target);
X(target);
}
}
}
function MarkingToPhaseOracle (markingOracle : ((Qubit[], Qubit) => Unit)) : (Qubit[] => Unit) {
return MarkingToPhaseOracleImpl(markingOracle, _);
}
}

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

@ -24,10 +24,14 @@ namespace Quantum.DeutschJozsaAlgorithm {
}
// ------------------------------------------------------------------------------------------
operation CheckAlgorithmOnOneTest (N : Int, oracle : ((Qubit[], Qubit) => Unit), expected : Bool, extraInfo : String) : Bool {
operation CheckAlgorithmOnOneTest (N : Int, markingOracle : ((Qubit[], Qubit) => Unit), expected : Bool, extraInfo : String) : Bool {
ResetOracleCallsCount();
let actual = DeutschJozsaAlgorithm(N, oracle);
// convert marking oracle to phase oracle
let phaseOracle = MarkingToPhaseOracle(markingOracle);
let actual = DeutschJozsaAlgorithm(N, phaseOracle);
// check that the return value is correct
if (actual != expected) {
@ -38,7 +42,7 @@ namespace Quantum.DeutschJozsaAlgorithm {
}
// check that the oracle has been called at most once
AssertOracleCallsCount(1, oracle);
AssertOracleCallsCount(1, phaseOracle);
return true;
}