qiskit 2.0.2__cp39-abi3-macosx_11_0_arm64.whl → 2.1.0rc1__cp39-abi3-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +19 -1
  3. qiskit/_accelerate.abi3.so +0 -0
  4. qiskit/circuit/__init__.py +13 -21
  5. qiskit/circuit/_add_control.py +57 -31
  6. qiskit/circuit/_classical_resource_map.py +4 -0
  7. qiskit/circuit/annotation.py +404 -0
  8. qiskit/circuit/classical/expr/__init__.py +1 -1
  9. qiskit/circuit/classical/expr/expr.py +104 -446
  10. qiskit/circuit/classical/expr/visitors.py +6 -0
  11. qiskit/circuit/classical/types/types.py +7 -130
  12. qiskit/circuit/controlflow/box.py +32 -7
  13. qiskit/circuit/delay.py +11 -9
  14. qiskit/circuit/library/arithmetic/adders/adder.py +5 -5
  15. qiskit/circuit/library/arithmetic/multipliers/multiplier.py +3 -3
  16. qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +7 -3
  17. qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +23 -15
  18. qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +22 -14
  19. qiskit/circuit/library/arithmetic/quadratic_form.py +6 -0
  20. qiskit/circuit/library/arithmetic/weighted_adder.py +43 -24
  21. qiskit/circuit/library/basis_change/qft.py +2 -2
  22. qiskit/circuit/library/blueprintcircuit.py +6 -0
  23. qiskit/circuit/library/boolean_logic/inner_product.py +2 -2
  24. qiskit/circuit/library/boolean_logic/quantum_and.py +2 -2
  25. qiskit/circuit/library/boolean_logic/quantum_or.py +3 -3
  26. qiskit/circuit/library/boolean_logic/quantum_xor.py +2 -2
  27. qiskit/circuit/library/data_preparation/_z_feature_map.py +2 -2
  28. qiskit/circuit/library/data_preparation/_zz_feature_map.py +2 -2
  29. qiskit/circuit/library/data_preparation/pauli_feature_map.py +2 -2
  30. qiskit/circuit/library/fourier_checking.py +2 -2
  31. qiskit/circuit/library/generalized_gates/diagonal.py +5 -1
  32. qiskit/circuit/library/generalized_gates/gms.py +5 -1
  33. qiskit/circuit/library/generalized_gates/linear_function.py +2 -2
  34. qiskit/circuit/library/generalized_gates/permutation.py +5 -1
  35. qiskit/circuit/library/generalized_gates/uc.py +1 -1
  36. qiskit/circuit/library/generalized_gates/unitary.py +21 -2
  37. qiskit/circuit/library/graph_state.py +2 -2
  38. qiskit/circuit/library/grover_operator.py +2 -2
  39. qiskit/circuit/library/hidden_linear_function.py +2 -2
  40. qiskit/circuit/library/iqp.py +2 -2
  41. qiskit/circuit/library/n_local/efficient_su2.py +2 -2
  42. qiskit/circuit/library/n_local/evolved_operator_ansatz.py +1 -1
  43. qiskit/circuit/library/n_local/excitation_preserving.py +7 -9
  44. qiskit/circuit/library/n_local/n_local.py +4 -3
  45. qiskit/circuit/library/n_local/pauli_two_design.py +2 -2
  46. qiskit/circuit/library/n_local/real_amplitudes.py +2 -2
  47. qiskit/circuit/library/n_local/two_local.py +2 -2
  48. qiskit/circuit/library/overlap.py +2 -2
  49. qiskit/circuit/library/pauli_evolution.py +3 -2
  50. qiskit/circuit/library/phase_estimation.py +2 -2
  51. qiskit/circuit/library/standard_gates/dcx.py +11 -12
  52. qiskit/circuit/library/standard_gates/ecr.py +21 -24
  53. qiskit/circuit/library/standard_gates/equivalence_library.py +232 -96
  54. qiskit/circuit/library/standard_gates/global_phase.py +5 -6
  55. qiskit/circuit/library/standard_gates/h.py +22 -45
  56. qiskit/circuit/library/standard_gates/i.py +1 -1
  57. qiskit/circuit/library/standard_gates/iswap.py +13 -31
  58. qiskit/circuit/library/standard_gates/p.py +19 -26
  59. qiskit/circuit/library/standard_gates/r.py +11 -17
  60. qiskit/circuit/library/standard_gates/rx.py +21 -45
  61. qiskit/circuit/library/standard_gates/rxx.py +7 -22
  62. qiskit/circuit/library/standard_gates/ry.py +21 -39
  63. qiskit/circuit/library/standard_gates/ryy.py +13 -28
  64. qiskit/circuit/library/standard_gates/rz.py +18 -35
  65. qiskit/circuit/library/standard_gates/rzx.py +7 -22
  66. qiskit/circuit/library/standard_gates/rzz.py +7 -19
  67. qiskit/circuit/library/standard_gates/s.py +44 -39
  68. qiskit/circuit/library/standard_gates/swap.py +25 -38
  69. qiskit/circuit/library/standard_gates/sx.py +34 -41
  70. qiskit/circuit/library/standard_gates/t.py +18 -27
  71. qiskit/circuit/library/standard_gates/u.py +8 -24
  72. qiskit/circuit/library/standard_gates/u1.py +28 -52
  73. qiskit/circuit/library/standard_gates/u2.py +9 -9
  74. qiskit/circuit/library/standard_gates/u3.py +24 -40
  75. qiskit/circuit/library/standard_gates/x.py +190 -336
  76. qiskit/circuit/library/standard_gates/xx_minus_yy.py +12 -50
  77. qiskit/circuit/library/standard_gates/xx_plus_yy.py +13 -52
  78. qiskit/circuit/library/standard_gates/y.py +19 -23
  79. qiskit/circuit/library/standard_gates/z.py +31 -38
  80. qiskit/circuit/parameter.py +14 -5
  81. qiskit/circuit/parameterexpression.py +109 -75
  82. qiskit/circuit/quantumcircuit.py +168 -98
  83. qiskit/circuit/quantumcircuitdata.py +1 -0
  84. qiskit/circuit/random/__init__.py +37 -2
  85. qiskit/circuit/random/utils.py +445 -56
  86. qiskit/circuit/tools/pi_check.py +5 -13
  87. qiskit/compiler/transpiler.py +1 -1
  88. qiskit/converters/circuit_to_instruction.py +2 -2
  89. qiskit/dagcircuit/dagnode.py +8 -3
  90. qiskit/primitives/__init__.py +2 -2
  91. qiskit/primitives/base/base_estimator.py +2 -2
  92. qiskit/primitives/containers/data_bin.py +0 -3
  93. qiskit/primitives/containers/observables_array.py +192 -108
  94. qiskit/primitives/primitive_job.py +29 -10
  95. qiskit/providers/fake_provider/generic_backend_v2.py +2 -0
  96. qiskit/qasm3/__init__.py +106 -12
  97. qiskit/qasm3/ast.py +15 -1
  98. qiskit/qasm3/exporter.py +59 -36
  99. qiskit/qasm3/printer.py +12 -0
  100. qiskit/qpy/__init__.py +183 -7
  101. qiskit/qpy/binary_io/circuits.py +256 -24
  102. qiskit/qpy/binary_io/parse_sympy_repr.py +5 -0
  103. qiskit/qpy/binary_io/schedules.py +12 -32
  104. qiskit/qpy/binary_io/value.py +36 -18
  105. qiskit/qpy/common.py +11 -3
  106. qiskit/qpy/formats.py +17 -1
  107. qiskit/qpy/interface.py +52 -12
  108. qiskit/qpy/type_keys.py +7 -1
  109. qiskit/quantum_info/__init__.py +10 -0
  110. qiskit/quantum_info/operators/__init__.py +1 -0
  111. qiskit/quantum_info/operators/symplectic/__init__.py +1 -0
  112. qiskit/quantum_info/operators/symplectic/clifford_circuits.py +26 -0
  113. qiskit/quantum_info/operators/symplectic/pauli.py +2 -2
  114. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +1 -1
  115. qiskit/result/sampled_expval.py +3 -1
  116. qiskit/synthesis/__init__.py +10 -0
  117. qiskit/synthesis/arithmetic/__init__.py +1 -1
  118. qiskit/synthesis/arithmetic/adders/__init__.py +1 -0
  119. qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +6 -2
  120. qiskit/synthesis/arithmetic/adders/rv_ripple_carry_adder.py +156 -0
  121. qiskit/synthesis/discrete_basis/generate_basis_approximations.py +14 -126
  122. qiskit/synthesis/discrete_basis/solovay_kitaev.py +161 -121
  123. qiskit/synthesis/evolution/lie_trotter.py +10 -7
  124. qiskit/synthesis/evolution/product_formula.py +10 -7
  125. qiskit/synthesis/evolution/qdrift.py +10 -7
  126. qiskit/synthesis/evolution/suzuki_trotter.py +10 -7
  127. qiskit/synthesis/multi_controlled/__init__.py +4 -0
  128. qiskit/synthesis/multi_controlled/mcx_synthesis.py +402 -178
  129. qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +14 -15
  130. qiskit/synthesis/qft/qft_decompose_lnn.py +7 -25
  131. qiskit/synthesis/unitary/qsd.py +80 -9
  132. qiskit/transpiler/__init__.py +19 -8
  133. qiskit/transpiler/instruction_durations.py +2 -20
  134. qiskit/transpiler/passes/__init__.py +4 -2
  135. qiskit/transpiler/passes/layout/dense_layout.py +26 -6
  136. qiskit/transpiler/passes/layout/disjoint_utils.py +1 -166
  137. qiskit/transpiler/passes/layout/sabre_layout.py +22 -3
  138. qiskit/transpiler/passes/layout/sabre_pre_layout.py +1 -1
  139. qiskit/transpiler/passes/layout/vf2_layout.py +49 -13
  140. qiskit/transpiler/passes/layout/vf2_utils.py +13 -1
  141. qiskit/transpiler/passes/optimization/__init__.py +1 -1
  142. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +2 -1
  143. qiskit/transpiler/passes/optimization/optimize_clifford_t.py +68 -0
  144. qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +3 -9
  145. qiskit/transpiler/passes/routing/sabre_swap.py +12 -2
  146. qiskit/transpiler/passes/routing/star_prerouting.py +106 -81
  147. qiskit/transpiler/passes/scheduling/__init__.py +1 -1
  148. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -1
  149. qiskit/transpiler/passes/scheduling/padding/__init__.py +1 -0
  150. qiskit/transpiler/passes/scheduling/padding/context_aware_dynamical_decoupling.py +876 -0
  151. qiskit/transpiler/passes/synthesis/__init__.py +1 -0
  152. qiskit/transpiler/passes/synthesis/clifford_unitary_synth_plugin.py +123 -0
  153. qiskit/transpiler/passes/synthesis/hls_plugins.py +472 -92
  154. qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +27 -22
  155. qiskit/transpiler/passmanager_config.py +3 -0
  156. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +149 -28
  157. qiskit/transpiler/preset_passmanagers/common.py +101 -0
  158. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +6 -0
  159. qiskit/transpiler/preset_passmanagers/level3.py +2 -2
  160. qiskit/utils/optionals.py +6 -5
  161. qiskit/visualization/circuit/_utils.py +5 -3
  162. qiskit/visualization/circuit/latex.py +9 -2
  163. qiskit/visualization/circuit/matplotlib.py +26 -4
  164. qiskit/visualization/circuit/qcstyle.py +9 -157
  165. qiskit/visualization/dag/__init__.py +13 -0
  166. qiskit/visualization/dag/dagstyle.py +103 -0
  167. qiskit/visualization/dag/styles/__init__.py +13 -0
  168. qiskit/visualization/dag/styles/color.json +10 -0
  169. qiskit/visualization/dag/styles/plain.json +5 -0
  170. qiskit/visualization/dag_visualization.py +169 -98
  171. qiskit/visualization/style.py +223 -0
  172. {qiskit-2.0.2.dist-info → qiskit-2.1.0rc1.dist-info}/METADATA +14 -13
  173. {qiskit-2.0.2.dist-info → qiskit-2.1.0rc1.dist-info}/RECORD +177 -168
  174. {qiskit-2.0.2.dist-info → qiskit-2.1.0rc1.dist-info}/entry_points.txt +6 -0
  175. qiskit/synthesis/discrete_basis/commutator_decompose.py +0 -265
  176. qiskit/synthesis/discrete_basis/gate_sequence.py +0 -421
  177. {qiskit-2.0.2.dist-info → qiskit-2.1.0rc1.dist-info}/WHEEL +0 -0
  178. {qiskit-2.0.2.dist-info → qiskit-2.1.0rc1.dist-info}/licenses/LICENSE.txt +0 -0
  179. {qiskit-2.0.2.dist-info → qiskit-2.1.0rc1.dist-info}/top_level.txt +0 -0
@@ -5,6 +5,7 @@ FullAdder.ripple_v95 = qiskit.transpiler.passes.synthesis.hls_plugins:FullAdderS
5
5
  HalfAdder.default = qiskit.transpiler.passes.synthesis.hls_plugins:HalfAdderSynthesisDefault
6
6
  HalfAdder.qft_d00 = qiskit.transpiler.passes.synthesis.hls_plugins:HalfAdderSynthesisD00
7
7
  HalfAdder.ripple_c04 = qiskit.transpiler.passes.synthesis.hls_plugins:HalfAdderSynthesisC04
8
+ HalfAdder.ripple_r25 = qiskit.transpiler.passes.synthesis.hls_plugins:HalfAdderSynthesisR25
8
9
  HalfAdder.ripple_v95 = qiskit.transpiler.passes.synthesis.hls_plugins:HalfAdderSynthesisV95
9
10
  IntComp.default = qiskit.transpiler.passes.synthesis.hls_plugins:IntComparatorSynthesisDefault
10
11
  IntComp.noaux = qiskit.transpiler.passes.synthesis.hls_plugins:IntComparatorSynthesisNoAux
@@ -33,6 +34,10 @@ mcmt.default = qiskit.transpiler.passes.synthesis.hls_plugins:MCMTSynthesisDefau
33
34
  mcmt.noaux = qiskit.transpiler.passes.synthesis.hls_plugins:MCMTSynthesisNoAux
34
35
  mcmt.vchain = qiskit.transpiler.passes.synthesis.hls_plugins:MCMTSynthesisVChain
35
36
  mcx.1_clean_b95 = qiskit.transpiler.passes.synthesis.hls_plugins:MCXSynthesis1CleanB95
37
+ mcx.1_clean_kg24 = qiskit.transpiler.passes.synthesis.hls_plugins:MCXSynthesis1CleanKG24
38
+ mcx.1_dirty_kg24 = qiskit.transpiler.passes.synthesis.hls_plugins:MCXSynthesis1DirtyKG24
39
+ mcx.2_clean_kg24 = qiskit.transpiler.passes.synthesis.hls_plugins:MCXSynthesis2CleanKG24
40
+ mcx.2_dirty_kg24 = qiskit.transpiler.passes.synthesis.hls_plugins:MCXSynthesis2DirtyKG24
36
41
  mcx.default = qiskit.transpiler.passes.synthesis.hls_plugins:MCXSynthesisDefault
37
42
  mcx.gray_code = qiskit.transpiler.passes.synthesis.hls_plugins:MCXSynthesisGrayCode
38
43
  mcx.n_clean_m15 = qiskit.transpiler.passes.synthesis.hls_plugins:MCXSynthesisNCleanM15
@@ -78,5 +83,6 @@ translator = qiskit.transpiler.preset_passmanagers.builtin_plugins:BasisTranslat
78
83
 
79
84
  [qiskit.unitary_synthesis]
80
85
  aqc = qiskit.transpiler.passes.synthesis.aqc_plugin:AQCSynthesisPlugin
86
+ clifford = qiskit.transpiler.passes.synthesis.clifford_unitary_synth_plugin:CliffordUnitarySynthesis
81
87
  default = qiskit.transpiler.passes.synthesis.default_unitary_synth_plugin:DefaultUnitarySynthesis
82
88
  sk = qiskit.transpiler.passes.synthesis.solovay_kitaev_synthesis:SolovayKitaevSynthesis
@@ -1,265 +0,0 @@
1
- # This code is part of Qiskit.
2
- #
3
- # (C) Copyright IBM 2017, 2022.
4
- #
5
- # This code is licensed under the Apache License, Version 2.0. You may
6
- # obtain a copy of this license in the LICENSE.txt file in the root directory
7
- # of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
8
- #
9
- # Any modifications or derivative works of this code must retain this
10
- # copyright notice, and modified files need to carry a notice indicating
11
- # that they have been altered from the originals.
12
-
13
- """Functions to compute the decomposition of an SO(3) matrix as balanced commutator."""
14
-
15
- from __future__ import annotations
16
-
17
- import math
18
- import numpy as np
19
- from qiskit.quantum_info.operators.predicates import is_identity_matrix
20
- from .gate_sequence import _check_is_so3, GateSequence
21
-
22
-
23
- def _compute_trace_so3(matrix: np.ndarray) -> float:
24
- """Computes trace of an SO(3)-matrix.
25
-
26
- Args:
27
- matrix: an SO(3)-matrix
28
-
29
- Returns:
30
- Trace of ``matrix``.
31
-
32
- Raises:
33
- ValueError: if ``matrix`` is not an SO(3)-matrix.
34
- """
35
- _check_is_so3(matrix)
36
-
37
- trace = np.matrix.trace(matrix)
38
- trace_rounded = min(trace, 3)
39
- return trace_rounded
40
-
41
-
42
- def _compute_rotation_axis(matrix: np.ndarray) -> np.ndarray:
43
- """Computes rotation axis of SO(3)-matrix.
44
-
45
- Args:
46
- matrix: The SO(3)-matrix for which rotation angle needs to be computed.
47
-
48
- Returns:
49
- The rotation axis of the SO(3)-matrix ``matrix``.
50
-
51
- Raises:
52
- ValueError: if ``matrix`` is not an SO(3)-matrix.
53
- """
54
- _check_is_so3(matrix)
55
-
56
- # If theta represents the rotation angle, then trace = 1 + 2cos(theta).
57
- trace = _compute_trace_so3(matrix)
58
-
59
- if trace >= 3 - 1e-10:
60
- # The matrix is the identity (rotation by 0)
61
- x = 1.0
62
- y = 0.0
63
- z = 0.0
64
-
65
- elif trace <= -1 + 1e-10:
66
- # The matrix is the 180-degree rotation
67
- squares = (1 + np.diagonal(matrix)) / 2
68
- index_of_max = np.argmax(squares)
69
-
70
- if index_of_max == 0:
71
- x = math.sqrt(squares[0])
72
- y = matrix[0][1] / (2 * x)
73
- z = matrix[0][2] / (2 * x)
74
- elif index_of_max == 1:
75
- y = math.sqrt(squares[1])
76
- x = matrix[0][1] / (2 * y)
77
- z = matrix[1][2] / (2 * y)
78
- else:
79
- z = math.sqrt(squares[2])
80
- x = matrix[0][2] / (2 * z)
81
- y = matrix[1][2] / (2 * z)
82
-
83
- else:
84
- # The matrix is the rotation by theta with sin(theta)!=0
85
- theta = math.acos(0.5 * (trace - 1))
86
- x = 1 / (2 * math.sin(theta)) * (matrix[2][1] - matrix[1][2])
87
- y = 1 / (2 * math.sin(theta)) * (matrix[0][2] - matrix[2][0])
88
- z = 1 / (2 * math.sin(theta)) * (matrix[1][0] - matrix[0][1])
89
-
90
- return np.array([x, y, z])
91
-
92
-
93
- def _solve_decomposition_angle(matrix: np.ndarray) -> float:
94
- """Computes angle for balanced commutator of SO(3)-matrix ``matrix``.
95
-
96
- Computes angle a so that the SO(3)-matrix ``matrix`` can be decomposed
97
- as commutator [v,w] where v and w are both rotations of a about some axis.
98
- The computation is done by solving a trigonometric equation using scipy.optimize.fsolve.
99
-
100
- Args:
101
- matrix: The SO(3)-matrix for which the decomposition angle needs to be computed.
102
-
103
- Returns:
104
- Angle a so that matrix = [v,w] with v and w rotations of a about some axis.
105
-
106
- Raises:
107
- ValueError: if ``matrix`` is not an SO(3)-matrix.
108
- """
109
- from scipy.optimize import fsolve
110
-
111
- _check_is_so3(matrix)
112
-
113
- trace = _compute_trace_so3(matrix)
114
- angle = math.acos((1 / 2) * (trace - 1))
115
-
116
- lhs = math.sin(angle / 2)
117
-
118
- def objective(phi):
119
- sin_sq = math.sin(phi.item() / 2) ** 2
120
- return 2 * sin_sq * math.sqrt(1 - sin_sq**2) - lhs
121
-
122
- decomposition_angle = fsolve(objective, angle)[0]
123
- return decomposition_angle
124
-
125
-
126
- def _compute_rotation_from_angle_and_axis(angle: float, axis: np.ndarray) -> np.ndarray:
127
- """Computes the SO(3)-matrix corresponding to the rotation of ``angle`` about ``axis``.
128
-
129
- Args:
130
- angle: The angle of the rotation.
131
- axis: The axis of the rotation.
132
-
133
- Returns:
134
- SO(3)-matrix that represents a rotation of ``angle`` about ``axis``.
135
-
136
- Raises:
137
- ValueError: if ``axis`` is not a 3-dim unit vector.
138
- """
139
- if axis.shape != (3,):
140
- raise ValueError(f"Axis must be a 1d array of length 3, but has shape {axis.shape}.")
141
-
142
- if abs(np.linalg.norm(axis) - 1.0) > 1e-4:
143
- raise ValueError(f"Axis must have a norm of 1, but has {np.linalg.norm(axis)}.")
144
-
145
- res = math.cos(angle) * np.identity(3) + math.sin(angle) * _cross_product_matrix(axis)
146
- res += (1 - math.cos(angle)) * np.outer(axis, axis)
147
- return res
148
-
149
-
150
- def _compute_rotation_between(from_vector: np.ndarray, to_vector: np.ndarray) -> np.ndarray:
151
- """Computes the SO(3)-matrix for rotating ``from_vector`` to ``to_vector``.
152
-
153
- Args:
154
- from_vector: unit vector of size 3
155
- to_vector: unit vector of size 3
156
-
157
- Returns:
158
- SO(3)-matrix that brings ``from_vector`` to ``to_vector``.
159
-
160
- Raises:
161
- ValueError: if at least one of ``from_vector`` of ``to_vector`` is not a 3-dim unit vector.
162
- """
163
- from_vector = from_vector / np.linalg.norm(from_vector)
164
- to_vector = to_vector / np.linalg.norm(to_vector)
165
-
166
- dot = np.dot(from_vector, to_vector)
167
- cross = _cross_product_matrix(np.cross(from_vector, to_vector))
168
- rotation_matrix = np.identity(3) + cross + np.dot(cross, cross) / (1 + dot)
169
- return rotation_matrix
170
-
171
-
172
- def _cross_product_matrix(v: np.ndarray) -> np.ndarray:
173
- """Computes cross product matrix from vector.
174
-
175
- Args:
176
- v: Vector for which cross product matrix needs to be computed.
177
-
178
- Returns:
179
- The cross product matrix corresponding to vector ``v``.
180
- """
181
- return np.array([[0, -v[2], v[1]], [v[2], 0, -v[0]], [-v[1], v[0], 0]])
182
-
183
-
184
- def _compute_commutator_so3(a: np.ndarray, b: np.ndarray) -> np.ndarray:
185
- """Computes the commutator of the SO(3)-matrices ``a`` and ``b``.
186
-
187
- The computation uses the fact that the inverse of an SO(3)-matrix is equal to its transpose.
188
-
189
- Args:
190
- a: SO(3)-matrix
191
- b: SO(3)-matrix
192
-
193
- Returns:
194
- The commutator [a,b] of ``a`` and ``b`` w
195
-
196
- Raises:
197
- ValueError: if at least one of ``a`` or ``b`` is not an SO(3)-matrix.
198
- """
199
- _check_is_so3(a)
200
- _check_is_so3(b)
201
-
202
- a_dagger = np.conj(a).T
203
- b_dagger = np.conj(b).T
204
-
205
- return np.dot(np.dot(np.dot(a, b), a_dagger), b_dagger)
206
-
207
-
208
- def commutator_decompose(
209
- u_so3: np.ndarray, check_input: bool = True
210
- ) -> tuple[GateSequence, GateSequence]:
211
- r"""Decompose an :math:`SO(3)`-matrix, :math:`U` as a balanced commutator.
212
-
213
- This function finds two :math:`SO(3)` matrices :math:`V, W` such that the input matrix
214
- equals
215
-
216
- .. math::
217
-
218
- U = V^\dagger W^\dagger V W.
219
-
220
- For this decomposition, the following statement holds
221
-
222
-
223
- .. math::
224
-
225
- ||V - I||_F, ||W - I||_F \leq \frac{\sqrt{||U - I||_F}}{2},
226
-
227
- where :math:`I` is the identity and :math:`||\cdot ||_F` is the Frobenius norm.
228
-
229
- Args:
230
- u_so3: SO(3)-matrix that needs to be decomposed as balanced commutator.
231
- check_input: If True, checks whether the input matrix is actually SO(3).
232
-
233
- Returns:
234
- Tuple of GateSequences from SO(3)-matrices :math:`V, W`.
235
-
236
- Raises:
237
- ValueError: if ``u_so3`` is not an SO(3)-matrix.
238
- """
239
- if check_input:
240
- # assert that the input matrix is really SO(3)
241
- _check_is_so3(u_so3)
242
-
243
- if not is_identity_matrix(u_so3.dot(u_so3.T)):
244
- raise ValueError("Input matrix is not orthogonal.")
245
-
246
- angle = _solve_decomposition_angle(u_so3)
247
-
248
- # Compute rotation about x-axis with angle 'angle'
249
- vx = _compute_rotation_from_angle_and_axis(angle, np.array([1, 0, 0]))
250
-
251
- # Compute rotation about y-axis with angle 'angle'
252
- wy = _compute_rotation_from_angle_and_axis(angle, np.array([0, 1, 0]))
253
-
254
- commutator = _compute_commutator_so3(vx, wy)
255
-
256
- u_so3_axis = _compute_rotation_axis(u_so3)
257
- commutator_axis = _compute_rotation_axis(commutator)
258
-
259
- sim_matrix = _compute_rotation_between(commutator_axis, u_so3_axis)
260
- sim_matrix_dagger = np.conj(sim_matrix).T
261
-
262
- v = np.dot(np.dot(sim_matrix, vx), sim_matrix_dagger)
263
- w = np.dot(np.dot(sim_matrix, wy), sim_matrix_dagger)
264
-
265
- return GateSequence.from_matrix(v), GateSequence.from_matrix(w)