-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathAdjointControlled.qs
69 lines (63 loc) · 2.16 KB
/
AdjointControlled.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
namespace CallableExamples {
open Microsoft.Quantum.Arrays;
open Microsoft.Quantum.Diagnostics;
open Microsoft.Quantum.Intrinsic;
// Add "is Adj + Ctl" suffix to generate specializations automatically.
operation ApplyRyArrayCA(
qs : Qubit[],
angles : Double[]
) : Unit is Adj + Ctl {
for (q, angle) in Zipped(qs, angles) {
Ry(angle, q);
}
}
// You can define specializations manually.
operation ApplyRyArrayCAManual(
qs : Qubit[],
angles : Double[]
) : Unit is Adj + Ctl {
body (...) {
for (q, angle) in Zipped(qs, angles) {
Ry(angle, q);
}
}
adjoint (...) {
// The gates applied to different qubits
// commute, so no need to reverse loop.
for (q, angle) in Zipped(qs, angles) {
// Adjoint of a rotation gate is
// the same gate with the opposite
// rotation angle.
Ry(-angle, q);
}
}
controlled (cs, ...) {
for (q, angle) in Zipped(qs, angles) {
Controlled Ry(cs, (angle, q));
}
}
controlled adjoint auto;
}
/// # Summary
/// The collection of examples of working with adjoint and controlled specializations.
operation AdjointControlledExamples() : Unit {
Message("============================== Q# callables: adjoint and controlled ==============================");
// Example 1: Calling adjoint specialization.
Message("\nExample 1: Calling adjoint specialization.");
use qs = Qubit[2] {
let angles = [.2, .4];
Adjoint ApplyRyArrayCA(qs, angles);
DumpMachine();
ResetAll(qs);
}
// Example 2: Calling controlled specialization.
Message("\nExample 1: Calling controlled specialization.");
use (cs, qs) = (Qubit[1], Qubit[2]) {
H(cs[0]);
let angles = [.2, .4];
Controlled ApplyRyArrayCAManual(cs, (qs, angles));
DumpMachine();
ResetAll(cs + qs);
}
}
}