forked from microsoft/QuantumKatas
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Tests.qs
133 lines (100 loc) · 5.04 KB
/
Tests.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// 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.
// The tasks themselves can be found in Tasks.qs file.
//////////////////////////////////////////////////////////////////////
namespace Quantum.Kata.PhaseEstimation {
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Diagnostics;
open Quantum.Kata.Utils;
//////////////////////////////////////////////////////////////////
// Part I. Quantum phase estimation (QPE)
//////////////////////////////////////////////////////////////////
operation AssertEqualOnZeroState1 (testImpl : (Qubit => Unit), refImpl : (Qubit => Unit is Adj)) : Unit {
using (q = Qubit()) {
// apply operation that needs to be tested
testImpl(q);
// apply adjoint reference operation and check that the result is |0⟩
Adjoint refImpl(q);
AssertQubit(Zero, q);
}
}
operation T11_Eigenstates_ZST_Test () : Unit {
for (state in 0 .. 1) {
AssertEqualOnZeroState1(Eigenstates_ZST(_, state), Eigenstates_ZST_Reference(_, state));
}
}
// ------------------------------------------------------
// helper wrapper to represent operation on one qubit as an operation on an array of qubits
operation ArrayWrapperOperation1 (op : (Qubit => Unit is Adj + Ctl), qs : Qubit[]) : Unit is Adj + Ctl {
op(qs[0]);
}
operation T12_UnitaryPower_Test () : Unit {
for (U in [Z, S, T]) {
for (power in 1 .. 5) {
AssertOperationsEqualReferenced(1, ArrayWrapperOperation1(UnitaryPower(U, power), _),
ArrayWrapperOperation1(UnitaryPower_Reference(U, power), _));
}
}
}
// ------------------------------------------------------
operation TestAssertIsEigenstate_True () : Unit {
// Test state/unitary pairs which are eigenstates (so no exception should be thrown)
for ((unitary, statePrep) in [(Z, I), (Z, X),
(S, I), (S, X),
(X, H), (X, BoundCA([X, H])),
(Y, BoundCA([H, S])), (Y, BoundCA([X, H, S]))]) {
AssertIsEigenstate(unitary, statePrep);
}
}
// ------------------------------------------------------
operation T14_QPE_Test () : Unit {
EqualityWithinToleranceFact(QPE(Z, I, 1), 0.0, 0.25);
EqualityWithinToleranceFact(QPE(Z, X, 1), 0.5, 0.25);
EqualityWithinToleranceFact(QPE(S, I, 2), 0.0, 0.125);
EqualityWithinToleranceFact(QPE(S, X, 2), 0.25, 0.125);
EqualityWithinToleranceFact(QPE(T, I, 3), 0.0, 0.0625);
EqualityWithinToleranceFact(QPE(T, X, 3), 0.125, 0.0625);
}
//////////////////////////////////////////////////////////////////
// Part II. Iterative phase estimation
//////////////////////////////////////////////////////////////////
operation Test1BitPEOnOnePair(U : (Qubit => Unit is Adj + Ctl), P : (Qubit => Unit is Adj), expected : Int) : Unit {
ResetQubitCount();
ResetOracleCallsCount();
let actual = SingleBitPE(U, P);
EqualityFactI(actual, expected, $"Unexpected return for ({U}, {P}): expected {expected}, got {actual}");
let nq = GetMaxQubitCount();
EqualityFactI(nq, 2, $"You are allowed to allocate exactly 2 qubits, and you allocated {nq}");
let nu = GetOracleCallsCount(Controlled U);
EqualityFactI(nu, 1, $"You are allowed to call Controlled U exactly once, and you called it {nu} times");
}
operation T21_SingleBitPE_Test () : Unit {
Test1BitPEOnOnePair(Z, I, +1);
Test1BitPEOnOnePair(Z, X, -1);
Test1BitPEOnOnePair(X, H, +1);
Test1BitPEOnOnePair(X, BoundCA([X, H]), -1);
}
// ------------------------------------------------------
operation Test2BitPEOnOnePair(U : (Qubit => Unit is Adj + Ctl), P : (Qubit => Unit is Adj), expected : Double) : Unit {
ResetQubitCount();
let actual = TwoBitPE(U, P);
EqualityWithinToleranceFact(actual, expected, 0.001);
let nq = GetMaxQubitCount();
EqualityFactI(nq, 2, $"You are allowed to allocate exactly 2 qubits, and you allocated {nq}");
}
operation T22_TwoBitPE_Test () : Unit {
Test2BitPEOnOnePair(Z, I, 0.0);
Test2BitPEOnOnePair(Z, X, 0.5);
Test2BitPEOnOnePair(S, X, 0.25);
Test2BitPEOnOnePair(BoundCA([S, Z]), X, 0.75);
Test2BitPEOnOnePair(X, H, 0.0);
Test2BitPEOnOnePair(X, BoundCA([X, H]), 0.5);
Test2BitPEOnOnePair(BoundCA([H, S, H]), H, 0.0);
Test2BitPEOnOnePair(BoundCA([H, S, H]), BoundCA([X, H]), 0.25);
Test2BitPEOnOnePair(BoundCA([H, S, Z, H]), BoundCA([X, H]), 0.75);
}
}