Line | Branch | Decision | Exec | Source |
---|---|---|---|---|
1 | // Copyright 2019-2022 Cambridge Quantum Computing | |||
2 | // | |||
3 | // Licensed under the Apache License, Version 2.0 (the "License"); | |||
4 | // you may not use this file except in compliance with the License. | |||
5 | // You may obtain a copy of the License at | |||
6 | // | |||
7 | // http://www.apache.org/licenses/LICENSE-2.0 | |||
8 | // | |||
9 | // Unless required by applicable law or agreed to in writing, software | |||
10 | // distributed under the License is distributed on an "AS IS" BASIS, | |||
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
12 | // See the License for the specific language governing permissions and | |||
13 | // limitations under the License. | |||
14 | ||||
15 | #pragma once | |||
16 | ||||
17 | #include "OpType/OpType.hpp" | |||
18 | #include "Utils/Expression.hpp" | |||
19 | #include "Utils/MatrixAnalysis.hpp" | |||
20 | ||||
21 | namespace tket { | |||
22 | ||||
23 | /** A faithful representation of SU(2). */ | |||
24 | class Rotation { | |||
25 | public: | |||
26 | /** Identity */ | |||
27 | 37846 | Rotation() | ||
28 |
4/8✓ Branch 2 taken 37846 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 37846 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 37846 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 37846 times.
✗ Branch 12 not taken.
|
37846 | : rep_(Rep::id), s_(1), i_(0), j_(0), k_(0), optype_(OpType::noop) {} | |
29 | ||||
30 | /** | |||
31 | * Represent an X, Y or Z rotation | |||
32 | * | |||
33 | * @param optype one of @ref OpType::Rx, @ref OpType::Ry or @ref OpType::Rz | |||
34 | * @param a angle in half-turns | |||
35 | */ | |||
36 | Rotation(OpType optype, Expr a); | |||
37 | ||||
38 | /** Apply a second rotation */ | |||
39 | void apply(const Rotation& other); | |||
40 | ||||
41 | /** Is it the identity? */ | |||
42 | 187834 | bool is_id() const { return rep_ == Rep::id; } | ||
43 | ||||
44 | /** Is it minus the identity? */ | |||
45 | bool is_minus_id() const { return rep_ == Rep::minus_id; } | |||
46 | ||||
47 | /** | |||
48 | * Return the angle given the axis | |||
49 | * | |||
50 | * @param optype axis of rotation | |||
51 | * | |||
52 | * @return angle of rotation in half-turns, if the axis matches | |||
53 | * @pre \p optype is @ref OpType::Rx, @ref OpType::Ry or @ref OpType::Rz | |||
54 | */ | |||
55 | std::optional<Expr> angle(OpType optype) const; | |||
56 | ||||
57 | /** | |||
58 | * Convert to a sequence of angles in a PQP representation | |||
59 | * | |||
60 | * @param p one of @ref OpType::Rx, @ref OpType::Ry or @ref OpType::Rz | |||
61 | * @param q one of @ref OpType::Rx, @ref OpType::Ry or @ref OpType::Rz | |||
62 | * | |||
63 | * @return angles (p1,q,p2) (in half-turns) such that the rotation is | |||
64 | * equivalent to P(p1) followed by Q(q) followed by P(p2) | |||
65 | * | |||
66 | * @pre p != q | |||
67 | */ | |||
68 | std::tuple<Expr, Expr, Expr> to_pqp(OpType p, OpType q) const; | |||
69 | ||||
70 | // Default copy and assignment is fine. | |||
71 | ||||
72 | friend std::ostream& operator<<(std::ostream& os, const Rotation& q); | |||
73 | ||||
74 | private: | |||
75 | enum class Rep { | |||
76 | id, /**< identity rotation */ | |||
77 | minus_id, /**< minus the identity */ | |||
78 | orth_rot, /**< rotation about X, Y or Z */ | |||
79 | quat /**< general rotation */ | |||
80 | }; | |||
81 | Rep rep_; | |||
82 | ||||
83 | // We represent every rotation as a quaternion of unit norm: | |||
84 | Expr s_; // scalar | |||
85 | Expr i_; // i coordinate | |||
86 | Expr j_; // j coordinate | |||
87 | Expr k_; // k coordinate | |||
88 | ||||
89 | // If rep_ == Rep::orth_rot, we represent the rotation as an axis and angle: | |||
90 | OpType optype_; | |||
91 | Expr a_; | |||
92 | }; | |||
93 | ||||
94 | /** | |||
95 | * Construct TK1 angles and phase from matrix | |||
96 | * | |||
97 | * @param U 2x2 unitary matrix | |||
98 | * | |||
99 | * @return [a,b,c,t] where a,b,c are the TK1 angles and t is the phase | |||
100 | */ | |||
101 | std::vector<double> tk1_angles_from_unitary(const Eigen::Matrix2cd& U); | |||
102 | ||||
103 | /** | |||
104 | * Construct matrix from TK1 angles and phase | |||
105 | * | |||
106 | * @param params [a,b,c,t] where a,b,c are the TK1 angles and t is the phase | |||
107 | * | |||
108 | * @return 2x2 unitary matrix | |||
109 | * @pre no symbolic parameters | |||
110 | */ | |||
111 | Eigen::Matrix2cd get_matrix_from_tk1_angles(std::vector<Expr> params); | |||
112 | ||||
113 | } // namespace tket | |||
114 |