qiskit 1.0.2__cp38-abi3-win32.whl → 1.1.0__cp38-abi3-win32.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 (263) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +27 -16
  3. qiskit/_accelerate.pyd +0 -0
  4. qiskit/_numpy_compat.py +73 -0
  5. qiskit/assembler/__init__.py +5 -10
  6. qiskit/assembler/disassemble.py +5 -6
  7. qiskit/circuit/__init__.py +1061 -232
  8. qiskit/circuit/_classical_resource_map.py +10 -6
  9. qiskit/circuit/_utils.py +18 -8
  10. qiskit/circuit/annotated_operation.py +21 -0
  11. qiskit/circuit/barrier.py +10 -13
  12. qiskit/circuit/bit.py +0 -1
  13. qiskit/circuit/classical/__init__.py +2 -2
  14. qiskit/circuit/classical/expr/__init__.py +39 -5
  15. qiskit/circuit/classical/expr/constructors.py +84 -1
  16. qiskit/circuit/classical/expr/expr.py +83 -13
  17. qiskit/circuit/classical/expr/visitors.py +83 -0
  18. qiskit/circuit/classical/types/__init__.py +5 -4
  19. qiskit/circuit/classicalfunction/__init__.py +1 -0
  20. qiskit/circuit/commutation_checker.py +86 -51
  21. qiskit/circuit/controlflow/_builder_utils.py +9 -1
  22. qiskit/circuit/controlflow/break_loop.py +8 -22
  23. qiskit/circuit/controlflow/builder.py +116 -1
  24. qiskit/circuit/controlflow/continue_loop.py +8 -22
  25. qiskit/circuit/controlflow/control_flow.py +47 -8
  26. qiskit/circuit/controlflow/for_loop.py +8 -23
  27. qiskit/circuit/controlflow/if_else.py +13 -27
  28. qiskit/circuit/controlflow/switch_case.py +14 -21
  29. qiskit/circuit/controlflow/while_loop.py +9 -23
  30. qiskit/circuit/controlledgate.py +2 -2
  31. qiskit/circuit/delay.py +7 -5
  32. qiskit/circuit/gate.py +20 -7
  33. qiskit/circuit/instruction.py +31 -30
  34. qiskit/circuit/instructionset.py +9 -22
  35. qiskit/circuit/library/__init__.py +3 -13
  36. qiskit/circuit/library/arithmetic/integer_comparator.py +2 -2
  37. qiskit/circuit/library/arithmetic/quadratic_form.py +3 -2
  38. qiskit/circuit/library/blueprintcircuit.py +29 -7
  39. qiskit/circuit/library/data_preparation/state_preparation.py +6 -5
  40. qiskit/circuit/library/generalized_gates/diagonal.py +5 -4
  41. qiskit/circuit/library/generalized_gates/isometry.py +51 -254
  42. qiskit/circuit/library/generalized_gates/pauli.py +2 -2
  43. qiskit/circuit/library/generalized_gates/permutation.py +4 -1
  44. qiskit/circuit/library/generalized_gates/rv.py +15 -11
  45. qiskit/circuit/library/generalized_gates/uc.py +2 -98
  46. qiskit/circuit/library/generalized_gates/unitary.py +9 -4
  47. qiskit/circuit/library/hamiltonian_gate.py +11 -5
  48. qiskit/circuit/library/n_local/efficient_su2.py +5 -5
  49. qiskit/circuit/library/n_local/n_local.py +100 -49
  50. qiskit/circuit/library/n_local/two_local.py +3 -59
  51. qiskit/circuit/library/overlap.py +3 -3
  52. qiskit/circuit/library/phase_oracle.py +1 -1
  53. qiskit/circuit/library/quantum_volume.py +39 -38
  54. qiskit/circuit/library/standard_gates/equivalence_library.py +50 -0
  55. qiskit/circuit/library/standard_gates/global_phase.py +4 -2
  56. qiskit/circuit/library/standard_gates/i.py +1 -2
  57. qiskit/circuit/library/standard_gates/iswap.py +1 -2
  58. qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +11 -5
  59. qiskit/circuit/library/standard_gates/p.py +31 -15
  60. qiskit/circuit/library/standard_gates/r.py +4 -3
  61. qiskit/circuit/library/standard_gates/rx.py +7 -4
  62. qiskit/circuit/library/standard_gates/rxx.py +4 -3
  63. qiskit/circuit/library/standard_gates/ry.py +7 -4
  64. qiskit/circuit/library/standard_gates/ryy.py +4 -3
  65. qiskit/circuit/library/standard_gates/rz.py +7 -4
  66. qiskit/circuit/library/standard_gates/rzx.py +4 -3
  67. qiskit/circuit/library/standard_gates/rzz.py +4 -3
  68. qiskit/circuit/library/standard_gates/s.py +4 -8
  69. qiskit/circuit/library/standard_gates/t.py +2 -4
  70. qiskit/circuit/library/standard_gates/u.py +16 -11
  71. qiskit/circuit/library/standard_gates/u1.py +6 -2
  72. qiskit/circuit/library/standard_gates/u2.py +4 -2
  73. qiskit/circuit/library/standard_gates/u3.py +9 -5
  74. qiskit/circuit/library/standard_gates/x.py +22 -11
  75. qiskit/circuit/library/standard_gates/xx_minus_yy.py +4 -3
  76. qiskit/circuit/library/standard_gates/xx_plus_yy.py +7 -5
  77. qiskit/circuit/library/standard_gates/z.py +1 -2
  78. qiskit/circuit/measure.py +4 -1
  79. qiskit/circuit/operation.py +13 -8
  80. qiskit/circuit/parameter.py +11 -6
  81. qiskit/circuit/quantumcircuit.py +1910 -260
  82. qiskit/circuit/quantumcircuitdata.py +2 -2
  83. qiskit/circuit/reset.py +5 -2
  84. qiskit/circuit/store.py +95 -0
  85. qiskit/compiler/assembler.py +22 -22
  86. qiskit/compiler/transpiler.py +63 -112
  87. qiskit/converters/__init__.py +17 -2
  88. qiskit/converters/circuit_to_dag.py +7 -0
  89. qiskit/converters/circuit_to_dagdependency_v2.py +47 -0
  90. qiskit/converters/circuit_to_gate.py +2 -0
  91. qiskit/converters/circuit_to_instruction.py +22 -0
  92. qiskit/converters/dag_to_circuit.py +4 -0
  93. qiskit/converters/dag_to_dagdependency_v2.py +44 -0
  94. qiskit/dagcircuit/collect_blocks.py +15 -10
  95. qiskit/dagcircuit/dagcircuit.py +434 -124
  96. qiskit/dagcircuit/dagdependency.py +19 -12
  97. qiskit/dagcircuit/dagdependency_v2.py +641 -0
  98. qiskit/dagcircuit/dagdepnode.py +19 -16
  99. qiskit/dagcircuit/dagnode.py +14 -4
  100. qiskit/passmanager/passmanager.py +11 -11
  101. qiskit/primitives/__init__.py +22 -12
  102. qiskit/primitives/backend_estimator.py +3 -5
  103. qiskit/primitives/backend_estimator_v2.py +410 -0
  104. qiskit/primitives/backend_sampler_v2.py +287 -0
  105. qiskit/primitives/base/base_estimator.py +4 -9
  106. qiskit/primitives/base/base_sampler.py +2 -2
  107. qiskit/primitives/containers/__init__.py +6 -4
  108. qiskit/primitives/containers/bit_array.py +293 -2
  109. qiskit/primitives/containers/data_bin.py +123 -50
  110. qiskit/primitives/containers/estimator_pub.py +10 -3
  111. qiskit/primitives/containers/observables_array.py +2 -2
  112. qiskit/primitives/containers/pub_result.py +1 -1
  113. qiskit/primitives/containers/sampler_pub.py +19 -3
  114. qiskit/primitives/containers/sampler_pub_result.py +74 -0
  115. qiskit/primitives/containers/shape.py +4 -4
  116. qiskit/primitives/statevector_estimator.py +4 -4
  117. qiskit/primitives/statevector_sampler.py +7 -12
  118. qiskit/providers/__init__.py +65 -34
  119. qiskit/providers/backend.py +2 -2
  120. qiskit/providers/backend_compat.py +8 -10
  121. qiskit/providers/basic_provider/__init__.py +2 -23
  122. qiskit/providers/basic_provider/basic_provider_tools.py +67 -31
  123. qiskit/providers/basic_provider/basic_simulator.py +81 -21
  124. qiskit/providers/fake_provider/__init__.py +1 -1
  125. qiskit/providers/fake_provider/fake_1q.py +1 -1
  126. qiskit/providers/fake_provider/fake_backend.py +3 -408
  127. qiskit/providers/fake_provider/generic_backend_v2.py +26 -14
  128. qiskit/providers/models/__init__.py +2 -2
  129. qiskit/providers/provider.py +16 -0
  130. qiskit/pulse/builder.py +4 -1
  131. qiskit/pulse/parameter_manager.py +60 -4
  132. qiskit/pulse/schedule.py +29 -13
  133. qiskit/pulse/utils.py +61 -20
  134. qiskit/qasm2/__init__.py +1 -5
  135. qiskit/qasm2/parse.py +1 -4
  136. qiskit/qasm3/__init__.py +42 -5
  137. qiskit/qasm3/ast.py +19 -0
  138. qiskit/qasm3/exporter.py +178 -106
  139. qiskit/qasm3/printer.py +27 -5
  140. qiskit/qobj/converters/pulse_instruction.py +6 -6
  141. qiskit/qpy/__init__.py +299 -67
  142. qiskit/qpy/binary_io/circuits.py +216 -47
  143. qiskit/qpy/binary_io/schedules.py +42 -36
  144. qiskit/qpy/binary_io/value.py +201 -22
  145. qiskit/qpy/common.py +1 -1
  146. qiskit/qpy/exceptions.py +20 -0
  147. qiskit/qpy/formats.py +29 -0
  148. qiskit/qpy/type_keys.py +21 -0
  149. qiskit/quantum_info/analysis/distance.py +3 -3
  150. qiskit/quantum_info/analysis/make_observable.py +2 -1
  151. qiskit/quantum_info/analysis/z2_symmetries.py +2 -1
  152. qiskit/quantum_info/operators/channel/chi.py +9 -8
  153. qiskit/quantum_info/operators/channel/choi.py +10 -9
  154. qiskit/quantum_info/operators/channel/kraus.py +2 -1
  155. qiskit/quantum_info/operators/channel/ptm.py +10 -9
  156. qiskit/quantum_info/operators/channel/quantum_channel.py +2 -1
  157. qiskit/quantum_info/operators/channel/stinespring.py +2 -1
  158. qiskit/quantum_info/operators/channel/superop.py +12 -11
  159. qiskit/quantum_info/operators/channel/transformations.py +12 -11
  160. qiskit/quantum_info/operators/dihedral/dihedral.py +5 -4
  161. qiskit/quantum_info/operators/operator.py +43 -30
  162. qiskit/quantum_info/operators/scalar_op.py +10 -9
  163. qiskit/quantum_info/operators/symplectic/base_pauli.py +70 -59
  164. qiskit/quantum_info/operators/symplectic/clifford.py +36 -9
  165. qiskit/quantum_info/operators/symplectic/pauli.py +53 -6
  166. qiskit/quantum_info/operators/symplectic/pauli_list.py +36 -14
  167. qiskit/quantum_info/operators/symplectic/random.py +3 -2
  168. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +61 -36
  169. qiskit/quantum_info/states/densitymatrix.py +13 -13
  170. qiskit/quantum_info/states/stabilizerstate.py +3 -3
  171. qiskit/quantum_info/states/statevector.py +14 -13
  172. qiskit/quantum_info/states/utils.py +5 -3
  173. qiskit/result/__init__.py +6 -0
  174. qiskit/result/mitigation/correlated_readout_mitigator.py +3 -2
  175. qiskit/result/mitigation/local_readout_mitigator.py +2 -1
  176. qiskit/result/mitigation/utils.py +3 -2
  177. qiskit/scheduler/__init__.py +10 -1
  178. qiskit/scheduler/methods/__init__.py +1 -8
  179. qiskit/synthesis/__init__.py +3 -6
  180. qiskit/synthesis/discrete_basis/commutator_decompose.py +2 -2
  181. qiskit/synthesis/evolution/lie_trotter.py +7 -14
  182. qiskit/synthesis/evolution/qdrift.py +3 -4
  183. qiskit/synthesis/linear/cnot_synth.py +1 -3
  184. qiskit/synthesis/linear/linear_circuits_utils.py +1 -1
  185. qiskit/synthesis/linear_phase/cz_depth_lnn.py +4 -18
  186. qiskit/synthesis/permutation/__init__.py +1 -0
  187. qiskit/synthesis/permutation/permutation_reverse_lnn.py +90 -0
  188. qiskit/synthesis/qft/qft_decompose_lnn.py +2 -6
  189. qiskit/synthesis/two_qubit/two_qubit_decompose.py +165 -954
  190. qiskit/synthesis/two_qubit/xx_decompose/circuits.py +13 -12
  191. qiskit/synthesis/two_qubit/xx_decompose/decomposer.py +7 -1
  192. qiskit/synthesis/unitary/aqc/__init__.py +1 -1
  193. qiskit/synthesis/unitary/aqc/cnot_structures.py +2 -1
  194. qiskit/synthesis/unitary/aqc/fast_gradient/fast_gradient.py +2 -1
  195. qiskit/synthesis/unitary/qsd.py +3 -2
  196. qiskit/transpiler/__init__.py +7 -3
  197. qiskit/transpiler/layout.py +140 -61
  198. qiskit/transpiler/passes/__init__.py +10 -2
  199. qiskit/transpiler/passes/basis/basis_translator.py +9 -4
  200. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -1
  201. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +1 -1
  202. qiskit/transpiler/passes/calibration/rzx_builder.py +2 -1
  203. qiskit/transpiler/passes/layout/apply_layout.py +8 -3
  204. qiskit/transpiler/passes/layout/sabre_layout.py +15 -3
  205. qiskit/transpiler/passes/layout/set_layout.py +1 -1
  206. qiskit/transpiler/passes/optimization/__init__.py +2 -0
  207. qiskit/transpiler/passes/optimization/commutation_analysis.py +2 -2
  208. qiskit/transpiler/passes/optimization/commutative_cancellation.py +1 -1
  209. qiskit/transpiler/passes/optimization/consolidate_blocks.py +1 -1
  210. qiskit/transpiler/passes/optimization/cx_cancellation.py +10 -0
  211. qiskit/transpiler/passes/optimization/elide_permutations.py +114 -0
  212. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +9 -3
  213. qiskit/transpiler/passes/optimization/optimize_annotated.py +248 -12
  214. qiskit/transpiler/passes/optimization/remove_final_reset.py +37 -0
  215. qiskit/transpiler/passes/optimization/template_matching/forward_match.py +1 -3
  216. qiskit/transpiler/passes/routing/__init__.py +1 -0
  217. qiskit/transpiler/passes/routing/basic_swap.py +13 -2
  218. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +8 -1
  219. qiskit/transpiler/passes/routing/lookahead_swap.py +7 -1
  220. qiskit/transpiler/passes/routing/sabre_swap.py +10 -6
  221. qiskit/transpiler/passes/routing/star_prerouting.py +417 -0
  222. qiskit/transpiler/passes/routing/stochastic_swap.py +24 -8
  223. qiskit/transpiler/passes/scheduling/__init__.py +1 -1
  224. qiskit/transpiler/passes/scheduling/alap.py +1 -2
  225. qiskit/transpiler/passes/scheduling/alignments/align_measures.py +1 -2
  226. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +9 -6
  227. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +8 -0
  228. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +13 -4
  229. qiskit/transpiler/passes/scheduling/asap.py +1 -2
  230. qiskit/transpiler/passes/scheduling/base_scheduler.py +21 -2
  231. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +26 -4
  232. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +24 -2
  233. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +28 -4
  234. qiskit/transpiler/passes/synthesis/aqc_plugin.py +2 -2
  235. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +120 -13
  236. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +162 -55
  237. qiskit/transpiler/passes/utils/gates_basis.py +3 -3
  238. qiskit/transpiler/passmanager.py +44 -1
  239. qiskit/transpiler/preset_passmanagers/__init__.py +3 -3
  240. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +34 -16
  241. qiskit/transpiler/preset_passmanagers/common.py +4 -6
  242. qiskit/transpiler/preset_passmanagers/plugin.py +9 -1
  243. qiskit/utils/__init__.py +3 -2
  244. qiskit/utils/optionals.py +6 -2
  245. qiskit/utils/parallel.py +24 -15
  246. qiskit/visualization/array.py +1 -1
  247. qiskit/visualization/bloch.py +2 -3
  248. qiskit/visualization/circuit/matplotlib.py +44 -14
  249. qiskit/visualization/circuit/text.py +38 -18
  250. qiskit/visualization/counts_visualization.py +3 -6
  251. qiskit/visualization/dag_visualization.py +6 -7
  252. qiskit/visualization/gate_map.py +9 -1
  253. qiskit/visualization/pulse_v2/interface.py +8 -3
  254. qiskit/visualization/state_visualization.py +3 -2
  255. qiskit/visualization/timeline/interface.py +18 -8
  256. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/METADATA +12 -8
  257. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/RECORD +261 -251
  258. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/WHEEL +1 -1
  259. qiskit/_qasm2.pyd +0 -0
  260. qiskit/_qasm3.pyd +0 -0
  261. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/LICENSE.txt +0 -0
  262. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/entry_points.txt +0 -0
  263. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/top_level.txt +0 -0
@@ -15,7 +15,7 @@
15
15
  from __future__ import annotations
16
16
  from abc import ABC, abstractmethod
17
17
 
18
- from qiskit._accelerate.quantum_circuit import CircuitData
18
+ from qiskit._accelerate.circuit import CircuitData
19
19
  from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
20
20
  from qiskit.circuit.parametertable import ParameterTable, ParameterView
21
21
 
@@ -127,10 +127,32 @@ class BlueprintCircuit(QuantumCircuit, ABC):
127
127
  self._build()
128
128
  return super()._append(instruction, _qargs, _cargs)
129
129
 
130
- def compose(self, other, qubits=None, clbits=None, front=False, inplace=False, wrap=False):
131
- if not self._is_built:
132
- self._build()
133
- return super().compose(other, qubits, clbits, front, inplace, wrap)
130
+ def compose(
131
+ self,
132
+ other,
133
+ qubits=None,
134
+ clbits=None,
135
+ front=False,
136
+ inplace=False,
137
+ wrap=False,
138
+ *,
139
+ copy=True,
140
+ var_remap=None,
141
+ inline_captures=False,
142
+ ):
143
+ if not self._is_built:
144
+ self._build()
145
+ return super().compose(
146
+ other,
147
+ qubits,
148
+ clbits,
149
+ front,
150
+ inplace,
151
+ wrap,
152
+ copy=copy,
153
+ var_remap=var_remap,
154
+ inline_captures=False,
155
+ )
134
156
 
135
157
  def inverse(self, annotated: bool = False):
136
158
  if not self._is_built:
@@ -178,10 +200,10 @@ class BlueprintCircuit(QuantumCircuit, ABC):
178
200
  self._build()
179
201
  return super().num_connected_components(unitary_only=unitary_only)
180
202
 
181
- def copy_empty_like(self, name=None):
203
+ def copy_empty_like(self, name=None, *, vars_mode="alike"):
182
204
  if not self._is_built:
183
205
  self._build()
184
- cpy = super().copy_empty_like(name=name)
206
+ cpy = super().copy_empty_like(name=name, vars_mode=vars_mode)
185
207
  # The base `copy_empty_like` will typically trigger code that `BlueprintCircuit` treats as
186
208
  # an "invalidation", so we have to manually restore properties deleted by that that
187
209
  # `copy_empty_like` is supposed to propagate.
@@ -11,6 +11,7 @@
11
11
  # that they have been altered from the originals.
12
12
  """Prepare a quantum state from the state where all qubits are 0."""
13
13
 
14
+ import cmath
14
15
  from typing import Union, Optional
15
16
 
16
17
  import math
@@ -339,20 +340,20 @@ class StatePreparation(Gate):
339
340
  a_complex = complex(a_complex)
340
341
  b_complex = complex(b_complex)
341
342
  mag_a = abs(a_complex)
342
- final_r = np.sqrt(mag_a**2 + np.absolute(b_complex) ** 2)
343
+ final_r = math.sqrt(mag_a**2 + abs(b_complex) ** 2)
343
344
  if final_r < _EPS:
344
345
  theta = 0
345
346
  phi = 0
346
347
  final_r = 0
347
348
  final_t = 0
348
349
  else:
349
- theta = 2 * np.arccos(mag_a / final_r)
350
- a_arg = np.angle(a_complex)
351
- b_arg = np.angle(b_complex)
350
+ theta = 2 * math.acos(mag_a / final_r)
351
+ a_arg = cmath.phase(a_complex)
352
+ b_arg = cmath.phase(b_complex)
352
353
  final_t = a_arg + b_arg
353
354
  phi = b_arg - a_arg
354
355
 
355
- return final_r * np.exp(1.0j * final_t / 2), theta, phi
356
+ return final_r * cmath.exp(1.0j * final_t / 2), theta, phi
356
357
 
357
358
  def _multiplex(self, target_gate, list_of_angles, last_cnot=True):
358
359
  """
@@ -17,6 +17,7 @@ from __future__ import annotations
17
17
  from collections.abc import Sequence
18
18
 
19
19
  import cmath
20
+ import math
20
21
  import numpy as np
21
22
 
22
23
  from qiskit.circuit.gate import Gate
@@ -87,7 +88,7 @@ class Diagonal(QuantumCircuit):
87
88
  number of qubits.
88
89
  """
89
90
  self._check_input(diag)
90
- num_qubits = int(np.log2(len(diag)))
91
+ num_qubits = int(math.log2(len(diag)))
91
92
 
92
93
  circuit = QuantumCircuit(num_qubits, name="Diagonal")
93
94
 
@@ -100,7 +101,7 @@ class Diagonal(QuantumCircuit):
100
101
  for i in range(0, n, 2):
101
102
  diag_phases[i // 2], rz_angle = _extract_rz(diag_phases[i], diag_phases[i + 1])
102
103
  angles_rz.append(rz_angle)
103
- num_act_qubits = int(np.log2(n))
104
+ num_act_qubits = int(math.log2(n))
104
105
  ctrl_qubits = list(range(num_qubits - num_act_qubits + 1, num_qubits))
105
106
  target_qubit = num_qubits - num_act_qubits
106
107
 
@@ -118,7 +119,7 @@ class Diagonal(QuantumCircuit):
118
119
  """Check if ``diag`` is in valid format."""
119
120
  if not isinstance(diag, (list, np.ndarray)):
120
121
  raise CircuitError("Diagonal entries must be in a list or numpy array.")
121
- num_qubits = np.log2(len(diag))
122
+ num_qubits = math.log2(len(diag))
122
123
  if num_qubits < 1 or not num_qubits.is_integer():
123
124
  raise CircuitError("The number of diagonal entries is not a positive power of 2.")
124
125
  if not np.allclose(np.abs(diag), 1, atol=_EPS):
@@ -134,7 +135,7 @@ class DiagonalGate(Gate):
134
135
  diag: list of the :math:`2^k` diagonal entries (for a diagonal gate on :math:`k` qubits).
135
136
  """
136
137
  Diagonal._check_input(diag)
137
- num_qubits = int(np.log2(len(diag)))
138
+ num_qubits = int(math.log2(len(diag)))
138
139
 
139
140
  super().__init__("diagonal", num_qubits, diag)
140
141
 
@@ -21,7 +21,7 @@ Generic isometries from m to n qubits.
21
21
 
22
22
  from __future__ import annotations
23
23
 
24
- import itertools
24
+ import math
25
25
  import numpy as np
26
26
  from qiskit.circuit.exceptions import CircuitError
27
27
  from qiskit.circuit.instruction import Instruction
@@ -29,6 +29,7 @@ from qiskit.circuit.quantumcircuit import QuantumCircuit
29
29
  from qiskit.circuit.quantumregister import QuantumRegister
30
30
  from qiskit.exceptions import QiskitError
31
31
  from qiskit.quantum_info.operators.predicates import is_isometry
32
+ from qiskit._accelerate import isometry as isometry_rs
32
33
 
33
34
  from .diagonal import Diagonal
34
35
  from .uc import UCGate
@@ -93,8 +94,8 @@ class Isometry(Instruction):
93
94
  self._epsilon = epsilon
94
95
 
95
96
  # Check if the isometry has the right dimension and if the columns are orthonormal
96
- n = np.log2(isometry.shape[0])
97
- m = np.log2(isometry.shape[1])
97
+ n = math.log2(isometry.shape[0])
98
+ m = math.log2(isometry.shape[1])
98
99
  if not n.is_integer() or n < 0:
99
100
  raise QiskitError(
100
101
  "The number of rows of the isometry is not a non negative power of 2."
@@ -150,18 +151,22 @@ class Isometry(Instruction):
150
151
  # to keep a copyof the input isometry)
151
152
  remaining_isometry = self.iso_data.astype(complex) # note: "astype" does copy the isometry
152
153
  diag = []
153
- m = int(np.log2((self.iso_data).shape[1]))
154
+ m = int(math.log2(self.iso_data.shape[1]))
154
155
  # Decompose the column with index column_index and attache the gate to the circuit object.
155
156
  # Return the isometry that is left to decompose, where the columns up to index column_index
156
157
  # correspond to the firstfew columns of the identity matrix up to diag, and hence we only
157
158
  # have to save a list containing them.
158
159
  for column_index in range(2**m):
159
- self._decompose_column(circuit, q, diag, remaining_isometry, column_index)
160
+ remaining_isometry, diag = self._decompose_column(
161
+ circuit, q, diag, remaining_isometry, column_index
162
+ )
160
163
  # extract phase of the state that was sent to the basis state ket(column_index)
161
164
  diag.append(remaining_isometry[column_index, 0])
162
165
  # remove first column (which is now stored in diag)
163
166
  remaining_isometry = remaining_isometry[:, 1:]
164
- if len(diag) > 1 and not _diag_is_identity_up_to_global_phase(diag, self._epsilon):
167
+ if len(diag) > 1 and not isometry_rs.diag_is_identity_up_to_global_phase(
168
+ diag, self._epsilon
169
+ ):
165
170
  diagonal = Diagonal(np.conj(diag))
166
171
  circuit.append(diagonal, q_input)
167
172
  return circuit
@@ -170,9 +175,12 @@ class Isometry(Instruction):
170
175
  """
171
176
  Decomposes the column with index column_index.
172
177
  """
173
- n = int(np.log2(self.iso_data.shape[0]))
178
+ n = int(math.log2(self.iso_data.shape[0]))
174
179
  for s in range(n):
175
- self._disentangle(circuit, q, diag, remaining_isometry, column_index, s)
180
+ remaining_isometry, diag = self._disentangle(
181
+ circuit, q, diag, remaining_isometry, column_index, s
182
+ )
183
+ return remaining_isometry, diag
176
184
 
177
185
  def _disentangle(self, circuit, q, diag, remaining_isometry, column_index, s):
178
186
  """
@@ -185,16 +193,22 @@ class Isometry(Instruction):
185
193
  # (note that we remove columns of the isometry during the procedure for efficiency)
186
194
  k_prime = 0
187
195
  v = remaining_isometry
188
- n = int(np.log2(self.iso_data.shape[0]))
196
+ n = int(math.log2(self.iso_data.shape[0]))
189
197
 
190
198
  # MCG to set one entry to zero (preparation for disentangling with UCGate):
191
- index1 = 2 * _a(k, s + 1) * 2**s + _b(k, s + 1)
192
- index2 = (2 * _a(k, s + 1) + 1) * 2**s + _b(k, s + 1)
199
+ index1 = 2 * isometry_rs.a(k, s + 1) * 2**s + isometry_rs.b(k, s + 1)
200
+ index2 = (2 * isometry_rs.a(k, s + 1) + 1) * 2**s + isometry_rs.b(k, s + 1)
193
201
  target_label = n - s - 1
194
202
  # Check if a MCG is required
195
- if _k_s(k, s) == 0 and _b(k, s + 1) != 0 and np.abs(v[index2, k_prime]) > self._epsilon:
203
+ if (
204
+ isometry_rs.k_s(k, s) == 0
205
+ and isometry_rs.b(k, s + 1) != 0
206
+ and np.abs(v[index2, k_prime]) > self._epsilon
207
+ ):
196
208
  # Find the MCG, decompose it and apply it to the remaining isometry
197
- gate = _reverse_qubit_state([v[index1, k_prime], v[index2, k_prime]], 0, self._epsilon)
209
+ gate = isometry_rs.reverse_qubit_state(
210
+ [v[index1, k_prime], v[index2, k_prime]], 0, self._epsilon
211
+ )
198
212
  control_labels = [
199
213
  i
200
214
  for i, x in enumerate(_get_binary_rep_as_list(k, n))
@@ -204,57 +218,49 @@ class Isometry(Instruction):
204
218
  circuit, q, gate, control_labels, target_label
205
219
  )
206
220
  # apply the MCG to the remaining isometry
207
- _apply_multi_controlled_gate(v, control_labels, target_label, gate)
221
+ v = isometry_rs.apply_multi_controlled_gate(v, control_labels, target_label, gate)
208
222
  # correct for the implementation "up to diagonal"
209
- diag_mcg_inverse = np.conj(diagonal_mcg).tolist()
210
- _apply_diagonal_gate(v, control_labels + [target_label], diag_mcg_inverse)
223
+ diag_mcg_inverse = np.conj(diagonal_mcg).astype(complex, copy=False)
224
+ v = isometry_rs.apply_diagonal_gate(
225
+ v, control_labels + [target_label], diag_mcg_inverse
226
+ )
211
227
  # update the diag according to the applied diagonal gate
212
- _apply_diagonal_gate_to_diag(diag, control_labels + [target_label], diag_mcg_inverse, n)
228
+ diag = isometry_rs.apply_diagonal_gate_to_diag(
229
+ diag, control_labels + [target_label], diag_mcg_inverse, n
230
+ )
213
231
 
214
232
  # UCGate to disentangle a qubit:
215
233
  # Find the UCGate, decompose it and apply it to the remaining isometry
216
234
  single_qubit_gates = self._find_squs_for_disentangling(v, k, s)
217
- if not _ucg_is_identity_up_to_global_phase(single_qubit_gates, self._epsilon):
235
+ if not isometry_rs.ucg_is_identity_up_to_global_phase(single_qubit_gates, self._epsilon):
218
236
  control_labels = list(range(target_label))
219
237
  diagonal_ucg = self._append_ucg_up_to_diagonal(
220
238
  circuit, q, single_qubit_gates, control_labels, target_label
221
239
  )
222
240
  # merge the diagonal into the UCGate for efficient application of both together
223
- diagonal_ucg_inverse = np.conj(diagonal_ucg).tolist()
224
- single_qubit_gates = _merge_UCGate_and_diag(single_qubit_gates, diagonal_ucg_inverse)
241
+ diagonal_ucg_inverse = np.conj(diagonal_ucg).astype(complex, copy=False)
242
+ single_qubit_gates = isometry_rs.merge_ucgate_and_diag(
243
+ single_qubit_gates, diagonal_ucg_inverse
244
+ )
225
245
  # apply the UCGate (with the merged diagonal gate) to the remaining isometry
226
- _apply_ucg(v, len(control_labels), single_qubit_gates)
246
+ v = isometry_rs.apply_ucg(v, len(control_labels), single_qubit_gates)
227
247
  # update the diag according to the applied diagonal gate
228
- _apply_diagonal_gate_to_diag(
248
+ diag = isometry_rs.apply_diagonal_gate_to_diag(
229
249
  diag, control_labels + [target_label], diagonal_ucg_inverse, n
230
250
  )
231
251
  # # correct for the implementation "up to diagonal"
232
252
  # diag_inv = np.conj(diag).tolist()
233
253
  # _apply_diagonal_gate(v, control_labels + [target_label], diag_inv)
254
+ return v, diag
234
255
 
235
256
  # This method finds the single-qubit gates for a UCGate to disentangle a qubit:
236
257
  # we consider the n-qubit state v[:,0] starting with k zeros (in the computational basis).
237
258
  # The qubit with label n-s-1 is disentangled into the basis state k_s(k,s).
238
259
  def _find_squs_for_disentangling(self, v, k, s):
239
- k_prime = 0
240
- n = int(np.log2(self.iso_data.shape[0]))
241
- if _b(k, s + 1) == 0:
242
- i_start = _a(k, s + 1)
243
- else:
244
- i_start = _a(k, s + 1) + 1
245
- id_list = [np.eye(2, 2) for _ in range(i_start)]
246
- squs = [
247
- _reverse_qubit_state(
248
- [
249
- v[2 * i * 2**s + _b(k, s), k_prime],
250
- v[(2 * i + 1) * 2**s + _b(k, s), k_prime],
251
- ],
252
- _k_s(k, s),
253
- self._epsilon,
254
- )
255
- for i in range(i_start, 2 ** (n - s - 1))
256
- ]
257
- return id_list + squs
260
+ res = isometry_rs.find_squs_for_disentangling(
261
+ v, k, s, self._epsilon, n=int(math.log2(self.iso_data.shape[0]))
262
+ )
263
+ return res
258
264
 
259
265
  # Append a UCGate up to diagonal to the circuit circ.
260
266
  def _append_ucg_up_to_diagonal(self, circ, q, single_qubit_gates, control_labels, target_label):
@@ -264,7 +270,7 @@ class Isometry(Instruction):
264
270
  q_ancillas_zero,
265
271
  q_ancillas_dirty,
266
272
  ) = self._define_qubit_role(q)
267
- n = int(np.log2(self.iso_data.shape[0]))
273
+ n = int(math.log2(self.iso_data.shape[0]))
268
274
  qubits = q_input + q_ancillas_for_output
269
275
  # Note that we have to reverse the control labels, since controls are provided by
270
276
  # increasing qubit number toa UCGate by convention
@@ -286,7 +292,7 @@ class Isometry(Instruction):
286
292
  q_ancillas_zero,
287
293
  q_ancillas_dirty,
288
294
  ) = self._define_qubit_role(q)
289
- n = int(np.log2(self.iso_data.shape[0]))
295
+ n = int(math.log2(self.iso_data.shape[0]))
290
296
  qubits = q_input + q_ancillas_for_output
291
297
  control_qubits = _reverse_qubit_oder(_get_qubits_by_label(control_labels, qubits, n))
292
298
  target_qubit = _get_qubits_by_label([target_label], qubits, n)[0]
@@ -307,8 +313,8 @@ class Isometry(Instruction):
307
313
 
308
314
  def _define_qubit_role(self, q):
309
315
 
310
- n = int(np.log2(self.iso_data.shape[0]))
311
- m = int(np.log2(self.iso_data.shape[1]))
316
+ n = int(math.log2(self.iso_data.shape[0]))
317
+ m = int(math.log2(self.iso_data.shape[1]))
312
318
 
313
319
  # Define the role of the qubits
314
320
  q_input = q[:m]
@@ -337,146 +343,6 @@ class Isometry(Instruction):
337
343
  return self._inverse
338
344
 
339
345
 
340
- # Find special unitary matrix that maps [c0,c1] to [r,0] or [0,r] if basis_state=0 or
341
- # basis_state=1 respectively
342
- def _reverse_qubit_state(state, basis_state, epsilon):
343
- state = np.array(state)
344
- r = np.linalg.norm(state)
345
- if r < epsilon:
346
- return np.eye(2, 2)
347
- if basis_state == 0:
348
- m = np.array([[np.conj(state[0]), np.conj(state[1])], [-state[1], state[0]]]) / r
349
- else:
350
- m = np.array([[-state[1], state[0]], [np.conj(state[0]), np.conj(state[1])]]) / r
351
- return m
352
-
353
-
354
- # Methods for applying gates to matrices (should be moved to Qiskit AER)
355
-
356
- # Input: matrix m with 2^n rows (and arbitrary many columns). Think of the columns as states
357
- # on n qubits. The method applies a uniformly controlled gate (UCGate) to all the columns, where
358
- # the UCGate is specified by the inputs k and single_qubit_gates:
359
-
360
- # k = number of controls. We assume that the controls are on the k most significant qubits
361
- # (and the target is on the (k+1)th significant qubit)
362
- # single_qubit_gates = [u_0,...,u_{2^k-1}], where the u_i's are 2*2 unitaries
363
- # (provided as numpy arrays)
364
-
365
- # The order of the single-qubit unitaries is such that the first unitary u_0 is applied to the
366
- # (k+1)th significant qubit if the control qubits are in the state ket(0...00), the gate u_1 is
367
- # applied if the control qubits are in the state ket(0...01), and so on.
368
-
369
- # The input matrix m and the single-qubit gates have to be of dtype=complex.
370
-
371
-
372
- def _apply_ucg(m, k, single_qubit_gates):
373
- # ToDo: Improve efficiency by parallelizing the gate application. A generalized version of
374
- # ToDo: this method should be implemented by the state vector simulator in Qiskit AER.
375
- num_qubits = int(np.log2(m.shape[0]))
376
- num_col = m.shape[1]
377
- spacing = 2 ** (num_qubits - k - 1)
378
- for j in range(2 ** (num_qubits - 1)):
379
- i = (j // spacing) * spacing + j
380
- gate_index = i // (2 ** (num_qubits - k))
381
- for col in range(num_col):
382
- m[np.array([i, i + spacing]), np.array([col, col])] = np.ndarray.flatten(
383
- single_qubit_gates[gate_index].dot(np.array([[m[i, col]], [m[i + spacing, col]]]))
384
- ).tolist()
385
- return m
386
-
387
-
388
- # Apply a diagonal gate with diagonal entries liste in diag and acting on qubits with labels
389
- # action_qubit_labels to a matrix m.
390
- # The input matrix m has to be of dtype=complex
391
- # The qubit labels are such that label 0 corresponds to the most significant qubit, label 1 to
392
- # the second most significant qubit, and so on ...
393
-
394
-
395
- def _apply_diagonal_gate(m, action_qubit_labels, diag):
396
- # ToDo: Improve efficiency by parallelizing the gate application. A generalized version of
397
- # ToDo: this method should be implemented by the state vector simulator in Qiskit AER.
398
- num_qubits = int(np.log2(m.shape[0]))
399
- num_cols = m.shape[1]
400
- basis_states = list(itertools.product([0, 1], repeat=num_qubits))
401
- for state in basis_states:
402
- state_on_action_qubits = [state[i] for i in action_qubit_labels]
403
- diag_index = _bin_to_int(state_on_action_qubits)
404
- i = _bin_to_int(state)
405
- for j in range(num_cols):
406
- m[i, j] = diag[diag_index] * m[i, j]
407
- return m
408
-
409
-
410
- # Special case of the method _apply_diagonal_gate, where the input m is a diagonal matrix on the
411
- # log2(len(m_diagonal)) least significant qubits (this method is more efficient in this case
412
- # than _apply_diagonal_gate). The input m_diagonal is provided as a list of diagonal entries.
413
- # The diagonal diag is applied on the qubits with labels listed in action_qubit_labels. The input
414
- # num_qubits gives the total number of considered qubits (this input is required to interpret the
415
- # action_qubit_labels in relation to the least significant qubits).
416
-
417
-
418
- def _apply_diagonal_gate_to_diag(m_diagonal, action_qubit_labels, diag, num_qubits):
419
- if not m_diagonal:
420
- return m_diagonal
421
- basis_states = list(itertools.product([0, 1], repeat=num_qubits))
422
- for state in basis_states[: len(m_diagonal)]:
423
- state_on_action_qubits = [state[i] for i in action_qubit_labels]
424
- diag_index = _bin_to_int(state_on_action_qubits)
425
- i = _bin_to_int(state)
426
- m_diagonal[i] *= diag[diag_index]
427
- return m_diagonal
428
-
429
-
430
- # Apply a MC single-qubit gate (given by the 2*2 unitary input: gate) with controlling on
431
- # the qubits with label control_labels and acting on the qubit with label target_label
432
- # to a matrix m. The input matrix m and the gate have to be of dtype=complex. The qubit labels are
433
- # such that label 0 corresponds to the most significant qubit, label 1 to the second most
434
- # significant qubit, and so on ...
435
-
436
-
437
- def _apply_multi_controlled_gate(m, control_labels, target_label, gate):
438
- # ToDo: This method should be integrated into the state vector simulator in Qiskit AER.
439
- num_qubits = int(np.log2(m.shape[0]))
440
- num_cols = m.shape[1]
441
- control_labels.sort()
442
- free_qubits = num_qubits - len(control_labels) - 1
443
- basis_states_free = list(itertools.product([0, 1], repeat=free_qubits))
444
- for state_free in basis_states_free:
445
- (e1, e2) = _construct_basis_states(state_free, control_labels, target_label)
446
- for i in range(num_cols):
447
- m[np.array([e1, e2]), np.array([i, i])] = np.ndarray.flatten(
448
- gate.dot(np.array([[m[e1, i]], [m[e2, i]]]))
449
- ).tolist()
450
- return m
451
-
452
-
453
- # Helper method for _apply_multi_controlled_gate. This constructs the basis states the MG gate
454
- # is acting on for a specific state state_free of the qubits we neither control nor act on.
455
-
456
-
457
- def _construct_basis_states(state_free, control_labels, target_label):
458
- e1 = []
459
- e2 = []
460
- j = 0
461
- for i in range(len(state_free) + len(control_labels) + 1):
462
- if i in control_labels:
463
- e1.append(1)
464
- e2.append(1)
465
- elif i == target_label:
466
- e1.append(0)
467
- e2.append(1)
468
- else:
469
- e1.append(state_free[j])
470
- e2.append(state_free[j])
471
- j += 1
472
- out1 = _bin_to_int(e1)
473
- out2 = _bin_to_int(e2)
474
- return out1, out2
475
-
476
-
477
- # Some helper methods:
478
-
479
-
480
346
  # Get the qubits in the list qubits corresponding to the labels listed in labels. The total number
481
347
  # of qubits is given by num_qubits (and determines the convention for the qubit labeling)
482
348
 
@@ -495,14 +361,6 @@ def _reverse_qubit_oder(qubits):
495
361
  # Convert list of binary digits to integer
496
362
 
497
363
 
498
- def _bin_to_int(binary_digits_as_list):
499
- return int("".join(str(x) for x in binary_digits_as_list), 2)
500
-
501
-
502
- def _ct(m):
503
- return np.transpose(np.conjugate(m))
504
-
505
-
506
364
  def _get_binary_rep_as_list(n, num_digits):
507
365
  binary_string = np.binary_repr(n).zfill(num_digits)
508
366
  binary = []
@@ -510,64 +368,3 @@ def _get_binary_rep_as_list(n, num_digits):
510
368
  for c in line:
511
369
  binary.append(int(c))
512
370
  return binary[-num_digits:]
513
-
514
-
515
- # absorb a diagonal gate into a UCGate
516
-
517
-
518
- def _merge_UCGate_and_diag(single_qubit_gates, diag):
519
- for i, gate in enumerate(single_qubit_gates):
520
- single_qubit_gates[i] = np.array([[diag[2 * i], 0.0], [0.0, diag[2 * i + 1]]]).dot(gate)
521
- return single_qubit_gates
522
-
523
-
524
- # Helper variables/functions for the column-by-column decomposition
525
-
526
-
527
- # a(k,s) and b(k,s) are positive integers such that k = a(k,s)2^s + b(k,s)
528
- # (with the maximal choice of a(k,s))
529
-
530
-
531
- def _a(k, s):
532
- return k // 2**s
533
-
534
-
535
- def _b(k, s):
536
- return k - (_a(k, s) * 2**s)
537
-
538
-
539
- # given a binary representation of k with binary digits [k_{n-1},..,k_1,k_0],
540
- # the method k_s(k, s) returns k_s
541
-
542
-
543
- def _k_s(k, s):
544
- if k == 0:
545
- return 0
546
- else:
547
- num_digits = s + 1
548
- return _get_binary_rep_as_list(k, num_digits)[0]
549
-
550
-
551
- # Check if a gate of a special form is equal to the identity gate up to global phase
552
-
553
-
554
- def _ucg_is_identity_up_to_global_phase(single_qubit_gates, epsilon):
555
- if not np.abs(single_qubit_gates[0][0, 0]) < epsilon:
556
- global_phase = 1.0 / (single_qubit_gates[0][0, 0])
557
- else:
558
- return False
559
- for gate in single_qubit_gates:
560
- if not np.allclose(global_phase * gate, np.eye(2, 2)):
561
- return False
562
- return True
563
-
564
-
565
- def _diag_is_identity_up_to_global_phase(diag, epsilon):
566
- if not np.abs(diag[0]) < epsilon:
567
- global_phase = 1.0 / (diag[0])
568
- else:
569
- return False
570
- for d in diag:
571
- if not np.abs(global_phase * d - 1) < epsilon:
572
- return False
573
- return True
@@ -63,13 +63,13 @@ class PauliGate(Gate):
63
63
  r"""Return inverted pauli gate (itself)."""
64
64
  return PauliGate(self.params[0]) # self-inverse
65
65
 
66
- def __array__(self, dtype=None):
66
+ def __array__(self, dtype=None, copy=None):
67
67
  """Return a Numpy.array for the pauli gate.
68
68
  i.e. tensor product of the paulis"""
69
69
  # pylint: disable=cyclic-import
70
70
  from qiskit.quantum_info.operators import Pauli
71
71
 
72
- return Pauli(self.params[0]).__array__(dtype=dtype)
72
+ return Pauli(self.params[0]).__array__(dtype=dtype, copy=copy)
73
73
 
74
74
  def validate_parameter(self, parameter):
75
75
  if isinstance(parameter, str):
@@ -147,8 +147,11 @@ class PermutationGate(Gate):
147
147
 
148
148
  super().__init__(name="permutation", num_qubits=num_qubits, params=[pattern])
149
149
 
150
- def __array__(self, dtype=None):
150
+ def __array__(self, dtype=None, copy=None):
151
151
  """Return a numpy.array for the Permutation gate."""
152
+ if copy is False:
153
+ raise ValueError("unable to avoid copy while creating an array as requested")
154
+
152
155
  nq = len(self.pattern)
153
156
  mat = np.zeros((2**nq, 2**nq), dtype=dtype)
154
157
 
@@ -12,13 +12,14 @@
12
12
 
13
13
  """Rotation around an arbitrary axis on the Bloch sphere."""
14
14
 
15
+ import math
15
16
  import numpy
16
17
  from qiskit.circuit.gate import Gate
17
18
  from qiskit.circuit.exceptions import CircuitError
18
19
 
19
20
 
20
21
  class RVGate(Gate):
21
- r"""Rotation around arbitrary rotation axis :math:`v` where :math:`|v|` is
22
+ r"""Rotation around arbitrary rotation axis :math:`\vec{v}` where :math:`\|\vec{v}\|_2` is
22
23
  angle of rotation in radians.
23
24
 
24
25
  Can be applied to a :class:`~qiskit.circuit.QuantumCircuit`
@@ -36,14 +37,17 @@ class RVGate(Gate):
36
37
 
37
38
  .. math::
38
39
 
39
- \newcommand{\rotationangle}{|\vec{v}|}
40
- \newcommand{\sinc}{\text{sinc}}
41
- R(\vec{v}) = e^{-i \vec{v}\cdot\vec{\sigma}} =
40
+ \newcommand{\rotationangle}{\frac{\|\vec{v}\|_2}{2}}
41
+ R(\vec{v}) = e^{-i \vec{v}\cdot\vec{\sigma} / 2} =
42
42
  \begin{pmatrix}
43
- \cos\left(\rotationangle\right) -i v_z \sinc\left(\rotationangle\right)
44
- & -(i v_x + v_y) \sinc\left(\rotationangle\right) \\
45
- -(i v_x - v_y) \sinc\left(\rotationangle\right)
46
- & \cos\left(\rotationangle\right) + i v_z \sinc\left(\rotationangle\right)
43
+ \cos\left(\rotationangle\right)
44
+ -i \frac{v_z}{\|\vec{v}\|_2} \sin\left(\rotationangle\right)
45
+ & -(i \frac{v_x}{\|\vec{v}\|_2}
46
+ + \frac{v_y}{\|\vec{v}\|_2}) \sin\left(\rotationangle\right) \\
47
+ -(i \frac{v_x}{\|\vec{v}\|_2}
48
+ - \frac{v_y}{\|\vec{v}\|_2}) \sin\left(\rotationangle\right)
49
+ & \cos\left(\rotationangle\right)
50
+ + i \frac{v_z}{\|\vec{v}\|_2} \sin\left(\rotationangle\right)
47
51
  \end{pmatrix}
48
52
  """
49
53
 
@@ -79,12 +83,12 @@ class RVGate(Gate):
79
83
  def to_matrix(self):
80
84
  """Return a numpy.array for the R(v) gate."""
81
85
  v = numpy.asarray(self.params, dtype=float)
82
- angle = numpy.sqrt(v.dot(v))
86
+ angle = math.sqrt(v.dot(v))
83
87
  if angle == 0:
84
88
  return numpy.array([[1, 0], [0, 1]])
85
89
  nx, ny, nz = v / angle
86
- sin = numpy.sin(angle / 2)
87
- cos = numpy.cos(angle / 2)
90
+ sin = math.sin(angle / 2)
91
+ cos = math.cos(angle / 2)
88
92
  return numpy.array(
89
93
  [
90
94
  [cos - 1j * nz * sin, (-ny - 1j * nx) * sin],