forked from microsoft/Quantum
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProgram.qs
118 lines (95 loc) · 5.06 KB
/
Program.qs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
//////////////////////////////////////////////////////////////////////////
// Introduction //////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// This sample contains several simple quantum algorithms coded in Q#. The
// intent is to highlight the expressive capabilities of the language that
// enable it to express quantum algorithms that consist of a short quantum
// part and classical post-processing that is simple, or in some cases,
// trivial.
namespace Microsoft.Quantum.Samples.SimpleAlgorithms {
open Microsoft.Quantum.Arrays as Array;
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Convert;
open Microsoft.Quantum.Samples.SimpleAlgorithms.HiddenShift;
open Microsoft.Quantum.Samples.SimpleAlgorithms.DeutschJozsa;
open Microsoft.Quantum.Samples.SimpleAlgorithms.BernsteinVazirani;
@EntryPoint()
operation RunProgram (nQubits : Int) : Unit {
// Parity Sampling with the Bernstein–Vazirani Algorithm:
// Consider a function 𝑓(𝑥⃗) on bitstrings 𝑥⃗ = (𝑥₀, …, 𝑥ₙ₋₁) of the
// form
//
// 𝑓(𝑥⃗) ≔ Σᵢ 𝑥ᵢ 𝑟ᵢ
//
// where 𝑟⃗ = (𝑟₀, …, 𝑟ₙ₋₁) is an unknown bitstring that determines
// the parity of 𝑓.
// The Bernstein–Vazirani algorithm allows determining 𝑟 given a
// quantum operation that implements
//
// |𝑥〉|𝑦〉 ↦ |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉.
//
// In SimpleAlgorithms.qs, we implement this algorithm as the
// operation RunBernsteinVazirani. This operation takes an
// integer whose bits describe 𝑟, then uses those bits to
// construct an appropriate operation, and finally measures 𝑟.
// We call that operation here, ensuring that we always get the
// same value for 𝑟 that we provided as input.
for (parity in 0 .. (1 <<< nQubits) - 1)
{
let measuredParity = RunBernsteinVazirani(nQubits, parity);
if (measuredParity != parity) {
fail $"Measured parity {measuredParity}, but expected {parity}.";
}
}
Message("All parities measured successfully!");
// Constant versus Balanced Functions with the Deutsch–Jozsa Algorithm:
// A Boolean function is a function that maps bitstrings to a
// bit,
//
// 𝑓 : {0, 1}^n → {0, 1}.
//
// We say that 𝑓 is constant if 𝑓(𝑥⃗) = 𝑓(𝑦⃗) for all bitstrings
// 𝑥⃗ and 𝑦⃗, and that 𝑓 is balanced if 𝑓 evaluates to true (1) for
// exactly half of its inputs.
// If we are given a function 𝑓 as a quantum operation 𝑈 |𝑥〉|𝑦〉
// = |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉, and are promised that 𝑓 is either constant or
// is balanced, then the Deutsch–Jozsa algorithm decides between
// these cases with a single application of 𝑈.
// In SimpleAlgorithms.qs, we implement this algorithm as
// RunDeutschJozsa, following the pattern above.
// This time, however, we will pass an array to Q# indicating
// which elements of 𝑓 are marked; that is, should result in true.
// We check by ensuring that RunDeutschJozsa returns true
// for constant functions and false for balanced functions.
let elements = nQubits > 0 ? Array.SequenceI(0, (1 <<< nQubits) - 1) | new Int[0];
if (RunDeutschJozsa(nQubits, elements[...2...])) {
fail "Measured that test case {balancedTestCase} was constant!";
}
if (not RunDeutschJozsa(nQubits, elements))
{
fail "Measured that test case {constantTestCase} was balanced!";
}
Message("Both constant and balanced functions measured successfully!");
// Finding Hidden Shifts of Bent Functions with the Roetteler Algorithm:
// Finally, we consider the case of finding a hidden shift 𝑠
// between two Boolean functions 𝑓(𝑥) and 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠).
// This problem can be solved on a quantum computer with one call
// to each of 𝑓 and 𝑔 in the special case that both functions are
// bent; that is, that they are as far from linear as possible.
// Here, we run the test case HiddenShiftBentCorrelationTestCase
// defined in the matching Q# source code, and ensure that it
// correctly finds each hidden shift for a family of bent
// functions defined by the inner product.
for (shift in 0 .. (1 <<< nQubits) - 1)
{
let measuredShift = RunHiddenShift(shift, nQubits);
if (measuredShift != shift) {
fail $"Measured shift {measuredShift}, but expected {shift}.";
}
}
Message("Measured hidden shifts successfully!");
}
}