qiskit 1.0.0b1__cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.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.
- qiskit/VERSION.txt +1 -0
- qiskit/__init__.py +195 -0
- qiskit/_accelerate.abi3.so +0 -0
- qiskit/_qasm2.abi3.so +0 -0
- qiskit/assembler/__init__.py +47 -0
- qiskit/assembler/assemble_circuits.py +408 -0
- qiskit/assembler/assemble_schedules.py +372 -0
- qiskit/assembler/disassemble.py +318 -0
- qiskit/assembler/run_config.py +77 -0
- qiskit/circuit/__init__.py +425 -0
- qiskit/circuit/_classical_resource_map.py +144 -0
- qiskit/circuit/_utils.py +170 -0
- qiskit/circuit/add_control.py +274 -0
- qiskit/circuit/annotated_operation.py +188 -0
- qiskit/circuit/barrier.py +51 -0
- qiskit/circuit/bit.py +142 -0
- qiskit/circuit/classical/__init__.py +41 -0
- qiskit/circuit/classical/expr/__init__.py +218 -0
- qiskit/circuit/classical/expr/constructors.py +473 -0
- qiskit/circuit/classical/expr/expr.py +356 -0
- qiskit/circuit/classical/expr/visitors.py +280 -0
- qiskit/circuit/classical/types/__init__.py +108 -0
- qiskit/circuit/classical/types/ordering.py +222 -0
- qiskit/circuit/classical/types/types.py +117 -0
- qiskit/circuit/classicalfunction/__init__.py +131 -0
- qiskit/circuit/classicalfunction/boolean_expression.py +129 -0
- qiskit/circuit/classicalfunction/classical_element.py +54 -0
- qiskit/circuit/classicalfunction/classical_function_visitor.py +155 -0
- qiskit/circuit/classicalfunction/classicalfunction.py +173 -0
- qiskit/circuit/classicalfunction/exceptions.py +35 -0
- qiskit/circuit/classicalfunction/types.py +18 -0
- qiskit/circuit/classicalfunction/utils.py +91 -0
- qiskit/circuit/classicalregister.py +71 -0
- qiskit/circuit/commutation_checker.py +176 -0
- qiskit/circuit/controlflow/__init__.py +27 -0
- qiskit/circuit/controlflow/_builder_utils.py +199 -0
- qiskit/circuit/controlflow/break_loop.py +70 -0
- qiskit/circuit/controlflow/builder.py +651 -0
- qiskit/circuit/controlflow/continue_loop.py +72 -0
- qiskit/circuit/controlflow/control_flow.py +52 -0
- qiskit/circuit/controlflow/for_loop.py +232 -0
- qiskit/circuit/controlflow/if_else.py +517 -0
- qiskit/circuit/controlflow/switch_case.py +424 -0
- qiskit/circuit/controlflow/while_loop.py +177 -0
- qiskit/circuit/controlledgate.py +271 -0
- qiskit/circuit/delay.py +104 -0
- qiskit/circuit/duration.py +88 -0
- qiskit/circuit/equivalence.py +291 -0
- qiskit/circuit/equivalence_library.py +18 -0
- qiskit/circuit/exceptions.py +19 -0
- qiskit/circuit/gate.py +245 -0
- qiskit/circuit/instruction.py +655 -0
- qiskit/circuit/instructionset.py +191 -0
- qiskit/circuit/library/__init__.py +581 -0
- qiskit/circuit/library/arithmetic/__init__.py +27 -0
- qiskit/circuit/library/arithmetic/adders/__init__.py +17 -0
- qiskit/circuit/library/arithmetic/adders/adder.py +58 -0
- qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +159 -0
- qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +116 -0
- qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +165 -0
- qiskit/circuit/library/arithmetic/exact_reciprocal.py +88 -0
- qiskit/circuit/library/arithmetic/functional_pauli_rotations.py +114 -0
- qiskit/circuit/library/arithmetic/integer_comparator.py +243 -0
- qiskit/circuit/library/arithmetic/linear_amplitude_function.py +196 -0
- qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +189 -0
- qiskit/circuit/library/arithmetic/multipliers/__init__.py +16 -0
- qiskit/circuit/library/arithmetic/multipliers/hrs_cumulative_multiplier.py +138 -0
- qiskit/circuit/library/arithmetic/multipliers/multiplier.py +101 -0
- qiskit/circuit/library/arithmetic/multipliers/rg_qft_multiplier.py +101 -0
- qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +353 -0
- qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +277 -0
- qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +317 -0
- qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +335 -0
- qiskit/circuit/library/arithmetic/quadratic_form.py +197 -0
- qiskit/circuit/library/arithmetic/weighted_adder.py +337 -0
- qiskit/circuit/library/basis_change/__init__.py +15 -0
- qiskit/circuit/library/basis_change/qft.py +289 -0
- qiskit/circuit/library/blueprintcircuit.py +186 -0
- qiskit/circuit/library/boolean_logic/__init__.py +18 -0
- qiskit/circuit/library/boolean_logic/inner_product.py +78 -0
- qiskit/circuit/library/boolean_logic/quantum_and.py +97 -0
- qiskit/circuit/library/boolean_logic/quantum_or.py +98 -0
- qiskit/circuit/library/boolean_logic/quantum_xor.py +71 -0
- qiskit/circuit/library/data_preparation/__init__.py +47 -0
- qiskit/circuit/library/data_preparation/initializer.py +96 -0
- qiskit/circuit/library/data_preparation/pauli_feature_map.py +296 -0
- qiskit/circuit/library/data_preparation/state_preparation.py +526 -0
- qiskit/circuit/library/data_preparation/z_feature_map.py +104 -0
- qiskit/circuit/library/data_preparation/zz_feature_map.py +114 -0
- qiskit/circuit/library/evolved_operator_ansatz.py +245 -0
- qiskit/circuit/library/fourier_checking.py +97 -0
- qiskit/circuit/library/generalized_gates/__init__.py +30 -0
- qiskit/circuit/library/generalized_gates/diagonal.py +164 -0
- qiskit/circuit/library/generalized_gates/gms.py +121 -0
- qiskit/circuit/library/generalized_gates/gr.py +215 -0
- qiskit/circuit/library/generalized_gates/isometry.py +573 -0
- qiskit/circuit/library/generalized_gates/linear_function.py +302 -0
- qiskit/circuit/library/generalized_gates/mcg_up_to_diagonal.py +138 -0
- qiskit/circuit/library/generalized_gates/mcmt.py +254 -0
- qiskit/circuit/library/generalized_gates/pauli.py +85 -0
- qiskit/circuit/library/generalized_gates/permutation.py +190 -0
- qiskit/circuit/library/generalized_gates/rv.py +93 -0
- qiskit/circuit/library/generalized_gates/uc.py +304 -0
- qiskit/circuit/library/generalized_gates/uc_pauli_rot.py +164 -0
- qiskit/circuit/library/generalized_gates/ucrx.py +32 -0
- qiskit/circuit/library/generalized_gates/ucry.py +32 -0
- qiskit/circuit/library/generalized_gates/ucrz.py +32 -0
- qiskit/circuit/library/generalized_gates/unitary.py +198 -0
- qiskit/circuit/library/graph_state.py +86 -0
- qiskit/circuit/library/grover_operator.py +311 -0
- qiskit/circuit/library/hamiltonian_gate.py +146 -0
- qiskit/circuit/library/hidden_linear_function.py +98 -0
- qiskit/circuit/library/iqp.py +96 -0
- qiskit/circuit/library/n_local/__init__.py +31 -0
- qiskit/circuit/library/n_local/efficient_su2.py +162 -0
- qiskit/circuit/library/n_local/excitation_preserving.py +176 -0
- qiskit/circuit/library/n_local/n_local.py +1044 -0
- qiskit/circuit/library/n_local/pauli_two_design.py +131 -0
- qiskit/circuit/library/n_local/qaoa_ansatz.py +288 -0
- qiskit/circuit/library/n_local/real_amplitudes.py +189 -0
- qiskit/circuit/library/n_local/two_local.py +334 -0
- qiskit/circuit/library/overlap.py +111 -0
- qiskit/circuit/library/pauli_evolution.py +180 -0
- qiskit/circuit/library/phase_estimation.py +99 -0
- qiskit/circuit/library/phase_oracle.py +153 -0
- qiskit/circuit/library/quantum_volume.py +114 -0
- qiskit/circuit/library/standard_gates/__init__.py +116 -0
- qiskit/circuit/library/standard_gates/dcx.py +71 -0
- qiskit/circuit/library/standard_gates/ecr.py +114 -0
- qiskit/circuit/library/standard_gates/equivalence_library.py +1677 -0
- qiskit/circuit/library/standard_gates/global_phase.py +63 -0
- qiskit/circuit/library/standard_gates/h.py +224 -0
- qiskit/circuit/library/standard_gates/i.py +60 -0
- qiskit/circuit/library/standard_gates/iswap.py +129 -0
- qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +390 -0
- qiskit/circuit/library/standard_gates/p.py +364 -0
- qiskit/circuit/library/standard_gates/r.py +101 -0
- qiskit/circuit/library/standard_gates/rx.py +246 -0
- qiskit/circuit/library/standard_gates/rxx.py +128 -0
- qiskit/circuit/library/standard_gates/ry.py +241 -0
- qiskit/circuit/library/standard_gates/ryy.py +128 -0
- qiskit/circuit/library/standard_gates/rz.py +261 -0
- qiskit/circuit/library/standard_gates/rzx.py +174 -0
- qiskit/circuit/library/standard_gates/rzz.py +141 -0
- qiskit/circuit/library/standard_gates/s.py +303 -0
- qiskit/circuit/library/standard_gates/swap.py +246 -0
- qiskit/circuit/library/standard_gates/sx.py +268 -0
- qiskit/circuit/library/standard_gates/t.py +150 -0
- qiskit/circuit/library/standard_gates/u.py +338 -0
- qiskit/circuit/library/standard_gates/u1.py +383 -0
- qiskit/circuit/library/standard_gates/u2.py +132 -0
- qiskit/circuit/library/standard_gates/u3.py +358 -0
- qiskit/circuit/library/standard_gates/x.py +1370 -0
- qiskit/circuit/library/standard_gates/xx_minus_yy.py +179 -0
- qiskit/circuit/library/standard_gates/xx_plus_yy.py +180 -0
- qiskit/circuit/library/standard_gates/y.py +221 -0
- qiskit/circuit/library/standard_gates/z.py +294 -0
- qiskit/circuit/library/templates/__init__.py +92 -0
- qiskit/circuit/library/templates/clifford/__init__.py +33 -0
- qiskit/circuit/library/templates/clifford/clifford_2_1.py +33 -0
- qiskit/circuit/library/templates/clifford/clifford_2_2.py +34 -0
- qiskit/circuit/library/templates/clifford/clifford_2_3.py +32 -0
- qiskit/circuit/library/templates/clifford/clifford_2_4.py +33 -0
- qiskit/circuit/library/templates/clifford/clifford_3_1.py +34 -0
- qiskit/circuit/library/templates/clifford/clifford_4_1.py +37 -0
- qiskit/circuit/library/templates/clifford/clifford_4_2.py +36 -0
- qiskit/circuit/library/templates/clifford/clifford_4_3.py +37 -0
- qiskit/circuit/library/templates/clifford/clifford_4_4.py +36 -0
- qiskit/circuit/library/templates/clifford/clifford_5_1.py +39 -0
- qiskit/circuit/library/templates/clifford/clifford_6_1.py +39 -0
- qiskit/circuit/library/templates/clifford/clifford_6_2.py +39 -0
- qiskit/circuit/library/templates/clifford/clifford_6_3.py +39 -0
- qiskit/circuit/library/templates/clifford/clifford_6_4.py +37 -0
- qiskit/circuit/library/templates/clifford/clifford_6_5.py +39 -0
- qiskit/circuit/library/templates/clifford/clifford_8_1.py +41 -0
- qiskit/circuit/library/templates/clifford/clifford_8_2.py +41 -0
- qiskit/circuit/library/templates/clifford/clifford_8_3.py +40 -0
- qiskit/circuit/library/templates/nct/__init__.py +67 -0
- qiskit/circuit/library/templates/nct/template_nct_2a_1.py +32 -0
- qiskit/circuit/library/templates/nct/template_nct_2a_2.py +33 -0
- qiskit/circuit/library/templates/nct/template_nct_2a_3.py +35 -0
- qiskit/circuit/library/templates/nct/template_nct_4a_1.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_4a_2.py +39 -0
- qiskit/circuit/library/templates/nct/template_nct_4a_3.py +37 -0
- qiskit/circuit/library/templates/nct/template_nct_4b_1.py +39 -0
- qiskit/circuit/library/templates/nct/template_nct_4b_2.py +37 -0
- qiskit/circuit/library/templates/nct/template_nct_5a_1.py +38 -0
- qiskit/circuit/library/templates/nct/template_nct_5a_2.py +38 -0
- qiskit/circuit/library/templates/nct/template_nct_5a_3.py +38 -0
- qiskit/circuit/library/templates/nct/template_nct_5a_4.py +37 -0
- qiskit/circuit/library/templates/nct/template_nct_6a_1.py +38 -0
- qiskit/circuit/library/templates/nct/template_nct_6a_2.py +39 -0
- qiskit/circuit/library/templates/nct/template_nct_6a_3.py +39 -0
- qiskit/circuit/library/templates/nct/template_nct_6a_4.py +39 -0
- qiskit/circuit/library/templates/nct/template_nct_6b_1.py +39 -0
- qiskit/circuit/library/templates/nct/template_nct_6b_2.py +39 -0
- qiskit/circuit/library/templates/nct/template_nct_6c_1.py +39 -0
- qiskit/circuit/library/templates/nct/template_nct_7a_1.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_7b_1.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_7c_1.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_7d_1.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_7e_1.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_9a_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_1.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_10.py +42 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_11.py +42 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_12.py +42 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_2.py +42 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_3.py +42 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_4.py +42 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_5.py +42 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_6.py +42 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_7.py +42 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_8.py +42 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_9.py +42 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_1.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_10.py +42 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_2.py +42 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_3.py +42 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_4.py +42 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_5.py +42 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_6.py +42 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_7.py +42 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_8.py +42 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_9.py +42 -0
- qiskit/circuit/library/templates/rzx/__init__.py +25 -0
- qiskit/circuit/library/templates/rzx/rzx_cy.py +46 -0
- qiskit/circuit/library/templates/rzx/rzx_xz.py +53 -0
- qiskit/circuit/library/templates/rzx/rzx_yz.py +43 -0
- qiskit/circuit/library/templates/rzx/rzx_zz1.py +67 -0
- qiskit/circuit/library/templates/rzx/rzx_zz2.py +58 -0
- qiskit/circuit/library/templates/rzx/rzx_zz3.py +57 -0
- qiskit/circuit/measure.py +41 -0
- qiskit/circuit/operation.py +62 -0
- qiskit/circuit/parameter.py +160 -0
- qiskit/circuit/parameterexpression.py +515 -0
- qiskit/circuit/parametertable.py +263 -0
- qiskit/circuit/parametervector.py +114 -0
- qiskit/circuit/qpy_serialization.py +28 -0
- qiskit/circuit/quantumcircuit.py +6074 -0
- qiskit/circuit/quantumcircuitdata.py +138 -0
- qiskit/circuit/quantumregister.py +90 -0
- qiskit/circuit/random/__init__.py +15 -0
- qiskit/circuit/random/utils.py +209 -0
- qiskit/circuit/register.py +256 -0
- qiskit/circuit/reset.py +31 -0
- qiskit/circuit/singleton.py +604 -0
- qiskit/circuit/store.py +87 -0
- qiskit/circuit/tools/__init__.py +16 -0
- qiskit/circuit/tools/pi_check.py +190 -0
- qiskit/compiler/__init__.py +33 -0
- qiskit/compiler/assembler.py +597 -0
- qiskit/compiler/scheduler.py +107 -0
- qiskit/compiler/sequencer.py +69 -0
- qiskit/compiler/transpiler.py +613 -0
- qiskit/converters/__init__.py +59 -0
- qiskit/converters/circuit_to_dag.py +96 -0
- qiskit/converters/circuit_to_dagdependency.py +51 -0
- qiskit/converters/circuit_to_gate.py +109 -0
- qiskit/converters/circuit_to_instruction.py +131 -0
- qiskit/converters/dag_to_circuit.py +77 -0
- qiskit/converters/dag_to_dagdependency.py +55 -0
- qiskit/converters/dagdependency_to_circuit.py +42 -0
- qiskit/converters/dagdependency_to_dag.py +49 -0
- qiskit/dagcircuit/__init__.py +44 -0
- qiskit/dagcircuit/collect_blocks.py +386 -0
- qiskit/dagcircuit/dagcircuit.py +2105 -0
- qiskit/dagcircuit/dagdependency.py +626 -0
- qiskit/dagcircuit/dagdepnode.py +157 -0
- qiskit/dagcircuit/dagnode.py +322 -0
- qiskit/dagcircuit/exceptions.py +42 -0
- qiskit/exceptions.py +97 -0
- qiskit/execute_function.py +354 -0
- qiskit/extensions/__init__.py +70 -0
- qiskit/extensions/exceptions.py +31 -0
- qiskit/extensions/quantum_initializer/__init__.py +26 -0
- qiskit/extensions/quantum_initializer/squ.py +163 -0
- qiskit/extensions/simulator/__init__.py +15 -0
- qiskit/extensions/simulator/snapshot.py +70 -0
- qiskit/namespace.py +76 -0
- qiskit/passmanager/__init__.py +242 -0
- qiskit/passmanager/base_tasks.py +230 -0
- qiskit/passmanager/compilation_status.py +74 -0
- qiskit/passmanager/exceptions.py +19 -0
- qiskit/passmanager/flow_controllers.py +336 -0
- qiskit/passmanager/passmanager.py +317 -0
- qiskit/primitives/__init__.py +62 -0
- qiskit/primitives/backend_estimator.py +473 -0
- qiskit/primitives/backend_sampler.py +209 -0
- qiskit/primitives/base/__init__.py +20 -0
- qiskit/primitives/base/base_estimator.py +256 -0
- qiskit/primitives/base/base_primitive.py +74 -0
- qiskit/primitives/base/base_result.py +87 -0
- qiskit/primitives/base/base_sampler.py +202 -0
- qiskit/primitives/base/estimator_result.py +46 -0
- qiskit/primitives/base/sampler_result.py +45 -0
- qiskit/primitives/base/validation.py +231 -0
- qiskit/primitives/estimator.py +158 -0
- qiskit/primitives/primitive_job.py +73 -0
- qiskit/primitives/sampler.py +155 -0
- qiskit/primitives/utils.py +216 -0
- qiskit/providers/__init__.py +773 -0
- qiskit/providers/backend.py +653 -0
- qiskit/providers/backend_compat.py +347 -0
- qiskit/providers/basicaer/__init__.py +73 -0
- qiskit/providers/basicaer/basicaerjob.py +65 -0
- qiskit/providers/basicaer/basicaerprovider.py +127 -0
- qiskit/providers/basicaer/basicaertools.py +186 -0
- qiskit/providers/basicaer/exceptions.py +30 -0
- qiskit/providers/basicaer/qasm_simulator.py +678 -0
- qiskit/providers/basicaer/statevector_simulator.py +121 -0
- qiskit/providers/basicaer/unitary_simulator.py +395 -0
- qiskit/providers/exceptions.py +45 -0
- qiskit/providers/fake_provider/__init__.py +267 -0
- qiskit/providers/fake_provider/backends/__init__.py +110 -0
- qiskit/providers/fake_provider/backends/almaden/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/almaden/conf_almaden.json +1 -0
- qiskit/providers/fake_provider/backends/almaden/fake_almaden.py +58 -0
- qiskit/providers/fake_provider/backends/almaden/props_almaden.json +1 -0
- qiskit/providers/fake_provider/backends/armonk/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/armonk/conf_armonk.json +1 -0
- qiskit/providers/fake_provider/backends/armonk/defs_armonk.json +1 -0
- qiskit/providers/fake_provider/backends/armonk/fake_armonk.py +48 -0
- qiskit/providers/fake_provider/backends/armonk/props_armonk.json +1 -0
- qiskit/providers/fake_provider/backends/athens/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/athens/conf_athens.json +1 -0
- qiskit/providers/fake_provider/backends/athens/defs_athens.json +1 -0
- qiskit/providers/fake_provider/backends/athens/fake_athens.py +38 -0
- qiskit/providers/fake_provider/backends/athens/props_athens.json +1 -0
- qiskit/providers/fake_provider/backends/auckland/__init__.py +15 -0
- qiskit/providers/fake_provider/backends/auckland/conf_auckland.json +1 -0
- qiskit/providers/fake_provider/backends/auckland/defs_auckland.json +1 -0
- qiskit/providers/fake_provider/backends/auckland/fake_auckland.py +29 -0
- qiskit/providers/fake_provider/backends/auckland/props_auckland.json +1 -0
- qiskit/providers/fake_provider/backends/belem/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/belem/conf_belem.json +1 -0
- qiskit/providers/fake_provider/backends/belem/defs_belem.json +1 -0
- qiskit/providers/fake_provider/backends/belem/fake_belem.py +38 -0
- qiskit/providers/fake_provider/backends/belem/props_belem.json +1 -0
- qiskit/providers/fake_provider/backends/boeblingen/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/boeblingen/conf_boeblingen.json +1 -0
- qiskit/providers/fake_provider/backends/boeblingen/defs_boeblingen.json +1 -0
- qiskit/providers/fake_provider/backends/boeblingen/fake_boeblingen.py +60 -0
- qiskit/providers/fake_provider/backends/boeblingen/props_boeblingen.json +1 -0
- qiskit/providers/fake_provider/backends/bogota/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/bogota/conf_bogota.json +1 -0
- qiskit/providers/fake_provider/backends/bogota/defs_bogota.json +1 -0
- qiskit/providers/fake_provider/backends/bogota/fake_bogota.py +38 -0
- qiskit/providers/fake_provider/backends/bogota/props_bogota.json +1 -0
- qiskit/providers/fake_provider/backends/brooklyn/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/brooklyn/conf_brooklyn.json +1 -0
- qiskit/providers/fake_provider/backends/brooklyn/defs_brooklyn.json +1 -0
- qiskit/providers/fake_provider/backends/brooklyn/fake_brooklyn.py +38 -0
- qiskit/providers/fake_provider/backends/brooklyn/props_brooklyn.json +1 -0
- qiskit/providers/fake_provider/backends/burlington/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/burlington/conf_burlington.json +1 -0
- qiskit/providers/fake_provider/backends/burlington/fake_burlington.py +50 -0
- qiskit/providers/fake_provider/backends/burlington/props_burlington.json +1 -0
- qiskit/providers/fake_provider/backends/cairo/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/cairo/conf_cairo.json +1 -0
- qiskit/providers/fake_provider/backends/cairo/defs_cairo.json +1 -0
- qiskit/providers/fake_provider/backends/cairo/fake_cairo.py +38 -0
- qiskit/providers/fake_provider/backends/cairo/props_cairo.json +1 -0
- qiskit/providers/fake_provider/backends/cambridge/__init__.py +17 -0
- qiskit/providers/fake_provider/backends/cambridge/conf_cambridge.json +1 -0
- qiskit/providers/fake_provider/backends/cambridge/fake_cambridge.py +72 -0
- qiskit/providers/fake_provider/backends/cambridge/props_cambridge.json +1 -0
- qiskit/providers/fake_provider/backends/cambridge/props_cambridge_alt.json +1 -0
- qiskit/providers/fake_provider/backends/casablanca/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/casablanca/conf_casablanca.json +1 -0
- qiskit/providers/fake_provider/backends/casablanca/defs_casablanca.json +1 -0
- qiskit/providers/fake_provider/backends/casablanca/fake_casablanca.py +38 -0
- qiskit/providers/fake_provider/backends/casablanca/props_casablanca.json +1 -0
- qiskit/providers/fake_provider/backends/essex/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/essex/conf_essex.json +1 -0
- qiskit/providers/fake_provider/backends/essex/fake_essex.py +54 -0
- qiskit/providers/fake_provider/backends/essex/props_essex.json +1 -0
- qiskit/providers/fake_provider/backends/geneva/__init__.py +15 -0
- qiskit/providers/fake_provider/backends/geneva/conf_geneva.json +1 -0
- qiskit/providers/fake_provider/backends/geneva/defs_geneva.json +1 -0
- qiskit/providers/fake_provider/backends/geneva/fake_geneva.py +29 -0
- qiskit/providers/fake_provider/backends/geneva/props_geneva.json +1 -0
- qiskit/providers/fake_provider/backends/guadalupe/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/guadalupe/conf_guadalupe.json +1 -0
- qiskit/providers/fake_provider/backends/guadalupe/defs_guadalupe.json +1 -0
- qiskit/providers/fake_provider/backends/guadalupe/fake_guadalupe.py +39 -0
- qiskit/providers/fake_provider/backends/guadalupe/props_guadalupe.json +1 -0
- qiskit/providers/fake_provider/backends/hanoi/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/hanoi/conf_hanoi.json +1 -0
- qiskit/providers/fake_provider/backends/hanoi/defs_hanoi.json +1 -0
- qiskit/providers/fake_provider/backends/hanoi/fake_hanoi.py +38 -0
- qiskit/providers/fake_provider/backends/hanoi/props_hanoi.json +1 -0
- qiskit/providers/fake_provider/backends/jakarta/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/jakarta/conf_jakarta.json +1 -0
- qiskit/providers/fake_provider/backends/jakarta/defs_jakarta.json +1 -0
- qiskit/providers/fake_provider/backends/jakarta/fake_jakarta.py +38 -0
- qiskit/providers/fake_provider/backends/jakarta/props_jakarta.json +1 -0
- qiskit/providers/fake_provider/backends/johannesburg/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/johannesburg/conf_johannesburg.json +1 -0
- qiskit/providers/fake_provider/backends/johannesburg/fake_johannesburg.py +58 -0
- qiskit/providers/fake_provider/backends/johannesburg/props_johannesburg.json +1 -0
- qiskit/providers/fake_provider/backends/kolkata/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/kolkata/conf_kolkata.json +1 -0
- qiskit/providers/fake_provider/backends/kolkata/defs_kolkata.json +1 -0
- qiskit/providers/fake_provider/backends/kolkata/fake_kolkata.py +38 -0
- qiskit/providers/fake_provider/backends/kolkata/props_kolkata.json +1 -0
- qiskit/providers/fake_provider/backends/lagos/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/lagos/conf_lagos.json +1 -0
- qiskit/providers/fake_provider/backends/lagos/defs_lagos.json +1 -0
- qiskit/providers/fake_provider/backends/lagos/fake_lagos.py +38 -0
- qiskit/providers/fake_provider/backends/lagos/props_lagos.json +1 -0
- qiskit/providers/fake_provider/backends/lima/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/lima/conf_lima.json +1 -0
- qiskit/providers/fake_provider/backends/lima/defs_lima.json +1 -0
- qiskit/providers/fake_provider/backends/lima/fake_lima.py +38 -0
- qiskit/providers/fake_provider/backends/lima/props_lima.json +1 -0
- qiskit/providers/fake_provider/backends/london/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/london/conf_london.json +1 -0
- qiskit/providers/fake_provider/backends/london/fake_london.py +54 -0
- qiskit/providers/fake_provider/backends/london/props_london.json +1 -0
- qiskit/providers/fake_provider/backends/manhattan/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/manhattan/conf_manhattan.json +1 -0
- qiskit/providers/fake_provider/backends/manhattan/defs_manhattan.json +1 -0
- qiskit/providers/fake_provider/backends/manhattan/fake_manhattan.py +38 -0
- qiskit/providers/fake_provider/backends/manhattan/props_manhattan.json +1 -0
- qiskit/providers/fake_provider/backends/manila/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/manila/conf_manila.json +1 -0
- qiskit/providers/fake_provider/backends/manila/defs_manila.json +1 -0
- qiskit/providers/fake_provider/backends/manila/fake_manila.py +38 -0
- qiskit/providers/fake_provider/backends/manila/props_manila.json +1 -0
- qiskit/providers/fake_provider/backends/melbourne/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/melbourne/conf_melbourne.json +1 -0
- qiskit/providers/fake_provider/backends/melbourne/fake_melbourne.py +91 -0
- qiskit/providers/fake_provider/backends/melbourne/props_melbourne.json +1 -0
- qiskit/providers/fake_provider/backends/montreal/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/montreal/conf_montreal.json +1 -0
- qiskit/providers/fake_provider/backends/montreal/defs_montreal.json +1 -0
- qiskit/providers/fake_provider/backends/montreal/fake_montreal.py +38 -0
- qiskit/providers/fake_provider/backends/montreal/props_montreal.json +1 -0
- qiskit/providers/fake_provider/backends/mumbai/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/mumbai/conf_mumbai.json +1 -0
- qiskit/providers/fake_provider/backends/mumbai/defs_mumbai.json +1 -0
- qiskit/providers/fake_provider/backends/mumbai/fake_mumbai.py +38 -0
- qiskit/providers/fake_provider/backends/mumbai/props_mumbai.json +1 -0
- qiskit/providers/fake_provider/backends/nairobi/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/nairobi/conf_nairobi.json +1 -0
- qiskit/providers/fake_provider/backends/nairobi/defs_nairobi.json +1 -0
- qiskit/providers/fake_provider/backends/nairobi/fake_nairobi.py +38 -0
- qiskit/providers/fake_provider/backends/nairobi/props_nairobi.json +1 -0
- qiskit/providers/fake_provider/backends/oslo/__init__.py +15 -0
- qiskit/providers/fake_provider/backends/oslo/conf_oslo.json +1 -0
- qiskit/providers/fake_provider/backends/oslo/defs_oslo.json +1 -0
- qiskit/providers/fake_provider/backends/oslo/fake_oslo.py +29 -0
- qiskit/providers/fake_provider/backends/oslo/props_oslo.json +1 -0
- qiskit/providers/fake_provider/backends/ourense/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/ourense/conf_ourense.json +1 -0
- qiskit/providers/fake_provider/backends/ourense/fake_ourense.py +50 -0
- qiskit/providers/fake_provider/backends/ourense/props_ourense.json +1 -0
- qiskit/providers/fake_provider/backends/paris/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/paris/conf_paris.json +1 -0
- qiskit/providers/fake_provider/backends/paris/defs_paris.json +1 -0
- qiskit/providers/fake_provider/backends/paris/fake_paris.py +64 -0
- qiskit/providers/fake_provider/backends/paris/props_paris.json +1 -0
- qiskit/providers/fake_provider/backends/perth/__init__.py +15 -0
- qiskit/providers/fake_provider/backends/perth/conf_perth.json +1 -0
- qiskit/providers/fake_provider/backends/perth/defs_perth.json +1 -0
- qiskit/providers/fake_provider/backends/perth/fake_perth.py +29 -0
- qiskit/providers/fake_provider/backends/perth/props_perth.json +1 -0
- qiskit/providers/fake_provider/backends/poughkeepsie/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/poughkeepsie/conf_poughkeepsie.json +1 -0
- qiskit/providers/fake_provider/backends/poughkeepsie/defs_poughkeepsie.json +1 -0
- qiskit/providers/fake_provider/backends/poughkeepsie/fake_poughkeepsie.py +124 -0
- qiskit/providers/fake_provider/backends/poughkeepsie/props_poughkeepsie.json +1 -0
- qiskit/providers/fake_provider/backends/prague/__init__.py +15 -0
- qiskit/providers/fake_provider/backends/prague/conf_prague.json +1 -0
- qiskit/providers/fake_provider/backends/prague/fake_prague.py +28 -0
- qiskit/providers/fake_provider/backends/prague/props_prague.json +1 -0
- qiskit/providers/fake_provider/backends/quito/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/quito/conf_quito.json +1 -0
- qiskit/providers/fake_provider/backends/quito/defs_quito.json +1 -0
- qiskit/providers/fake_provider/backends/quito/fake_quito.py +38 -0
- qiskit/providers/fake_provider/backends/quito/props_quito.json +1 -0
- qiskit/providers/fake_provider/backends/rochester/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/rochester/conf_rochester.json +1 -0
- qiskit/providers/fake_provider/backends/rochester/fake_rochester.py +36 -0
- qiskit/providers/fake_provider/backends/rochester/props_rochester.json +1 -0
- qiskit/providers/fake_provider/backends/rome/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/rome/conf_rome.json +1 -0
- qiskit/providers/fake_provider/backends/rome/defs_rome.json +1 -0
- qiskit/providers/fake_provider/backends/rome/fake_rome.py +38 -0
- qiskit/providers/fake_provider/backends/rome/props_rome.json +1 -0
- qiskit/providers/fake_provider/backends/rueschlikon/__init__.py +15 -0
- qiskit/providers/fake_provider/backends/rueschlikon/fake_rueschlikon.py +74 -0
- qiskit/providers/fake_provider/backends/santiago/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/santiago/conf_santiago.json +1 -0
- qiskit/providers/fake_provider/backends/santiago/defs_santiago.json +1 -0
- qiskit/providers/fake_provider/backends/santiago/fake_santiago.py +38 -0
- qiskit/providers/fake_provider/backends/santiago/props_santiago.json +1 -0
- qiskit/providers/fake_provider/backends/sherbrooke/__init__.py +17 -0
- qiskit/providers/fake_provider/backends/sherbrooke/conf_sherbrooke.json +1 -0
- qiskit/providers/fake_provider/backends/sherbrooke/defs_sherbrooke.json +1 -0
- qiskit/providers/fake_provider/backends/sherbrooke/fake_sherbrooke.py +28 -0
- qiskit/providers/fake_provider/backends/sherbrooke/props_sherbrooke.json +1 -0
- qiskit/providers/fake_provider/backends/singapore/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/singapore/conf_singapore.json +1 -0
- qiskit/providers/fake_provider/backends/singapore/fake_singapore.py +58 -0
- qiskit/providers/fake_provider/backends/singapore/props_singapore.json +1 -0
- qiskit/providers/fake_provider/backends/sydney/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/sydney/conf_sydney.json +1 -0
- qiskit/providers/fake_provider/backends/sydney/defs_sydney.json +1 -0
- qiskit/providers/fake_provider/backends/sydney/fake_sydney.py +38 -0
- qiskit/providers/fake_provider/backends/sydney/props_sydney.json +1 -0
- qiskit/providers/fake_provider/backends/tenerife/__init__.py +15 -0
- qiskit/providers/fake_provider/backends/tenerife/fake_tenerife.py +64 -0
- qiskit/providers/fake_provider/backends/tenerife/props_tenerife.json +1 -0
- qiskit/providers/fake_provider/backends/tokyo/__init__.py +15 -0
- qiskit/providers/fake_provider/backends/tokyo/fake_tokyo.py +137 -0
- qiskit/providers/fake_provider/backends/tokyo/props_tokyo.json +1 -0
- qiskit/providers/fake_provider/backends/toronto/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/toronto/conf_toronto.json +1 -0
- qiskit/providers/fake_provider/backends/toronto/defs_toronto.json +1 -0
- qiskit/providers/fake_provider/backends/toronto/fake_toronto.py +38 -0
- qiskit/providers/fake_provider/backends/toronto/props_toronto.json +1 -0
- qiskit/providers/fake_provider/backends/valencia/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/valencia/conf_valencia.json +1 -0
- qiskit/providers/fake_provider/backends/valencia/defs_valencia.json +1 -0
- qiskit/providers/fake_provider/backends/valencia/fake_valencia.py +38 -0
- qiskit/providers/fake_provider/backends/valencia/props_valencia.json +1 -0
- qiskit/providers/fake_provider/backends/vigo/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/vigo/conf_vigo.json +1 -0
- qiskit/providers/fake_provider/backends/vigo/fake_vigo.py +50 -0
- qiskit/providers/fake_provider/backends/vigo/props_vigo.json +1 -0
- qiskit/providers/fake_provider/backends/washington/__init__.py +18 -0
- qiskit/providers/fake_provider/backends/washington/conf_washington.json +1 -0
- qiskit/providers/fake_provider/backends/washington/defs_washington.json +1 -0
- qiskit/providers/fake_provider/backends/washington/fake_washington.py +38 -0
- qiskit/providers/fake_provider/backends/washington/props_washington.json +1 -0
- qiskit/providers/fake_provider/backends/yorktown/__init__.py +16 -0
- qiskit/providers/fake_provider/backends/yorktown/conf_yorktown.json +1 -0
- qiskit/providers/fake_provider/backends/yorktown/fake_yorktown.py +54 -0
- qiskit/providers/fake_provider/backends/yorktown/props_yorktown.json +1 -0
- qiskit/providers/fake_provider/fake_1q.py +91 -0
- qiskit/providers/fake_provider/fake_backend.py +572 -0
- qiskit/providers/fake_provider/fake_backend_v2.py +217 -0
- qiskit/providers/fake_provider/fake_job.py +81 -0
- qiskit/providers/fake_provider/fake_mumbai_v2.py +637 -0
- qiskit/providers/fake_provider/fake_openpulse_2q.py +342 -0
- qiskit/providers/fake_provider/fake_openpulse_3q.py +332 -0
- qiskit/providers/fake_provider/fake_provider.py +214 -0
- qiskit/providers/fake_provider/fake_pulse_backend.py +43 -0
- qiskit/providers/fake_provider/fake_qasm_backend.py +72 -0
- qiskit/providers/fake_provider/fake_qasm_simulator.py +48 -0
- qiskit/providers/fake_provider/fake_qobj.py +44 -0
- qiskit/providers/fake_provider/utils/__init__.py +15 -0
- qiskit/providers/fake_provider/utils/backend_converter.py +150 -0
- qiskit/providers/fake_provider/utils/configurable_backend.py +360 -0
- qiskit/providers/fake_provider/utils/json_decoder.py +109 -0
- qiskit/providers/job.py +142 -0
- qiskit/providers/jobstatus.py +30 -0
- qiskit/providers/models/__init__.py +52 -0
- qiskit/providers/models/backendconfiguration.py +994 -0
- qiskit/providers/models/backendproperties.py +490 -0
- qiskit/providers/models/backendstatus.py +94 -0
- qiskit/providers/models/jobstatus.py +66 -0
- qiskit/providers/models/pulsedefaults.py +304 -0
- qiskit/providers/options.py +273 -0
- qiskit/providers/provider.py +79 -0
- qiskit/providers/providerutils.py +99 -0
- qiskit/pulse/__init__.py +170 -0
- qiskit/pulse/builder.py +2733 -0
- qiskit/pulse/calibration_entries.py +357 -0
- qiskit/pulse/channels.py +221 -0
- qiskit/pulse/configuration.py +244 -0
- qiskit/pulse/exceptions.py +43 -0
- qiskit/pulse/filters.py +302 -0
- qiskit/pulse/instruction_schedule_map.py +406 -0
- qiskit/pulse/instructions/__init__.py +69 -0
- qiskit/pulse/instructions/acquire.py +150 -0
- qiskit/pulse/instructions/call.py +176 -0
- qiskit/pulse/instructions/delay.py +69 -0
- qiskit/pulse/instructions/directives.py +145 -0
- qiskit/pulse/instructions/frequency.py +132 -0
- qiskit/pulse/instructions/instruction.py +266 -0
- qiskit/pulse/instructions/phase.py +149 -0
- qiskit/pulse/instructions/play.py +96 -0
- qiskit/pulse/instructions/reference.py +99 -0
- qiskit/pulse/instructions/snapshot.py +80 -0
- qiskit/pulse/library/__init__.py +99 -0
- qiskit/pulse/library/continuous.py +430 -0
- qiskit/pulse/library/parametric_pulses.py +629 -0
- qiskit/pulse/library/pulse.py +137 -0
- qiskit/pulse/library/samplers/__init__.py +15 -0
- qiskit/pulse/library/samplers/decorators.py +299 -0
- qiskit/pulse/library/samplers/strategies.py +71 -0
- qiskit/pulse/library/symbolic_pulses.py +1962 -0
- qiskit/pulse/library/waveform.py +134 -0
- qiskit/pulse/macros.py +256 -0
- qiskit/pulse/parameter_manager.py +432 -0
- qiskit/pulse/parser.py +314 -0
- qiskit/pulse/reference_manager.py +58 -0
- qiskit/pulse/schedule.py +2002 -0
- qiskit/pulse/transforms/__init__.py +106 -0
- qiskit/pulse/transforms/alignments.py +406 -0
- qiskit/pulse/transforms/base_transforms.py +71 -0
- qiskit/pulse/transforms/canonicalization.py +514 -0
- qiskit/pulse/transforms/dag.py +107 -0
- qiskit/pulse/utils.py +109 -0
- qiskit/qasm/libs/qelib1.inc +266 -0
- qiskit/qasm/libs/stdgates.inc +75 -0
- qiskit/qasm2/__init__.py +658 -0
- qiskit/qasm2/exceptions.py +27 -0
- qiskit/qasm2/export.py +374 -0
- qiskit/qasm2/parse.py +403 -0
- qiskit/qasm3/__init__.py +255 -0
- qiskit/qasm3/ast.py +606 -0
- qiskit/qasm3/exceptions.py +27 -0
- qiskit/qasm3/experimental.py +30 -0
- qiskit/qasm3/exporter.py +1079 -0
- qiskit/qasm3/printer.py +545 -0
- qiskit/qobj/__init__.py +75 -0
- qiskit/qobj/common.py +71 -0
- qiskit/qobj/converters/__init__.py +18 -0
- qiskit/qobj/converters/lo_config.py +168 -0
- qiskit/qobj/converters/pulse_instruction.py +1070 -0
- qiskit/qobj/pulse_qobj.py +655 -0
- qiskit/qobj/qasm_qobj.py +656 -0
- qiskit/qobj/utils.py +37 -0
- qiskit/qpy/__init__.py +1348 -0
- qiskit/qpy/binary_io/__init__.py +36 -0
- qiskit/qpy/binary_io/circuits.py +1212 -0
- qiskit/qpy/binary_io/schedules.py +619 -0
- qiskit/qpy/binary_io/value.py +549 -0
- qiskit/qpy/common.py +305 -0
- qiskit/qpy/exceptions.py +28 -0
- qiskit/qpy/formats.py +360 -0
- qiskit/qpy/interface.py +308 -0
- qiskit/qpy/type_keys.py +544 -0
- qiskit/quantum_info/__init__.py +173 -0
- qiskit/quantum_info/analysis/__init__.py +17 -0
- qiskit/quantum_info/analysis/average.py +47 -0
- qiskit/quantum_info/analysis/distance.py +101 -0
- qiskit/quantum_info/analysis/make_observable.py +43 -0
- qiskit/quantum_info/analysis/z2_symmetries.py +483 -0
- qiskit/quantum_info/operators/__init__.py +28 -0
- qiskit/quantum_info/operators/base_operator.py +145 -0
- qiskit/quantum_info/operators/channel/__init__.py +29 -0
- qiskit/quantum_info/operators/channel/chi.py +190 -0
- qiskit/quantum_info/operators/channel/choi.py +217 -0
- qiskit/quantum_info/operators/channel/kraus.py +336 -0
- qiskit/quantum_info/operators/channel/ptm.py +203 -0
- qiskit/quantum_info/operators/channel/quantum_channel.py +350 -0
- qiskit/quantum_info/operators/channel/stinespring.py +295 -0
- qiskit/quantum_info/operators/channel/superop.py +376 -0
- qiskit/quantum_info/operators/channel/transformations.py +467 -0
- qiskit/quantum_info/operators/custom_iterator.py +48 -0
- qiskit/quantum_info/operators/dihedral/__init__.py +18 -0
- qiskit/quantum_info/operators/dihedral/dihedral.py +508 -0
- qiskit/quantum_info/operators/dihedral/dihedral_circuits.py +218 -0
- qiskit/quantum_info/operators/dihedral/polynomial.py +313 -0
- qiskit/quantum_info/operators/dihedral/random.py +61 -0
- qiskit/quantum_info/operators/linear_op.py +25 -0
- qiskit/quantum_info/operators/measures.py +423 -0
- qiskit/quantum_info/operators/mixins/__init__.py +52 -0
- qiskit/quantum_info/operators/mixins/adjoint.py +52 -0
- qiskit/quantum_info/operators/mixins/group.py +171 -0
- qiskit/quantum_info/operators/mixins/linear.py +84 -0
- qiskit/quantum_info/operators/mixins/multiply.py +62 -0
- qiskit/quantum_info/operators/mixins/tolerances.py +72 -0
- qiskit/quantum_info/operators/op_shape.py +533 -0
- qiskit/quantum_info/operators/operator.py +778 -0
- qiskit/quantum_info/operators/predicates.py +170 -0
- qiskit/quantum_info/operators/random.py +154 -0
- qiskit/quantum_info/operators/scalar_op.py +253 -0
- qiskit/quantum_info/operators/symplectic/__init__.py +23 -0
- qiskit/quantum_info/operators/symplectic/base_pauli.py +720 -0
- qiskit/quantum_info/operators/symplectic/clifford.py +1022 -0
- qiskit/quantum_info/operators/symplectic/clifford_circuits.py +558 -0
- qiskit/quantum_info/operators/symplectic/pauli.py +699 -0
- qiskit/quantum_info/operators/symplectic/pauli_list.py +1209 -0
- qiskit/quantum_info/operators/symplectic/pauli_utils.py +40 -0
- qiskit/quantum_info/operators/symplectic/random.py +264 -0
- qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +1156 -0
- qiskit/quantum_info/operators/utils/__init__.py +20 -0
- qiskit/quantum_info/operators/utils/anti_commutator.py +36 -0
- qiskit/quantum_info/operators/utils/commutator.py +36 -0
- qiskit/quantum_info/operators/utils/double_commutator.py +76 -0
- qiskit/quantum_info/random.py +26 -0
- qiskit/quantum_info/states/__init__.py +28 -0
- qiskit/quantum_info/states/densitymatrix.py +848 -0
- qiskit/quantum_info/states/measures.py +288 -0
- qiskit/quantum_info/states/quantum_state.py +503 -0
- qiskit/quantum_info/states/random.py +157 -0
- qiskit/quantum_info/states/stabilizerstate.py +638 -0
- qiskit/quantum_info/states/statevector.py +961 -0
- qiskit/quantum_info/states/utils.py +245 -0
- qiskit/quantum_info/synthesis/__init__.py +20 -0
- qiskit/quantum_info/synthesis/clifford_decompose.py +69 -0
- qiskit/quantum_info/synthesis/cnotdihedral_decompose.py +50 -0
- qiskit/quantum_info/synthesis/ion_decompose.py +55 -0
- qiskit/quantum_info/synthesis/local_invariance.py +93 -0
- qiskit/quantum_info/synthesis/one_qubit_decompose.py +284 -0
- qiskit/quantum_info/synthesis/qsd.py +269 -0
- qiskit/quantum_info/synthesis/quaternion.py +156 -0
- qiskit/quantum_info/synthesis/two_qubit_decompose.py +1567 -0
- qiskit/quantum_info/synthesis/weyl.py +98 -0
- qiskit/quantum_info/synthesis/xx_decompose/__init__.py +19 -0
- qiskit/quantum_info/synthesis/xx_decompose/circuits.py +299 -0
- qiskit/quantum_info/synthesis/xx_decompose/decomposer.py +314 -0
- qiskit/quantum_info/synthesis/xx_decompose/embodiments.py +163 -0
- qiskit/quantum_info/synthesis/xx_decompose/paths.py +412 -0
- qiskit/quantum_info/synthesis/xx_decompose/polytopes.py +264 -0
- qiskit/quantum_info/synthesis/xx_decompose/utilities.py +40 -0
- qiskit/quantum_info/synthesis/xx_decompose/weyl.py +133 -0
- qiskit/result/__init__.py +67 -0
- qiskit/result/counts.py +189 -0
- qiskit/result/distributions/__init__.py +17 -0
- qiskit/result/distributions/probability.py +100 -0
- qiskit/result/distributions/quasi.py +154 -0
- qiskit/result/exceptions.py +40 -0
- qiskit/result/mitigation/__init__.py +13 -0
- qiskit/result/mitigation/base_readout_mitigator.py +79 -0
- qiskit/result/mitigation/correlated_readout_mitigator.py +268 -0
- qiskit/result/mitigation/local_readout_mitigator.py +319 -0
- qiskit/result/mitigation/utils.py +161 -0
- qiskit/result/models.py +233 -0
- qiskit/result/postprocess.py +239 -0
- qiskit/result/result.py +397 -0
- qiskit/result/sampled_expval.py +75 -0
- qiskit/result/utils.py +295 -0
- qiskit/scheduler/__init__.py +31 -0
- qiskit/scheduler/config.py +35 -0
- qiskit/scheduler/lowering.py +187 -0
- qiskit/scheduler/methods/__init__.py +22 -0
- qiskit/scheduler/methods/basic.py +137 -0
- qiskit/scheduler/schedule_circuit.py +67 -0
- qiskit/scheduler/sequence.py +102 -0
- qiskit/synthesis/__init__.py +122 -0
- qiskit/synthesis/clifford/__init__.py +19 -0
- qiskit/synthesis/clifford/clifford_decompose_ag.py +176 -0
- qiskit/synthesis/clifford/clifford_decompose_bm.py +276 -0
- qiskit/synthesis/clifford/clifford_decompose_full.py +61 -0
- qiskit/synthesis/clifford/clifford_decompose_greedy.py +347 -0
- qiskit/synthesis/clifford/clifford_decompose_layers.py +443 -0
- qiskit/synthesis/cnotdihedral/__init__.py +17 -0
- qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_full.py +46 -0
- qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_general.py +140 -0
- qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_two_qubits.py +264 -0
- qiskit/synthesis/discrete_basis/__init__.py +16 -0
- qiskit/synthesis/discrete_basis/commutator_decompose.py +241 -0
- qiskit/synthesis/discrete_basis/gate_sequence.py +415 -0
- qiskit/synthesis/discrete_basis/generate_basis_approximations.py +163 -0
- qiskit/synthesis/discrete_basis/solovay_kitaev.py +207 -0
- qiskit/synthesis/evolution/__init__.py +20 -0
- qiskit/synthesis/evolution/evolution_synthesis.py +46 -0
- qiskit/synthesis/evolution/lie_trotter.py +123 -0
- qiskit/synthesis/evolution/matrix_synthesis.py +47 -0
- qiskit/synthesis/evolution/product_formula.py +328 -0
- qiskit/synthesis/evolution/qdrift.py +102 -0
- qiskit/synthesis/evolution/suzuki_trotter.py +145 -0
- qiskit/synthesis/linear/__init__.py +25 -0
- qiskit/synthesis/linear/cnot_synth.py +141 -0
- qiskit/synthesis/linear/linear_circuits_utils.py +127 -0
- qiskit/synthesis/linear/linear_depth_lnn.py +275 -0
- qiskit/synthesis/linear/linear_matrix_utils.py +175 -0
- qiskit/synthesis/linear_phase/__init__.py +17 -0
- qiskit/synthesis/linear_phase/cnot_phase_synth.py +203 -0
- qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +262 -0
- qiskit/synthesis/linear_phase/cz_depth_lnn.py +206 -0
- qiskit/synthesis/permutation/__init__.py +17 -0
- qiskit/synthesis/permutation/permutation_full.py +90 -0
- qiskit/synthesis/permutation/permutation_lnn.py +68 -0
- qiskit/synthesis/permutation/permutation_utils.py +73 -0
- qiskit/synthesis/stabilizer/__init__.py +15 -0
- qiskit/synthesis/stabilizer/stabilizer_decompose.py +188 -0
- qiskit/test/__init__.py +18 -0
- qiskit/test/_canonical.py +125 -0
- qiskit/test/base.py +331 -0
- qiskit/test/decorators.py +308 -0
- qiskit/test/ibmq_mock.py +45 -0
- qiskit/test/mock/__init__.py +40 -0
- qiskit/test/mock/backends/__init__.py +32 -0
- qiskit/test/mock/backends/almaden/__init__.py +32 -0
- qiskit/test/mock/backends/armonk/__init__.py +32 -0
- qiskit/test/mock/backends/athens/__init__.py +32 -0
- qiskit/test/mock/backends/belem/__init__.py +32 -0
- qiskit/test/mock/backends/boeblingen/__init__.py +32 -0
- qiskit/test/mock/backends/bogota/__init__.py +32 -0
- qiskit/test/mock/backends/brooklyn/__init__.py +32 -0
- qiskit/test/mock/backends/burlington/__init__.py +32 -0
- qiskit/test/mock/backends/cairo/__init__.py +32 -0
- qiskit/test/mock/backends/cambridge/__init__.py +32 -0
- qiskit/test/mock/backends/casablanca/__init__.py +32 -0
- qiskit/test/mock/backends/essex/__init__.py +32 -0
- qiskit/test/mock/backends/guadalupe/__init__.py +32 -0
- qiskit/test/mock/backends/hanoi/__init__.py +32 -0
- qiskit/test/mock/backends/jakarta/__init__.py +32 -0
- qiskit/test/mock/backends/johannesburg/__init__.py +32 -0
- qiskit/test/mock/backends/kolkata/__init__.py +32 -0
- qiskit/test/mock/backends/lagos/__init__.py +32 -0
- qiskit/test/mock/backends/lima/__init__.py +32 -0
- qiskit/test/mock/backends/london/__init__.py +32 -0
- qiskit/test/mock/backends/manhattan/__init__.py +32 -0
- qiskit/test/mock/backends/manila/__init__.py +32 -0
- qiskit/test/mock/backends/melbourne/__init__.py +32 -0
- qiskit/test/mock/backends/montreal/__init__.py +32 -0
- qiskit/test/mock/backends/mumbai/__init__.py +32 -0
- qiskit/test/mock/backends/nairobi/__init__.py +32 -0
- qiskit/test/mock/backends/ourense/__init__.py +32 -0
- qiskit/test/mock/backends/paris/__init__.py +32 -0
- qiskit/test/mock/backends/poughkeepsie/__init__.py +32 -0
- qiskit/test/mock/backends/quito/__init__.py +32 -0
- qiskit/test/mock/backends/rochester/__init__.py +32 -0
- qiskit/test/mock/backends/rome/__init__.py +32 -0
- qiskit/test/mock/backends/rueschlikon/__init__.py +32 -0
- qiskit/test/mock/backends/santiago/__init__.py +32 -0
- qiskit/test/mock/backends/singapore/__init__.py +32 -0
- qiskit/test/mock/backends/sydney/__init__.py +32 -0
- qiskit/test/mock/backends/tenerife/__init__.py +32 -0
- qiskit/test/mock/backends/tokyo/__init__.py +32 -0
- qiskit/test/mock/backends/toronto/__init__.py +32 -0
- qiskit/test/mock/backends/valencia/__init__.py +32 -0
- qiskit/test/mock/backends/vigo/__init__.py +32 -0
- qiskit/test/mock/backends/washington/__init__.py +32 -0
- qiskit/test/mock/backends/yorktown/__init__.py +32 -0
- qiskit/test/providers/__init__.py +16 -0
- qiskit/test/providers/backend.py +75 -0
- qiskit/test/providers/provider.py +59 -0
- qiskit/test/reference_circuits.py +41 -0
- qiskit/test/testing_options.py +93 -0
- qiskit/test/utils.py +87 -0
- qiskit/tools/__init__.py +44 -0
- qiskit/tools/events/__init__.py +25 -0
- qiskit/tools/events/progressbar.py +195 -0
- qiskit/tools/events/pubsub.py +158 -0
- qiskit/tools/jupyter/__init__.py +138 -0
- qiskit/tools/jupyter/backend_monitor.py +588 -0
- qiskit/tools/jupyter/backend_overview.py +322 -0
- qiskit/tools/jupyter/copyright.py +42 -0
- qiskit/tools/jupyter/job_watcher.py +167 -0
- qiskit/tools/jupyter/job_widgets.py +160 -0
- qiskit/tools/jupyter/jupyter_magics.py +190 -0
- qiskit/tools/jupyter/library.py +189 -0
- qiskit/tools/jupyter/monospace.py +29 -0
- qiskit/tools/jupyter/progressbar.py +122 -0
- qiskit/tools/jupyter/version_table.py +67 -0
- qiskit/tools/jupyter/watcher_monitor.py +74 -0
- qiskit/tools/monitor/__init__.py +16 -0
- qiskit/tools/monitor/job_monitor.py +107 -0
- qiskit/tools/monitor/overview.py +247 -0
- qiskit/tools/parallel.py +198 -0
- qiskit/tools/visualization.py +16 -0
- qiskit/transpiler/__init__.py +1287 -0
- qiskit/transpiler/basepasses.py +221 -0
- qiskit/transpiler/coupling.py +500 -0
- qiskit/transpiler/exceptions.py +55 -0
- qiskit/transpiler/fencedobjs.py +78 -0
- qiskit/transpiler/instruction_durations.py +278 -0
- qiskit/transpiler/layout.py +658 -0
- qiskit/transpiler/passes/__init__.py +296 -0
- qiskit/transpiler/passes/analysis/__init__.py +23 -0
- qiskit/transpiler/passes/analysis/count_ops.py +30 -0
- qiskit/transpiler/passes/analysis/count_ops_longest_path.py +26 -0
- qiskit/transpiler/passes/analysis/dag_longest_path.py +24 -0
- qiskit/transpiler/passes/analysis/depth.py +33 -0
- qiskit/transpiler/passes/analysis/num_qubits.py +26 -0
- qiskit/transpiler/passes/analysis/num_tensor_factors.py +26 -0
- qiskit/transpiler/passes/analysis/resource_estimation.py +41 -0
- qiskit/transpiler/passes/analysis/size.py +36 -0
- qiskit/transpiler/passes/analysis/width.py +27 -0
- qiskit/transpiler/passes/basis/__init__.py +20 -0
- qiskit/transpiler/passes/basis/basis_translator.py +697 -0
- qiskit/transpiler/passes/basis/decompose.py +98 -0
- qiskit/transpiler/passes/basis/translate_parameterized.py +177 -0
- qiskit/transpiler/passes/basis/unroll_3q_or_more.py +86 -0
- qiskit/transpiler/passes/basis/unroll_custom_definitions.py +107 -0
- qiskit/transpiler/passes/basis/unroller.py +145 -0
- qiskit/transpiler/passes/calibration/__init__.py +17 -0
- qiskit/transpiler/passes/calibration/base_builder.py +79 -0
- qiskit/transpiler/passes/calibration/builders.py +20 -0
- qiskit/transpiler/passes/calibration/exceptions.py +22 -0
- qiskit/transpiler/passes/calibration/pulse_gate.py +98 -0
- qiskit/transpiler/passes/calibration/rx_builder.py +160 -0
- qiskit/transpiler/passes/calibration/rzx_builder.py +394 -0
- qiskit/transpiler/passes/calibration/rzx_templates.py +51 -0
- qiskit/transpiler/passes/layout/__init__.py +27 -0
- qiskit/transpiler/passes/layout/_csp_custom_solver.py +65 -0
- qiskit/transpiler/passes/layout/apply_layout.py +108 -0
- qiskit/transpiler/passes/layout/csp_layout.py +132 -0
- qiskit/transpiler/passes/layout/dense_layout.py +202 -0
- qiskit/transpiler/passes/layout/disjoint_utils.py +205 -0
- qiskit/transpiler/passes/layout/enlarge_with_ancilla.py +49 -0
- qiskit/transpiler/passes/layout/full_ancilla_allocation.py +117 -0
- qiskit/transpiler/passes/layout/layout_2q_distance.py +77 -0
- qiskit/transpiler/passes/layout/noise_adaptive_layout.py +311 -0
- qiskit/transpiler/passes/layout/sabre_layout.py +468 -0
- qiskit/transpiler/passes/layout/sabre_pre_layout.py +217 -0
- qiskit/transpiler/passes/layout/set_layout.py +64 -0
- qiskit/transpiler/passes/layout/trivial_layout.py +66 -0
- qiskit/transpiler/passes/layout/vf2_layout.py +257 -0
- qiskit/transpiler/passes/layout/vf2_post_layout.py +419 -0
- qiskit/transpiler/passes/layout/vf2_utils.py +260 -0
- qiskit/transpiler/passes/optimization/__init__.py +38 -0
- qiskit/transpiler/passes/optimization/_gate_extension.py +80 -0
- qiskit/transpiler/passes/optimization/collect_1q_runs.py +31 -0
- qiskit/transpiler/passes/optimization/collect_2q_blocks.py +35 -0
- qiskit/transpiler/passes/optimization/collect_and_collapse.py +115 -0
- qiskit/transpiler/passes/optimization/collect_cliffords.py +97 -0
- qiskit/transpiler/passes/optimization/collect_linear_functions.py +80 -0
- qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +227 -0
- qiskit/transpiler/passes/optimization/commutation_analysis.py +93 -0
- qiskit/transpiler/passes/optimization/commutative_cancellation.py +207 -0
- qiskit/transpiler/passes/optimization/commutative_inverse_cancellation.py +97 -0
- qiskit/transpiler/passes/optimization/consolidate_blocks.py +219 -0
- qiskit/transpiler/passes/optimization/crosstalk_adaptive_schedule.py +732 -0
- qiskit/transpiler/passes/optimization/cx_cancellation.py +55 -0
- qiskit/transpiler/passes/optimization/echo_rzx_weyl_decomposition.py +160 -0
- qiskit/transpiler/passes/optimization/hoare_opt.py +416 -0
- qiskit/transpiler/passes/optimization/inverse_cancellation.py +177 -0
- qiskit/transpiler/passes/optimization/normalize_rx_angle.py +149 -0
- qiskit/transpiler/passes/optimization/optimize_1q_commutation.py +268 -0
- qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +263 -0
- qiskit/transpiler/passes/optimization/optimize_1q_gates.py +384 -0
- qiskit/transpiler/passes/optimization/optimize_cliffords.py +89 -0
- qiskit/transpiler/passes/optimization/optimize_swap_before_measure.py +71 -0
- qiskit/transpiler/passes/optimization/remove_diagonal_gates_before_measure.py +69 -0
- qiskit/transpiler/passes/optimization/remove_reset_in_zero_state.py +37 -0
- qiskit/transpiler/passes/optimization/reset_after_measure_simplification.py +47 -0
- qiskit/transpiler/passes/optimization/template_matching/__init__.py +19 -0
- qiskit/transpiler/passes/optimization/template_matching/backward_match.py +749 -0
- qiskit/transpiler/passes/optimization/template_matching/forward_match.py +454 -0
- qiskit/transpiler/passes/optimization/template_matching/maximal_matches.py +77 -0
- qiskit/transpiler/passes/optimization/template_matching/template_matching.py +370 -0
- qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +629 -0
- qiskit/transpiler/passes/optimization/template_optimization.py +158 -0
- qiskit/transpiler/passes/routing/__init__.py +21 -0
- qiskit/transpiler/passes/routing/algorithms/__init__.py +33 -0
- qiskit/transpiler/passes/routing/algorithms/token_swapper.py +105 -0
- qiskit/transpiler/passes/routing/algorithms/types.py +46 -0
- qiskit/transpiler/passes/routing/algorithms/util.py +103 -0
- qiskit/transpiler/passes/routing/basic_swap.py +155 -0
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/__init__.py +25 -0
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_block.py +60 -0
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +387 -0
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/pauli_2q_evolution_commutation.py +141 -0
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/swap_strategy.py +306 -0
- qiskit/transpiler/passes/routing/layout_transformation.py +118 -0
- qiskit/transpiler/passes/routing/lookahead_swap.py +384 -0
- qiskit/transpiler/passes/routing/sabre_swap.py +430 -0
- qiskit/transpiler/passes/routing/stochastic_swap.py +512 -0
- qiskit/transpiler/passes/routing/utils.py +35 -0
- qiskit/transpiler/passes/scheduling/__init__.py +27 -0
- qiskit/transpiler/passes/scheduling/alap.py +155 -0
- qiskit/transpiler/passes/scheduling/alignments/__init__.py +81 -0
- qiskit/transpiler/passes/scheduling/alignments/align_measures.py +256 -0
- qiskit/transpiler/passes/scheduling/alignments/check_durations.py +75 -0
- qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +97 -0
- qiskit/transpiler/passes/scheduling/alignments/reschedule.py +241 -0
- qiskit/transpiler/passes/scheduling/asap.py +177 -0
- qiskit/transpiler/passes/scheduling/base_scheduler.py +289 -0
- qiskit/transpiler/passes/scheduling/calibration_creators.py +27 -0
- qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +285 -0
- qiskit/transpiler/passes/scheduling/padding/__init__.py +16 -0
- qiskit/transpiler/passes/scheduling/padding/base_padding.py +256 -0
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +408 -0
- qiskit/transpiler/passes/scheduling/padding/pad_delay.py +79 -0
- qiskit/transpiler/passes/scheduling/rzx_templates.py +28 -0
- qiskit/transpiler/passes/scheduling/scheduling/__init__.py +17 -0
- qiskit/transpiler/passes/scheduling/scheduling/alap.py +127 -0
- qiskit/transpiler/passes/scheduling/scheduling/asap.py +131 -0
- qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +89 -0
- qiskit/transpiler/passes/scheduling/scheduling/set_io_latency.py +64 -0
- qiskit/transpiler/passes/scheduling/time_unit_conversion.py +135 -0
- qiskit/transpiler/passes/synthesis/__init__.py +19 -0
- qiskit/transpiler/passes/synthesis/high_level_synthesis.py +637 -0
- qiskit/transpiler/passes/synthesis/linear_functions_synthesis.py +63 -0
- qiskit/transpiler/passes/synthesis/plugin.py +597 -0
- qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +289 -0
- qiskit/transpiler/passes/synthesis/unitary_synthesis.py +895 -0
- qiskit/transpiler/passes/utils/__init__.py +34 -0
- qiskit/transpiler/passes/utils/barrier_before_final_measurements.py +95 -0
- qiskit/transpiler/passes/utils/block_to_matrix.py +47 -0
- qiskit/transpiler/passes/utils/check_gate_direction.py +87 -0
- qiskit/transpiler/passes/utils/check_map.py +94 -0
- qiskit/transpiler/passes/utils/contains_instruction.py +45 -0
- qiskit/transpiler/passes/utils/control_flow.py +61 -0
- qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +89 -0
- qiskit/transpiler/passes/utils/dag_fixed_point.py +36 -0
- qiskit/transpiler/passes/utils/error.py +69 -0
- qiskit/transpiler/passes/utils/filter_op_nodes.py +65 -0
- qiskit/transpiler/passes/utils/fixed_point.py +48 -0
- qiskit/transpiler/passes/utils/gate_direction.py +347 -0
- qiskit/transpiler/passes/utils/gates_basis.py +75 -0
- qiskit/transpiler/passes/utils/merge_adjacent_barriers.py +162 -0
- qiskit/transpiler/passes/utils/minimum_point.py +118 -0
- qiskit/transpiler/passes/utils/remove_barriers.py +49 -0
- qiskit/transpiler/passes/utils/remove_final_measurements.py +114 -0
- qiskit/transpiler/passes/utils/unroll_forloops.py +81 -0
- qiskit/transpiler/passmanager.py +617 -0
- qiskit/transpiler/passmanager_config.py +193 -0
- qiskit/transpiler/preset_passmanagers/__init__.py +280 -0
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +971 -0
- qiskit/transpiler/preset_passmanagers/common.py +651 -0
- qiskit/transpiler/preset_passmanagers/level0.py +113 -0
- qiskit/transpiler/preset_passmanagers/level1.py +120 -0
- qiskit/transpiler/preset_passmanagers/level2.py +119 -0
- qiskit/transpiler/preset_passmanagers/level3.py +119 -0
- qiskit/transpiler/preset_passmanagers/plugin.py +345 -0
- qiskit/transpiler/propertyset.py +19 -0
- qiskit/transpiler/runningpassmanager.py +174 -0
- qiskit/transpiler/synthesis/__init__.py +16 -0
- qiskit/transpiler/synthesis/aqc/__init__.py +178 -0
- qiskit/transpiler/synthesis/aqc/approximate.py +116 -0
- qiskit/transpiler/synthesis/aqc/aqc.py +170 -0
- qiskit/transpiler/synthesis/aqc/aqc_plugin.py +146 -0
- qiskit/transpiler/synthesis/aqc/cnot_structures.py +299 -0
- qiskit/transpiler/synthesis/aqc/cnot_unit_circuit.py +103 -0
- qiskit/transpiler/synthesis/aqc/cnot_unit_objective.py +299 -0
- qiskit/transpiler/synthesis/aqc/elementary_operations.py +108 -0
- qiskit/transpiler/synthesis/aqc/fast_gradient/__init__.py +164 -0
- qiskit/transpiler/synthesis/aqc/fast_gradient/fast_grad_utils.py +237 -0
- qiskit/transpiler/synthesis/aqc/fast_gradient/fast_gradient.py +225 -0
- qiskit/transpiler/synthesis/aqc/fast_gradient/layer.py +370 -0
- qiskit/transpiler/synthesis/aqc/fast_gradient/pmatrix.py +312 -0
- qiskit/transpiler/synthesis/graysynth.py +114 -0
- qiskit/transpiler/target.py +1540 -0
- qiskit/transpiler/timing_constraints.py +59 -0
- qiskit/user_config.py +239 -0
- qiskit/utils/__init__.py +66 -0
- qiskit/utils/classtools.py +146 -0
- qiskit/utils/deprecation.py +489 -0
- qiskit/utils/lazy_tester.py +334 -0
- qiskit/utils/multiprocessing.py +48 -0
- qiskit/utils/optionals.py +320 -0
- qiskit/utils/units.py +143 -0
- qiskit/version.py +84 -0
- qiskit/visualization/__init__.py +289 -0
- qiskit/visualization/array.py +204 -0
- qiskit/visualization/bloch.py +741 -0
- qiskit/visualization/circuit/__init__.py +15 -0
- qiskit/visualization/circuit/_utils.py +633 -0
- qiskit/visualization/circuit/circuit_visualization.py +717 -0
- qiskit/visualization/circuit/latex.py +659 -0
- qiskit/visualization/circuit/matplotlib.py +1975 -0
- qiskit/visualization/circuit/qcstyle.py +420 -0
- qiskit/visualization/circuit/styles/bw.json +202 -0
- qiskit/visualization/circuit/styles/clifford.json +202 -0
- qiskit/visualization/circuit/styles/iqp-dark.json +214 -0
- qiskit/visualization/circuit/styles/iqp.json +214 -0
- qiskit/visualization/circuit/styles/textbook.json +202 -0
- qiskit/visualization/circuit/text.py +1802 -0
- qiskit/visualization/circuit_visualization.py +19 -0
- qiskit/visualization/counts_visualization.py +496 -0
- qiskit/visualization/dag_visualization.py +224 -0
- qiskit/visualization/exceptions.py +21 -0
- qiskit/visualization/gate_map.py +1461 -0
- qiskit/visualization/pass_manager_visualization.py +281 -0
- qiskit/visualization/pulse_v2/__init__.py +21 -0
- qiskit/visualization/pulse_v2/core.py +905 -0
- qiskit/visualization/pulse_v2/device_info.py +146 -0
- qiskit/visualization/pulse_v2/drawings.py +253 -0
- qiskit/visualization/pulse_v2/events.py +254 -0
- qiskit/visualization/pulse_v2/generators/__init__.py +40 -0
- qiskit/visualization/pulse_v2/generators/barrier.py +76 -0
- qiskit/visualization/pulse_v2/generators/chart.py +208 -0
- qiskit/visualization/pulse_v2/generators/frame.py +437 -0
- qiskit/visualization/pulse_v2/generators/snapshot.py +133 -0
- qiskit/visualization/pulse_v2/generators/waveform.py +649 -0
- qiskit/visualization/pulse_v2/interface.py +452 -0
- qiskit/visualization/pulse_v2/layouts.py +395 -0
- qiskit/visualization/pulse_v2/plotters/__init__.py +17 -0
- qiskit/visualization/pulse_v2/plotters/base_plotter.py +53 -0
- qiskit/visualization/pulse_v2/plotters/matplotlib.py +202 -0
- qiskit/visualization/pulse_v2/stylesheet.py +322 -0
- qiskit/visualization/pulse_v2/types.py +242 -0
- qiskit/visualization/qcstyle.py +17 -0
- qiskit/visualization/state_visualization.py +1518 -0
- qiskit/visualization/timeline/__init__.py +21 -0
- qiskit/visualization/timeline/core.py +457 -0
- qiskit/visualization/timeline/drawings.py +260 -0
- qiskit/visualization/timeline/generators.py +506 -0
- qiskit/visualization/timeline/interface.py +414 -0
- qiskit/visualization/timeline/layouts.py +115 -0
- qiskit/visualization/timeline/plotters/__init__.py +16 -0
- qiskit/visualization/timeline/plotters/base_plotter.py +58 -0
- qiskit/visualization/timeline/plotters/matplotlib.py +193 -0
- qiskit/visualization/timeline/stylesheet.py +311 -0
- qiskit/visualization/timeline/types.py +148 -0
- qiskit/visualization/transition_visualization.py +364 -0
- qiskit/visualization/utils.py +49 -0
- qiskit-1.0.0b1.dist-info/LICENSE.txt +203 -0
- qiskit-1.0.0b1.dist-info/METADATA +430 -0
- qiskit-1.0.0b1.dist-info/RECORD +1095 -0
- qiskit-1.0.0b1.dist-info/WHEEL +6 -0
- qiskit-1.0.0b1.dist-info/entry_points.txt +49 -0
- qiskit-1.0.0b1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1567 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2017, 2019.
|
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
|
+
# pylint: disable=invalid-name
|
14
|
+
|
15
|
+
"""
|
16
|
+
Expand 2-qubit Unitary operators into an equivalent
|
17
|
+
decomposition over SU(2)+fixed 2q basis gate, using the KAK method.
|
18
|
+
|
19
|
+
May be exact or approximate expansion. In either case uses the minimal
|
20
|
+
number of basis applications.
|
21
|
+
|
22
|
+
Method is described in Appendix B of Cross, A. W., Bishop, L. S., Sheldon, S., Nation, P. D. &
|
23
|
+
Gambetta, J. M. Validating quantum computers using randomized model circuits.
|
24
|
+
arXiv:1811.12926 [quant-ph] (2018).
|
25
|
+
"""
|
26
|
+
from __future__ import annotations
|
27
|
+
import cmath
|
28
|
+
import math
|
29
|
+
import io
|
30
|
+
import base64
|
31
|
+
import warnings
|
32
|
+
from typing import ClassVar, Optional, Type
|
33
|
+
|
34
|
+
import logging
|
35
|
+
|
36
|
+
import numpy as np
|
37
|
+
|
38
|
+
from qiskit.circuit import QuantumRegister, QuantumCircuit, Gate
|
39
|
+
from qiskit.circuit.library.standard_gates import CXGate, RXGate, RYGate, RZGate
|
40
|
+
from qiskit.exceptions import QiskitError
|
41
|
+
from qiskit.quantum_info.operators import Operator
|
42
|
+
from qiskit.quantum_info.synthesis.weyl import weyl_coordinates, transform_to_magic_basis
|
43
|
+
from qiskit.quantum_info.synthesis.one_qubit_decompose import (
|
44
|
+
OneQubitEulerDecomposer,
|
45
|
+
DEFAULT_ATOL,
|
46
|
+
)
|
47
|
+
from qiskit.utils.deprecation import deprecate_arg
|
48
|
+
|
49
|
+
|
50
|
+
logger = logging.getLogger(__name__)
|
51
|
+
|
52
|
+
|
53
|
+
def decompose_two_qubit_product_gate(special_unitary_matrix):
|
54
|
+
"""Decompose U = Ul⊗Ur where U in SU(4), and Ul, Ur in SU(2).
|
55
|
+
Throws QiskitError if this isn't possible.
|
56
|
+
"""
|
57
|
+
special_unitary_matrix = np.asarray(special_unitary_matrix, dtype=complex)
|
58
|
+
# extract the right component
|
59
|
+
R = special_unitary_matrix[:2, :2].copy()
|
60
|
+
detR = R[0, 0] * R[1, 1] - R[0, 1] * R[1, 0]
|
61
|
+
if abs(detR) < 0.1:
|
62
|
+
R = special_unitary_matrix[2:, :2].copy()
|
63
|
+
detR = R[0, 0] * R[1, 1] - R[0, 1] * R[1, 0]
|
64
|
+
if abs(detR) < 0.1:
|
65
|
+
raise QiskitError("decompose_two_qubit_product_gate: unable to decompose: detR < 0.1")
|
66
|
+
R /= np.sqrt(detR)
|
67
|
+
|
68
|
+
# extract the left component
|
69
|
+
temp = np.kron(np.eye(2), R.T.conj())
|
70
|
+
temp = special_unitary_matrix.dot(temp)
|
71
|
+
L = temp[::2, ::2]
|
72
|
+
detL = L[0, 0] * L[1, 1] - L[0, 1] * L[1, 0]
|
73
|
+
if abs(detL) < 0.9:
|
74
|
+
raise QiskitError("decompose_two_qubit_product_gate: unable to decompose: detL < 0.9")
|
75
|
+
L /= np.sqrt(detL)
|
76
|
+
phase = cmath.phase(detL) / 2
|
77
|
+
|
78
|
+
temp = np.kron(L, R)
|
79
|
+
deviation = abs(abs(temp.conj().T.dot(special_unitary_matrix).trace()) - 4)
|
80
|
+
if deviation > 1.0e-13:
|
81
|
+
raise QiskitError(
|
82
|
+
"decompose_two_qubit_product_gate: decomposition failed: "
|
83
|
+
"deviation too large: {}".format(deviation)
|
84
|
+
)
|
85
|
+
|
86
|
+
return L, R, phase
|
87
|
+
|
88
|
+
|
89
|
+
_ipx = np.array([[0, 1j], [1j, 0]], dtype=complex)
|
90
|
+
_ipy = np.array([[0, 1], [-1, 0]], dtype=complex)
|
91
|
+
_ipz = np.array([[1j, 0], [0, -1j]], dtype=complex)
|
92
|
+
_id = np.array([[1, 0], [0, 1]], dtype=complex)
|
93
|
+
|
94
|
+
|
95
|
+
class TwoQubitWeylDecomposition:
|
96
|
+
"""Decompose two-qubit unitary U = (K1l⊗K1r).Exp(i a xx + i b yy + i c zz).(K2l⊗K2r) , where U ∈
|
97
|
+
U(4), (K1l|K1r|K2l|K2r) ∈ SU(2), and we stay in the "Weyl Chamber" 𝜋/4 ≥ a ≥ b ≥ |c|
|
98
|
+
|
99
|
+
This is an abstract factory class that instantiates itself as specialized subclasses based on
|
100
|
+
the fidelity, such that the approximation error from specialization has an average gate fidelity
|
101
|
+
at least as high as requested. The specialized subclasses have unique canonical representations
|
102
|
+
thus avoiding problems of numerical stability.
|
103
|
+
|
104
|
+
Passing non-None fidelity to specializations is treated as an assertion, raising QiskitError if
|
105
|
+
forcing the specialization is more approximate than asserted.
|
106
|
+
"""
|
107
|
+
|
108
|
+
# The parameters of the decomposition:
|
109
|
+
a: float
|
110
|
+
b: float
|
111
|
+
c: float
|
112
|
+
global_phase: float
|
113
|
+
K1l: np.ndarray
|
114
|
+
K2l: np.ndarray
|
115
|
+
K1r: np.ndarray
|
116
|
+
K2r: np.ndarray
|
117
|
+
|
118
|
+
unitary_matrix: np.ndarray # The unitary that was input
|
119
|
+
requested_fidelity: Optional[float] # None means no automatic specialization
|
120
|
+
calculated_fidelity: float # Fidelity after specialization
|
121
|
+
|
122
|
+
_original_decomposition: "TwoQubitWeylDecomposition"
|
123
|
+
_is_flipped_from_original: bool # The approx is closest to a Weyl reflection of the original?
|
124
|
+
|
125
|
+
_default_1q_basis: ClassVar[str] = "ZYZ" # Default one qubit basis (explicit parameterization)
|
126
|
+
|
127
|
+
def __init_subclass__(cls, **kwargs):
|
128
|
+
"""Subclasses should be concrete, not factories.
|
129
|
+
|
130
|
+
Make explicitly-instantiated subclass __new__ call base __new__ with fidelity=None"""
|
131
|
+
super().__init_subclass__(**kwargs)
|
132
|
+
cls.__new__ = lambda cls, *a, fidelity=None, **k: TwoQubitWeylDecomposition.__new__(
|
133
|
+
cls, *a, fidelity=None, **k
|
134
|
+
)
|
135
|
+
|
136
|
+
@staticmethod
|
137
|
+
def __new__(cls, unitary_matrix, *, fidelity=(1.0 - 1.0e-9), _unpickling=False):
|
138
|
+
"""Perform the Weyl chamber decomposition, and optionally choose a specialized subclass.
|
139
|
+
|
140
|
+
The flip into the Weyl Chamber is described in B. Kraus and J. I. Cirac, Phys. Rev. A 63,
|
141
|
+
062309 (2001).
|
142
|
+
|
143
|
+
FIXME: There's a cleaner-seeming method based on choosing branch cuts carefully, in Andrew
|
144
|
+
M. Childs, Henry L. Haselgrove, and Michael A. Nielsen, Phys. Rev. A 68, 052311, but I
|
145
|
+
wasn't able to get that to work.
|
146
|
+
|
147
|
+
The overall decomposition scheme is taken from Drury and Love, arXiv:0806.4015 [quant-ph].
|
148
|
+
"""
|
149
|
+
if _unpickling:
|
150
|
+
return super().__new__(cls)
|
151
|
+
|
152
|
+
pi = np.pi
|
153
|
+
pi2 = np.pi / 2
|
154
|
+
pi4 = np.pi / 4
|
155
|
+
|
156
|
+
# Make U be in SU(4)
|
157
|
+
U = np.array(unitary_matrix, dtype=complex, copy=True)
|
158
|
+
detU = np.linalg.det(U)
|
159
|
+
U *= detU ** (-0.25)
|
160
|
+
global_phase = cmath.phase(detU) / 4
|
161
|
+
|
162
|
+
Up = transform_to_magic_basis(U, reverse=True)
|
163
|
+
M2 = Up.T.dot(Up)
|
164
|
+
|
165
|
+
# M2 is a symmetric complex matrix. We need to decompose it as M2 = P D P^T where
|
166
|
+
# P ∈ SO(4), D is diagonal with unit-magnitude elements.
|
167
|
+
#
|
168
|
+
# We can't use raw `eig` directly because it isn't guaranteed to give us real or othogonal
|
169
|
+
# eigenvectors. Instead, since `M2` is complex-symmetric,
|
170
|
+
# M2 = A + iB
|
171
|
+
# for real-symmetric `A` and `B`, and as
|
172
|
+
# M2^+ @ M2 = A^2 + B^2 + i [A, B] = 1
|
173
|
+
# we must have `A` and `B` commute, and consequently they are simultaneously diagonalizable.
|
174
|
+
# Mixing them together _should_ account for any degeneracy problems, but it's not
|
175
|
+
# guaranteed, so we repeat it a little bit. The fixed seed is to make failures
|
176
|
+
# deterministic; the value is not important.
|
177
|
+
state = np.random.default_rng(2020)
|
178
|
+
for _ in range(100): # FIXME: this randomized algorithm is horrendous
|
179
|
+
M2real = state.normal() * M2.real + state.normal() * M2.imag
|
180
|
+
_, P = np.linalg.eigh(M2real)
|
181
|
+
D = P.T.dot(M2).dot(P).diagonal()
|
182
|
+
if np.allclose(P.dot(np.diag(D)).dot(P.T), M2, rtol=0, atol=1.0e-13):
|
183
|
+
break
|
184
|
+
else:
|
185
|
+
raise QiskitError(
|
186
|
+
"TwoQubitWeylDecomposition: failed to diagonalize M2."
|
187
|
+
" Please report this at https://github.com/Qiskit/qiskit-terra/issues/4159."
|
188
|
+
f" Input: {U.tolist()}"
|
189
|
+
)
|
190
|
+
|
191
|
+
d = -np.angle(D) / 2
|
192
|
+
d[3] = -d[0] - d[1] - d[2]
|
193
|
+
cs = np.mod((d[:3] + d[3]) / 2, 2 * np.pi)
|
194
|
+
|
195
|
+
# Reorder the eigenvalues to get in the Weyl chamber
|
196
|
+
cstemp = np.mod(cs, pi2)
|
197
|
+
np.minimum(cstemp, pi2 - cstemp, cstemp)
|
198
|
+
order = np.argsort(cstemp)[[1, 2, 0]]
|
199
|
+
cs = cs[order]
|
200
|
+
d[:3] = d[order]
|
201
|
+
P[:, :3] = P[:, order]
|
202
|
+
|
203
|
+
# Fix the sign of P to be in SO(4)
|
204
|
+
if np.real(np.linalg.det(P)) < 0:
|
205
|
+
P[:, -1] = -P[:, -1]
|
206
|
+
|
207
|
+
# Find K1, K2 so that U = K1.A.K2, with K being product of single-qubit unitaries
|
208
|
+
K1 = transform_to_magic_basis(Up @ P @ np.diag(np.exp(1j * d)))
|
209
|
+
K2 = transform_to_magic_basis(P.T)
|
210
|
+
|
211
|
+
K1l, K1r, phase_l = decompose_two_qubit_product_gate(K1)
|
212
|
+
K2l, K2r, phase_r = decompose_two_qubit_product_gate(K2)
|
213
|
+
global_phase += phase_l + phase_r
|
214
|
+
|
215
|
+
K1l = K1l.copy()
|
216
|
+
|
217
|
+
# Flip into Weyl chamber
|
218
|
+
if cs[0] > pi2:
|
219
|
+
cs[0] -= 3 * pi2
|
220
|
+
K1l = K1l.dot(_ipy)
|
221
|
+
K1r = K1r.dot(_ipy)
|
222
|
+
global_phase += pi2
|
223
|
+
if cs[1] > pi2:
|
224
|
+
cs[1] -= 3 * pi2
|
225
|
+
K1l = K1l.dot(_ipx)
|
226
|
+
K1r = K1r.dot(_ipx)
|
227
|
+
global_phase += pi2
|
228
|
+
conjs = 0
|
229
|
+
if cs[0] > pi4:
|
230
|
+
cs[0] = pi2 - cs[0]
|
231
|
+
K1l = K1l.dot(_ipy)
|
232
|
+
K2r = _ipy.dot(K2r)
|
233
|
+
conjs += 1
|
234
|
+
global_phase -= pi2
|
235
|
+
if cs[1] > pi4:
|
236
|
+
cs[1] = pi2 - cs[1]
|
237
|
+
K1l = K1l.dot(_ipx)
|
238
|
+
K2r = _ipx.dot(K2r)
|
239
|
+
conjs += 1
|
240
|
+
global_phase += pi2
|
241
|
+
if conjs == 1:
|
242
|
+
global_phase -= pi
|
243
|
+
if cs[2] > pi2:
|
244
|
+
cs[2] -= 3 * pi2
|
245
|
+
K1l = K1l.dot(_ipz)
|
246
|
+
K1r = K1r.dot(_ipz)
|
247
|
+
global_phase += pi2
|
248
|
+
if conjs == 1:
|
249
|
+
global_phase -= pi
|
250
|
+
if conjs == 1:
|
251
|
+
cs[2] = pi2 - cs[2]
|
252
|
+
K1l = K1l.dot(_ipz)
|
253
|
+
K2r = _ipz.dot(K2r)
|
254
|
+
global_phase += pi2
|
255
|
+
if cs[2] > pi4:
|
256
|
+
cs[2] -= pi2
|
257
|
+
K1l = K1l.dot(_ipz)
|
258
|
+
K1r = K1r.dot(_ipz)
|
259
|
+
global_phase -= pi2
|
260
|
+
|
261
|
+
a, b, c = cs[1], cs[0], cs[2]
|
262
|
+
|
263
|
+
# Save the non-specialized decomposition for later comparison
|
264
|
+
od = super().__new__(TwoQubitWeylDecomposition)
|
265
|
+
od.a = a
|
266
|
+
od.b = b
|
267
|
+
od.c = c
|
268
|
+
od.K1l = K1l
|
269
|
+
od.K1r = K1r
|
270
|
+
od.K2l = K2l
|
271
|
+
od.K2r = K2r
|
272
|
+
od.global_phase = global_phase
|
273
|
+
od.requested_fidelity = fidelity
|
274
|
+
od.calculated_fidelity = 1.0
|
275
|
+
od.unitary_matrix = np.array(unitary_matrix, dtype=complex, copy=True)
|
276
|
+
od.unitary_matrix.setflags(write=False)
|
277
|
+
od._original_decomposition = None
|
278
|
+
od._is_flipped_from_original = False
|
279
|
+
|
280
|
+
def is_close(ap, bp, cp):
|
281
|
+
da, db, dc = a - ap, b - bp, c - cp
|
282
|
+
tr = 4 * complex(
|
283
|
+
math.cos(da) * math.cos(db) * math.cos(dc),
|
284
|
+
math.sin(da) * math.sin(db) * math.sin(dc),
|
285
|
+
)
|
286
|
+
fid = trace_to_fid(tr)
|
287
|
+
return fid >= fidelity
|
288
|
+
|
289
|
+
if fidelity is None: # Don't specialize if None
|
290
|
+
instance = super().__new__(
|
291
|
+
TwoQubitWeylGeneral if cls is TwoQubitWeylDecomposition else cls
|
292
|
+
)
|
293
|
+
elif is_close(0, 0, 0):
|
294
|
+
instance = super().__new__(TwoQubitWeylIdEquiv)
|
295
|
+
elif is_close(pi4, pi4, pi4) or is_close(pi4, pi4, -pi4):
|
296
|
+
instance = super().__new__(TwoQubitWeylSWAPEquiv)
|
297
|
+
elif (lambda x: is_close(x, x, x))(_closest_partial_swap(a, b, c)):
|
298
|
+
instance = super().__new__(TwoQubitWeylPartialSWAPEquiv)
|
299
|
+
elif (lambda x: is_close(x, x, -x))(_closest_partial_swap(a, b, -c)):
|
300
|
+
instance = super().__new__(TwoQubitWeylPartialSWAPFlipEquiv)
|
301
|
+
elif is_close(a, 0, 0):
|
302
|
+
instance = super().__new__(TwoQubitWeylControlledEquiv)
|
303
|
+
elif is_close(pi4, pi4, c):
|
304
|
+
instance = super().__new__(TwoQubitWeylMirrorControlledEquiv)
|
305
|
+
elif is_close((a + b) / 2, (a + b) / 2, c):
|
306
|
+
instance = super().__new__(TwoQubitWeylfSimaabEquiv)
|
307
|
+
elif is_close(a, (b + c) / 2, (b + c) / 2):
|
308
|
+
instance = super().__new__(TwoQubitWeylfSimabbEquiv)
|
309
|
+
elif is_close(a, (b - c) / 2, (c - b) / 2):
|
310
|
+
instance = super().__new__(TwoQubitWeylfSimabmbEquiv)
|
311
|
+
else:
|
312
|
+
instance = super().__new__(TwoQubitWeylGeneral)
|
313
|
+
|
314
|
+
instance._original_decomposition = od
|
315
|
+
return instance
|
316
|
+
|
317
|
+
def __init__(self, unitary_matrix, fidelity=None):
|
318
|
+
del unitary_matrix # unused in __init__ (used in new)
|
319
|
+
od = self._original_decomposition
|
320
|
+
self.a, self.b, self.c = od.a, od.b, od.c
|
321
|
+
self.K1l, self.K1r = od.K1l, od.K1r
|
322
|
+
self.K2l, self.K2r = od.K2l, od.K2r
|
323
|
+
self.global_phase = od.global_phase
|
324
|
+
self.unitary_matrix = od.unitary_matrix
|
325
|
+
self.requested_fidelity = fidelity
|
326
|
+
self._is_flipped_from_original = False
|
327
|
+
self.specialize()
|
328
|
+
|
329
|
+
# Update the phase after specialization:
|
330
|
+
if self._is_flipped_from_original:
|
331
|
+
da, db, dc = (np.pi / 2 - od.a) - self.a, od.b - self.b, -od.c - self.c
|
332
|
+
tr = 4 * complex(
|
333
|
+
math.cos(da) * math.cos(db) * math.cos(dc),
|
334
|
+
math.sin(da) * math.sin(db) * math.sin(dc),
|
335
|
+
)
|
336
|
+
else:
|
337
|
+
da, db, dc = od.a - self.a, od.b - self.b, od.c - self.c
|
338
|
+
tr = 4 * complex(
|
339
|
+
math.cos(da) * math.cos(db) * math.cos(dc),
|
340
|
+
math.sin(da) * math.sin(db) * math.sin(dc),
|
341
|
+
)
|
342
|
+
self.global_phase += cmath.phase(tr)
|
343
|
+
self.calculated_fidelity = trace_to_fid(tr)
|
344
|
+
if logger.isEnabledFor(logging.DEBUG):
|
345
|
+
actual_fidelity = self.actual_fidelity()
|
346
|
+
logger.debug(
|
347
|
+
"Requested fidelity: %s calculated fidelity: %s actual fidelity %s",
|
348
|
+
self.requested_fidelity,
|
349
|
+
self.calculated_fidelity,
|
350
|
+
actual_fidelity,
|
351
|
+
)
|
352
|
+
if abs(self.calculated_fidelity - actual_fidelity) > 1.0e-12:
|
353
|
+
logger.warning(
|
354
|
+
"Requested fidelity different from actual by %s",
|
355
|
+
self.calculated_fidelity - actual_fidelity,
|
356
|
+
)
|
357
|
+
if self.requested_fidelity and self.calculated_fidelity + 1.0e-13 < self.requested_fidelity:
|
358
|
+
raise QiskitError(
|
359
|
+
f"{self.__class__.__name__}: "
|
360
|
+
f"calculated fidelity: {self.calculated_fidelity} "
|
361
|
+
f"is worse than requested fidelity: {self.requested_fidelity}."
|
362
|
+
)
|
363
|
+
|
364
|
+
def specialize(self):
|
365
|
+
"""Make changes to the decomposition to comply with any specialization.
|
366
|
+
|
367
|
+
Do update a, b, c, k1l, k1r, k2l, k2r, _is_flipped_from_original to round to the
|
368
|
+
specialization. Do not update the global phase, since this gets done in generic
|
369
|
+
__init__()"""
|
370
|
+
raise NotImplementedError
|
371
|
+
|
372
|
+
def circuit(
|
373
|
+
self, *, euler_basis: str | None = None, simplify=False, atol=DEFAULT_ATOL
|
374
|
+
) -> QuantumCircuit:
|
375
|
+
"""Returns Weyl decomposition in circuit form.
|
376
|
+
|
377
|
+
simplify, atol arguments are passed to OneQubitEulerDecomposer"""
|
378
|
+
if euler_basis is None:
|
379
|
+
euler_basis = self._default_1q_basis
|
380
|
+
oneq_decompose = OneQubitEulerDecomposer(euler_basis)
|
381
|
+
c1l, c1r, c2l, c2r = (
|
382
|
+
oneq_decompose(k, simplify=simplify, atol=atol)
|
383
|
+
for k in (self.K1l, self.K1r, self.K2l, self.K2r)
|
384
|
+
)
|
385
|
+
circ = QuantumCircuit(2, global_phase=self.global_phase)
|
386
|
+
circ.compose(c2r, [0], inplace=True)
|
387
|
+
circ.compose(c2l, [1], inplace=True)
|
388
|
+
self._weyl_gate(simplify, circ, atol)
|
389
|
+
circ.compose(c1r, [0], inplace=True)
|
390
|
+
circ.compose(c1l, [1], inplace=True)
|
391
|
+
return circ
|
392
|
+
|
393
|
+
def _weyl_gate(self, simplify, circ: QuantumCircuit, atol):
|
394
|
+
"""Appends Ud(a, b, c) to the circuit.
|
395
|
+
|
396
|
+
Can be overridden in subclasses for special cases"""
|
397
|
+
if not simplify or abs(self.a) > atol:
|
398
|
+
circ.rxx(-self.a * 2, 0, 1)
|
399
|
+
if not simplify or abs(self.b) > atol:
|
400
|
+
circ.ryy(-self.b * 2, 0, 1)
|
401
|
+
if not simplify or abs(self.c) > atol:
|
402
|
+
circ.rzz(-self.c * 2, 0, 1)
|
403
|
+
|
404
|
+
def actual_fidelity(self, **kwargs) -> float:
|
405
|
+
"""Calculates the actual fidelity of the decomposed circuit to the input unitary"""
|
406
|
+
circ = self.circuit(**kwargs)
|
407
|
+
trace = np.trace(Operator(circ).data.T.conj() @ self.unitary_matrix)
|
408
|
+
return trace_to_fid(trace)
|
409
|
+
|
410
|
+
def __getnewargs_ex__(self):
|
411
|
+
return (self.unitary_matrix,), {"_unpickling": True}
|
412
|
+
|
413
|
+
def __repr__(self):
|
414
|
+
"""Represent with enough precision to allow copy-paste debugging of all corner cases"""
|
415
|
+
prefix = f"{type(self).__qualname__}.from_bytes("
|
416
|
+
with io.BytesIO() as f:
|
417
|
+
np.save(f, self.unitary_matrix, allow_pickle=False)
|
418
|
+
b64 = base64.encodebytes(f.getvalue()).splitlines()
|
419
|
+
b64ascii = [repr(x) for x in b64]
|
420
|
+
b64ascii[-1] += ","
|
421
|
+
pretty = [f"# {x.rstrip()}" for x in str(self).splitlines()]
|
422
|
+
indent = "\n" + " " * 4
|
423
|
+
lines = (
|
424
|
+
[prefix]
|
425
|
+
+ pretty
|
426
|
+
+ b64ascii
|
427
|
+
+ [
|
428
|
+
f"requested_fidelity={self.requested_fidelity},",
|
429
|
+
f"calculated_fidelity={self.calculated_fidelity},",
|
430
|
+
f"actual_fidelity={self.actual_fidelity()},",
|
431
|
+
f"abc={(self.a, self.b, self.c)})",
|
432
|
+
]
|
433
|
+
)
|
434
|
+
return indent.join(lines)
|
435
|
+
|
436
|
+
@classmethod
|
437
|
+
def from_bytes(
|
438
|
+
cls, bytes_in: bytes, *, requested_fidelity: float, **kwargs
|
439
|
+
) -> "TwoQubitWeylDecomposition":
|
440
|
+
"""Decode bytes into TwoQubitWeylDecomposition. Used by __repr__"""
|
441
|
+
del kwargs # Unused (just for display)
|
442
|
+
b64 = base64.decodebytes(bytes_in)
|
443
|
+
with io.BytesIO(b64) as f:
|
444
|
+
arr = np.load(f, allow_pickle=False)
|
445
|
+
return cls(arr, fidelity=requested_fidelity)
|
446
|
+
|
447
|
+
def __str__(self):
|
448
|
+
pre = f"{self.__class__.__name__}(\n\t"
|
449
|
+
circ_indent = "\n\t".join(self.circuit(simplify=True).draw("text").lines(-1))
|
450
|
+
return f"{pre}{circ_indent}\n)"
|
451
|
+
|
452
|
+
|
453
|
+
class TwoQubitWeylIdEquiv(TwoQubitWeylDecomposition):
|
454
|
+
"""U ~ Ud(0,0,0) ~ Id
|
455
|
+
|
456
|
+
This gate binds 0 parameters, we make it canonical by setting
|
457
|
+
K2l = Id ,
|
458
|
+
K2r = Id .
|
459
|
+
"""
|
460
|
+
|
461
|
+
def specialize(self):
|
462
|
+
self.a = self.b = self.c = 0.0
|
463
|
+
self.K1l = self.K1l @ self.K2l
|
464
|
+
self.K1r = self.K1r @ self.K2r
|
465
|
+
self.K2l = _id.copy()
|
466
|
+
self.K2r = _id.copy()
|
467
|
+
|
468
|
+
|
469
|
+
class TwoQubitWeylSWAPEquiv(TwoQubitWeylDecomposition):
|
470
|
+
"""U ~ Ud(𝜋/4, 𝜋/4, 𝜋/4) ~ U(𝜋/4, 𝜋/4, -𝜋/4) ~ SWAP
|
471
|
+
|
472
|
+
This gate binds 0 parameters, we make it canonical by setting
|
473
|
+
K2l = Id ,
|
474
|
+
K2r = Id .
|
475
|
+
"""
|
476
|
+
|
477
|
+
def specialize(self):
|
478
|
+
if self.c > 0:
|
479
|
+
self.K1l = self.K1l @ self.K2r
|
480
|
+
self.K1r = self.K1r @ self.K2l
|
481
|
+
else:
|
482
|
+
self._is_flipped_from_original = True
|
483
|
+
self.K1l = self.K1l @ _ipz @ self.K2r
|
484
|
+
self.K1r = self.K1r @ _ipz @ self.K2l
|
485
|
+
self.global_phase = self.global_phase + np.pi / 2
|
486
|
+
self.a = self.b = self.c = np.pi / 4
|
487
|
+
self.K2l = _id.copy()
|
488
|
+
self.K2r = _id.copy()
|
489
|
+
|
490
|
+
def _weyl_gate(self, simplify, circ: QuantumCircuit, atol):
|
491
|
+
del self, simplify, atol # unused
|
492
|
+
circ.swap(0, 1)
|
493
|
+
circ.global_phase -= 3 * np.pi / 4
|
494
|
+
|
495
|
+
|
496
|
+
def _closest_partial_swap(a, b, c) -> float:
|
497
|
+
"""A good approximation to the best value x to get the minimum
|
498
|
+
trace distance for Ud(x, x, x) from Ud(a, b, c)
|
499
|
+
"""
|
500
|
+
m = (a + b + c) / 3
|
501
|
+
am, bm, cm = a - m, b - m, c - m
|
502
|
+
ab, bc, ca = a - b, b - c, c - a
|
503
|
+
|
504
|
+
return m + am * bm * cm * (6 + ab * ab + bc * bc * ca * ca) / 18
|
505
|
+
|
506
|
+
|
507
|
+
class TwoQubitWeylPartialSWAPEquiv(TwoQubitWeylDecomposition):
|
508
|
+
"""U ~ Ud(α𝜋/4, α𝜋/4, α𝜋/4) ~ SWAP**α
|
509
|
+
|
510
|
+
This gate binds 3 parameters, we make it canonical by setting:
|
511
|
+
K2l = Id .
|
512
|
+
"""
|
513
|
+
|
514
|
+
def specialize(self):
|
515
|
+
self.a = self.b = self.c = _closest_partial_swap(self.a, self.b, self.c)
|
516
|
+
self.K1l = self.K1l @ self.K2l
|
517
|
+
self.K1r = self.K1r @ self.K2l
|
518
|
+
self.K2r = self.K2l.T.conj() @ self.K2r
|
519
|
+
self.K2l = _id.copy()
|
520
|
+
|
521
|
+
|
522
|
+
class TwoQubitWeylPartialSWAPFlipEquiv(TwoQubitWeylDecomposition):
|
523
|
+
"""U ~ Ud(α𝜋/4, α𝜋/4, -α𝜋/4) ~ SWAP**α
|
524
|
+
|
525
|
+
(a non-equivalent root of SWAP from the TwoQubitWeylPartialSWAPEquiv
|
526
|
+
similar to how x = (±sqrt(x))**2 )
|
527
|
+
|
528
|
+
This gate binds 3 parameters, we make it canonical by setting:
|
529
|
+
K2l = Id .
|
530
|
+
"""
|
531
|
+
|
532
|
+
def specialize(self):
|
533
|
+
self.a = self.b = _closest_partial_swap(self.a, self.b, -self.c)
|
534
|
+
self.c = -self.a
|
535
|
+
self.K1l = self.K1l @ self.K2l
|
536
|
+
self.K1r = self.K1r @ _ipz @ self.K2l @ _ipz
|
537
|
+
self.K2r = _ipz @ self.K2l.T.conj() @ _ipz @ self.K2r
|
538
|
+
self.K2l = _id.copy()
|
539
|
+
|
540
|
+
|
541
|
+
_oneq_xyx = OneQubitEulerDecomposer("XYX")
|
542
|
+
_oneq_zyz = OneQubitEulerDecomposer("ZYZ")
|
543
|
+
|
544
|
+
|
545
|
+
class TwoQubitWeylControlledEquiv(TwoQubitWeylDecomposition):
|
546
|
+
"""U ~ Ud(α, 0, 0) ~ Ctrl-U
|
547
|
+
|
548
|
+
This gate binds 4 parameters, we make it canonical by setting:
|
549
|
+
K2l = Ry(θl).Rx(λl) ,
|
550
|
+
K2r = Ry(θr).Rx(λr) .
|
551
|
+
"""
|
552
|
+
|
553
|
+
_default_1q_basis = "XYX"
|
554
|
+
|
555
|
+
def specialize(self):
|
556
|
+
self.b = self.c = 0
|
557
|
+
k2ltheta, k2lphi, k2llambda, k2lphase = _oneq_xyx.angles_and_phase(self.K2l)
|
558
|
+
k2rtheta, k2rphi, k2rlambda, k2rphase = _oneq_xyx.angles_and_phase(self.K2r)
|
559
|
+
self.global_phase += k2lphase + k2rphase
|
560
|
+
self.K1l = self.K1l @ np.asarray(RXGate(k2lphi))
|
561
|
+
self.K1r = self.K1r @ np.asarray(RXGate(k2rphi))
|
562
|
+
self.K2l = np.asarray(RYGate(k2ltheta)) @ np.asarray(RXGate(k2llambda))
|
563
|
+
self.K2r = np.asarray(RYGate(k2rtheta)) @ np.asarray(RXGate(k2rlambda))
|
564
|
+
|
565
|
+
|
566
|
+
class TwoQubitControlledUDecomposer:
|
567
|
+
"""Decompose two-qubit unitary in terms of a desired U ~ Ud(α, 0, 0) ~ Ctrl-U gate
|
568
|
+
that is locally equivalent to an RXXGate."""
|
569
|
+
|
570
|
+
def __init__(self, rxx_equivalent_gate: Type[Gate]):
|
571
|
+
"""Initialize the KAK decomposition.
|
572
|
+
|
573
|
+
Args:
|
574
|
+
rxx_equivalent_gate: Gate that is locally equivalent to an RXXGate:
|
575
|
+
U ~ Ud(α, 0, 0) ~ Ctrl-U gate.
|
576
|
+
Raises:
|
577
|
+
QiskitError: If the gate is not locally equivalent to an RXXGate.
|
578
|
+
"""
|
579
|
+
atol = DEFAULT_ATOL
|
580
|
+
|
581
|
+
scales, test_angles, scale = [], [0.2, 0.3, np.pi / 2], None
|
582
|
+
|
583
|
+
for test_angle in test_angles:
|
584
|
+
# Check that gate takes a single angle parameter
|
585
|
+
try:
|
586
|
+
rxx_equivalent_gate(test_angle, label="foo")
|
587
|
+
except TypeError as _:
|
588
|
+
raise QiskitError("Equivalent gate needs to take exactly 1 angle parameter.") from _
|
589
|
+
decomp = TwoQubitWeylDecomposition(rxx_equivalent_gate(test_angle))
|
590
|
+
|
591
|
+
circ = QuantumCircuit(2)
|
592
|
+
circ.rxx(test_angle, 0, 1)
|
593
|
+
decomposer_rxx = TwoQubitWeylControlledEquiv(Operator(circ).data)
|
594
|
+
|
595
|
+
circ = QuantumCircuit(2)
|
596
|
+
circ.append(rxx_equivalent_gate(test_angle), qargs=[0, 1])
|
597
|
+
decomposer_equiv = TwoQubitWeylControlledEquiv(Operator(circ).data)
|
598
|
+
|
599
|
+
scale = decomposer_rxx.a / decomposer_equiv.a
|
600
|
+
|
601
|
+
if (
|
602
|
+
not isinstance(decomp, TwoQubitWeylControlledEquiv)
|
603
|
+
or abs(decomp.a * 2 - test_angle / scale) > atol
|
604
|
+
):
|
605
|
+
raise QiskitError(
|
606
|
+
f"{rxx_equivalent_gate.__name__} is not equivalent to an RXXGate."
|
607
|
+
)
|
608
|
+
|
609
|
+
scales.append(scale)
|
610
|
+
|
611
|
+
# Check that all three tested angles give the same scale
|
612
|
+
if not np.allclose(scales, [scale] * len(test_angles)):
|
613
|
+
raise QiskitError(
|
614
|
+
f"Cannot initialize {self.__class__.__name__}: with gate {rxx_equivalent_gate}. "
|
615
|
+
"Inconsistent scaling parameters in checks."
|
616
|
+
)
|
617
|
+
|
618
|
+
self.scale = scales[0]
|
619
|
+
|
620
|
+
self.rxx_equivalent_gate = rxx_equivalent_gate
|
621
|
+
|
622
|
+
def __call__(self, unitary, *, atol=DEFAULT_ATOL) -> QuantumCircuit:
|
623
|
+
"""Returns the Weyl decomposition in circuit form.
|
624
|
+
|
625
|
+
Note: atol ist passed to OneQubitEulerDecomposer.
|
626
|
+
"""
|
627
|
+
|
628
|
+
# pylint: disable=attribute-defined-outside-init
|
629
|
+
self.decomposer = TwoQubitWeylDecomposition(unitary)
|
630
|
+
|
631
|
+
oneq_decompose = OneQubitEulerDecomposer("ZYZ")
|
632
|
+
c1l, c1r, c2l, c2r = (
|
633
|
+
oneq_decompose(k, atol=atol)
|
634
|
+
for k in (
|
635
|
+
self.decomposer.K1l,
|
636
|
+
self.decomposer.K1r,
|
637
|
+
self.decomposer.K2l,
|
638
|
+
self.decomposer.K2r,
|
639
|
+
)
|
640
|
+
)
|
641
|
+
circ = QuantumCircuit(2, global_phase=self.decomposer.global_phase)
|
642
|
+
circ.compose(c2r, [0], inplace=True)
|
643
|
+
circ.compose(c2l, [1], inplace=True)
|
644
|
+
self._weyl_gate(circ)
|
645
|
+
circ.compose(c1r, [0], inplace=True)
|
646
|
+
circ.compose(c1l, [1], inplace=True)
|
647
|
+
return circ
|
648
|
+
|
649
|
+
def _to_rxx_gate(self, angle: float) -> QuantumCircuit:
|
650
|
+
"""
|
651
|
+
Takes an angle and returns the circuit equivalent to an RXXGate with the
|
652
|
+
RXX equivalent gate as the two-qubit unitary.
|
653
|
+
|
654
|
+
Args:
|
655
|
+
angle: Rotation angle (in this case one of the Weyl parameters a, b, or c)
|
656
|
+
|
657
|
+
Returns:
|
658
|
+
Circuit: Circuit equivalent to an RXXGate.
|
659
|
+
|
660
|
+
Raises:
|
661
|
+
QiskitError: If the circuit is not equivalent to an RXXGate.
|
662
|
+
"""
|
663
|
+
|
664
|
+
# The user-provided RXXGate equivalent gate may be locally equivalent to the RXXGate
|
665
|
+
# but with some scaling in the rotation angle. For example, RXXGate(angle) has Weyl
|
666
|
+
# parameters (angle, 0, 0) for angle in [0, pi/2] but the user provided gate, i.e.
|
667
|
+
# :code:`self.rxx_equivalent_gate(angle)` might produce the Weyl parameters
|
668
|
+
# (scale * angle, 0, 0) where scale != 1. This is the case for the CPhaseGate.
|
669
|
+
|
670
|
+
circ = QuantumCircuit(2)
|
671
|
+
circ.append(self.rxx_equivalent_gate(self.scale * angle), qargs=[0, 1])
|
672
|
+
decomposer_inv = TwoQubitWeylControlledEquiv(Operator(circ).data)
|
673
|
+
|
674
|
+
oneq_decompose = OneQubitEulerDecomposer("ZYZ")
|
675
|
+
|
676
|
+
# Express the RXXGate in terms of the user-provided RXXGate equivalent gate.
|
677
|
+
rxx_circ = QuantumCircuit(2, global_phase=-decomposer_inv.global_phase)
|
678
|
+
rxx_circ.compose(oneq_decompose(decomposer_inv.K2r).inverse(), inplace=True, qubits=[0])
|
679
|
+
rxx_circ.compose(oneq_decompose(decomposer_inv.K2l).inverse(), inplace=True, qubits=[1])
|
680
|
+
rxx_circ.compose(circ, inplace=True)
|
681
|
+
rxx_circ.compose(oneq_decompose(decomposer_inv.K1r).inverse(), inplace=True, qubits=[0])
|
682
|
+
rxx_circ.compose(oneq_decompose(decomposer_inv.K1l).inverse(), inplace=True, qubits=[1])
|
683
|
+
|
684
|
+
return rxx_circ
|
685
|
+
|
686
|
+
def _weyl_gate(self, circ: QuantumCircuit, atol=1.0e-13):
|
687
|
+
"""Appends Ud(a, b, c) to the circuit."""
|
688
|
+
|
689
|
+
circ_rxx = self._to_rxx_gate(-2 * self.decomposer.a)
|
690
|
+
circ.compose(circ_rxx, inplace=True)
|
691
|
+
|
692
|
+
# translate the RYYGate(b) into a circuit based on the desired Ctrl-U gate.
|
693
|
+
if abs(self.decomposer.b) > atol:
|
694
|
+
circ_ryy = QuantumCircuit(2)
|
695
|
+
circ_ryy.sdg(0)
|
696
|
+
circ_ryy.sdg(1)
|
697
|
+
circ_ryy.compose(self._to_rxx_gate(-2 * self.decomposer.b), inplace=True)
|
698
|
+
circ_ryy.s(0)
|
699
|
+
circ_ryy.s(1)
|
700
|
+
circ.compose(circ_ryy, inplace=True)
|
701
|
+
|
702
|
+
# translate the RZZGate(c) into a circuit based on the desired Ctrl-U gate.
|
703
|
+
if abs(self.decomposer.c) > atol:
|
704
|
+
# Since the Weyl chamber is here defined as a > b > |c| we may have
|
705
|
+
# negative c. This will cause issues in _to_rxx_gate
|
706
|
+
# as TwoQubitWeylControlledEquiv will map (c, 0, 0) to (|c|, 0, 0).
|
707
|
+
# We therefore produce RZZGate(|c|) and append its inverse to the
|
708
|
+
# circuit if c < 0.
|
709
|
+
gamma, invert = -2 * self.decomposer.c, False
|
710
|
+
if gamma > 0:
|
711
|
+
gamma *= -1
|
712
|
+
invert = True
|
713
|
+
|
714
|
+
circ_rzz = QuantumCircuit(2)
|
715
|
+
circ_rzz.h(0)
|
716
|
+
circ_rzz.h(1)
|
717
|
+
circ_rzz.compose(self._to_rxx_gate(gamma), inplace=True)
|
718
|
+
circ_rzz.h(0)
|
719
|
+
circ_rzz.h(1)
|
720
|
+
|
721
|
+
if invert:
|
722
|
+
circ.compose(circ_rzz.inverse(), inplace=True)
|
723
|
+
else:
|
724
|
+
circ.compose(circ_rzz, inplace=True)
|
725
|
+
|
726
|
+
return circ
|
727
|
+
|
728
|
+
|
729
|
+
class TwoQubitWeylMirrorControlledEquiv(TwoQubitWeylDecomposition):
|
730
|
+
"""U ~ Ud(𝜋/4, 𝜋/4, α) ~ SWAP . Ctrl-U
|
731
|
+
|
732
|
+
This gate binds 4 parameters, we make it canonical by setting:
|
733
|
+
K2l = Ry(θl).Rz(λl) ,
|
734
|
+
K2r = Ry(θr).Rz(λr) .
|
735
|
+
"""
|
736
|
+
|
737
|
+
def specialize(self):
|
738
|
+
self.a = self.b = np.pi / 4
|
739
|
+
k2ltheta, k2lphi, k2llambda, k2lphase = _oneq_zyz.angles_and_phase(self.K2l)
|
740
|
+
k2rtheta, k2rphi, k2rlambda, k2rphase = _oneq_zyz.angles_and_phase(self.K2r)
|
741
|
+
self.global_phase += k2lphase + k2rphase
|
742
|
+
self.K1r = self.K1r @ np.asarray(RZGate(k2lphi))
|
743
|
+
self.K1l = self.K1l @ np.asarray(RZGate(k2rphi))
|
744
|
+
self.K2l = np.asarray(RYGate(k2ltheta)) @ np.asarray(RZGate(k2llambda))
|
745
|
+
self.K2r = np.asarray(RYGate(k2rtheta)) @ np.asarray(RZGate(k2rlambda))
|
746
|
+
|
747
|
+
def _weyl_gate(self, simplify, circ: QuantumCircuit, atol):
|
748
|
+
circ.swap(0, 1)
|
749
|
+
circ.rzz((np.pi / 4 - self.c) * 2, 0, 1)
|
750
|
+
circ.global_phase += np.pi / 4
|
751
|
+
|
752
|
+
|
753
|
+
# These next 3 gates use the definition of fSim from https://arxiv.org/pdf/2001.08343.pdf eq (1)
|
754
|
+
class TwoQubitWeylfSimaabEquiv(TwoQubitWeylDecomposition):
|
755
|
+
"""U ~ Ud(α, α, β), α ≥ |β|
|
756
|
+
|
757
|
+
This gate binds 5 parameters, we make it canonical by setting:
|
758
|
+
K2l = Ry(θl).Rz(λl) .
|
759
|
+
"""
|
760
|
+
|
761
|
+
def specialize(self):
|
762
|
+
self.a = self.b = (self.a + self.b) / 2
|
763
|
+
k2ltheta, k2lphi, k2llambda, k2lphase = _oneq_zyz.angles_and_phase(self.K2l)
|
764
|
+
self.global_phase += k2lphase
|
765
|
+
self.K1r = self.K1r @ np.asarray(RZGate(k2lphi))
|
766
|
+
self.K1l = self.K1l @ np.asarray(RZGate(k2lphi))
|
767
|
+
self.K2l = np.asarray(RYGate(k2ltheta)) @ np.asarray(RZGate(k2llambda))
|
768
|
+
self.K2r = np.asarray(RZGate(-k2lphi)) @ self.K2r
|
769
|
+
|
770
|
+
|
771
|
+
class TwoQubitWeylfSimabbEquiv(TwoQubitWeylDecomposition):
|
772
|
+
"""U ~ Ud(α, β, β), α ≥ β
|
773
|
+
|
774
|
+
This gate binds 5 parameters, we make it canonical by setting:
|
775
|
+
K2l = Ry(θl).Rx(λl) .
|
776
|
+
"""
|
777
|
+
|
778
|
+
_default_1q_basis = "XYX"
|
779
|
+
|
780
|
+
def specialize(self):
|
781
|
+
self.b = self.c = (self.b + self.c) / 2
|
782
|
+
k2ltheta, k2lphi, k2llambda, k2lphase = _oneq_xyx.angles_and_phase(self.K2l)
|
783
|
+
self.global_phase += k2lphase
|
784
|
+
self.K1r = self.K1r @ np.asarray(RXGate(k2lphi))
|
785
|
+
self.K1l = self.K1l @ np.asarray(RXGate(k2lphi))
|
786
|
+
self.K2l = np.asarray(RYGate(k2ltheta)) @ np.asarray(RXGate(k2llambda))
|
787
|
+
self.K2r = np.asarray(RXGate(-k2lphi)) @ self.K2r
|
788
|
+
|
789
|
+
|
790
|
+
class TwoQubitWeylfSimabmbEquiv(TwoQubitWeylDecomposition):
|
791
|
+
"""U ~ Ud(α, β, -β), α ≥ β ≥ 0
|
792
|
+
|
793
|
+
This gate binds 5 parameters, we make it canonical by setting:
|
794
|
+
K2l = Ry(θl).Rx(λl) .
|
795
|
+
"""
|
796
|
+
|
797
|
+
_default_1q_basis = "XYX"
|
798
|
+
|
799
|
+
def specialize(self):
|
800
|
+
self.b = (self.b - self.c) / 2
|
801
|
+
self.c = -self.b
|
802
|
+
k2ltheta, k2lphi, k2llambda, k2lphase = _oneq_xyx.angles_and_phase(self.K2l)
|
803
|
+
self.global_phase += k2lphase
|
804
|
+
self.K1r = self.K1r @ _ipz @ np.asarray(RXGate(k2lphi)) @ _ipz
|
805
|
+
self.K1l = self.K1l @ np.asarray(RXGate(k2lphi))
|
806
|
+
self.K2l = np.asarray(RYGate(k2ltheta)) @ np.asarray(RXGate(k2llambda))
|
807
|
+
self.K2r = _ipz @ np.asarray(RXGate(-k2lphi)) @ _ipz @ self.K2r
|
808
|
+
|
809
|
+
|
810
|
+
class TwoQubitWeylGeneral(TwoQubitWeylDecomposition):
|
811
|
+
"""U has no special symmetry.
|
812
|
+
|
813
|
+
This gate binds all 6 possible parameters, so there is no need to make the single-qubit
|
814
|
+
pre-/post-gates canonical.
|
815
|
+
"""
|
816
|
+
|
817
|
+
def specialize(self):
|
818
|
+
pass # Nothing to do
|
819
|
+
|
820
|
+
|
821
|
+
def Ud(a, b, c):
|
822
|
+
"""Generates the array Exp(i(a xx + b yy + c zz))"""
|
823
|
+
return np.array(
|
824
|
+
[
|
825
|
+
[cmath.exp(1j * c) * math.cos(a - b), 0, 0, 1j * cmath.exp(1j * c) * math.sin(a - b)],
|
826
|
+
[0, cmath.exp(-1j * c) * math.cos(a + b), 1j * cmath.exp(-1j * c) * math.sin(a + b), 0],
|
827
|
+
[0, 1j * cmath.exp(-1j * c) * math.sin(a + b), cmath.exp(-1j * c) * math.cos(a + b), 0],
|
828
|
+
[1j * cmath.exp(1j * c) * math.sin(a - b), 0, 0, cmath.exp(1j * c) * math.cos(a - b)],
|
829
|
+
],
|
830
|
+
dtype=complex,
|
831
|
+
)
|
832
|
+
|
833
|
+
|
834
|
+
def trace_to_fid(trace):
|
835
|
+
"""Average gate fidelity is :math:`Fbar = (d + |Tr (Utarget \\cdot U^dag)|^2) / d(d+1)`
|
836
|
+
M. Horodecki, P. Horodecki and R. Horodecki, PRA 60, 1888 (1999)"""
|
837
|
+
return (4 + abs(trace) ** 2) / 20
|
838
|
+
|
839
|
+
|
840
|
+
def rz_array(theta):
|
841
|
+
"""Return numpy array for Rz(theta).
|
842
|
+
|
843
|
+
Rz(theta) = diag(exp(-i*theta/2),exp(i*theta/2))
|
844
|
+
"""
|
845
|
+
return np.array(
|
846
|
+
[[cmath.exp(-1j * theta / 2.0), 0], [0, cmath.exp(1j * theta / 2.0)]], dtype=complex
|
847
|
+
)
|
848
|
+
|
849
|
+
|
850
|
+
class TwoQubitBasisDecomposer:
|
851
|
+
"""A class for decomposing 2-qubit unitaries into minimal number of uses of a 2-qubit
|
852
|
+
basis gate.
|
853
|
+
|
854
|
+
Args:
|
855
|
+
gate (Gate): Two-qubit gate to be used in the KAK decomposition.
|
856
|
+
basis_fidelity (float): Fidelity to be assumed for applications of KAK Gate. Default 1.0.
|
857
|
+
euler_basis (str): Basis string to be provided to OneQubitEulerDecomposer for 1Q synthesis.
|
858
|
+
Valid options are ['ZYZ', 'ZXZ', 'XYX', 'U', 'U3', 'U1X', 'PSX', 'ZSX', 'RR'].
|
859
|
+
pulse_optimize (None or bool): If True, try to do decomposition which minimizes
|
860
|
+
local unitaries in between entangling gates. This will raise an exception if an
|
861
|
+
optimal decomposition is not implemented. Currently, only [{CX, SX, RZ}] is known.
|
862
|
+
If False, don't attempt optimization. If None, attempt optimization but don't raise
|
863
|
+
if unknown.
|
864
|
+
"""
|
865
|
+
|
866
|
+
def __init__(
|
867
|
+
self,
|
868
|
+
gate: Gate,
|
869
|
+
basis_fidelity: float = 1.0,
|
870
|
+
euler_basis: str = "U",
|
871
|
+
pulse_optimize: bool | None = None,
|
872
|
+
):
|
873
|
+
self.gate = gate
|
874
|
+
self.basis_fidelity = basis_fidelity
|
875
|
+
self.pulse_optimize = pulse_optimize
|
876
|
+
|
877
|
+
basis = self.basis = TwoQubitWeylDecomposition(Operator(gate).data)
|
878
|
+
self._decomposer1q = OneQubitEulerDecomposer(euler_basis)
|
879
|
+
|
880
|
+
# FIXME: find good tolerances
|
881
|
+
self.is_supercontrolled = math.isclose(basis.a, np.pi / 4) and math.isclose(basis.c, 0.0)
|
882
|
+
|
883
|
+
# Create some useful matrices U1, U2, U3 are equivalent to the basis,
|
884
|
+
# expand as Ui = Ki1.Ubasis.Ki2
|
885
|
+
b = basis.b
|
886
|
+
K11l = (
|
887
|
+
1
|
888
|
+
/ (1 + 1j)
|
889
|
+
* np.array(
|
890
|
+
[
|
891
|
+
[-1j * cmath.exp(-1j * b), cmath.exp(-1j * b)],
|
892
|
+
[-1j * cmath.exp(1j * b), -cmath.exp(1j * b)],
|
893
|
+
],
|
894
|
+
dtype=complex,
|
895
|
+
)
|
896
|
+
)
|
897
|
+
K11r = (
|
898
|
+
1
|
899
|
+
/ math.sqrt(2)
|
900
|
+
* np.array(
|
901
|
+
[
|
902
|
+
[1j * cmath.exp(-1j * b), -cmath.exp(-1j * b)],
|
903
|
+
[cmath.exp(1j * b), -1j * cmath.exp(1j * b)],
|
904
|
+
],
|
905
|
+
dtype=complex,
|
906
|
+
)
|
907
|
+
)
|
908
|
+
K12l = 1 / (1 + 1j) * np.array([[1j, 1j], [-1, 1]], dtype=complex)
|
909
|
+
K12r = 1 / math.sqrt(2) * np.array([[1j, 1], [-1, -1j]], dtype=complex)
|
910
|
+
K32lK21l = (
|
911
|
+
1
|
912
|
+
/ math.sqrt(2)
|
913
|
+
* np.array(
|
914
|
+
[
|
915
|
+
[1 + 1j * np.cos(2 * b), 1j * np.sin(2 * b)],
|
916
|
+
[1j * np.sin(2 * b), 1 - 1j * np.cos(2 * b)],
|
917
|
+
],
|
918
|
+
dtype=complex,
|
919
|
+
)
|
920
|
+
)
|
921
|
+
K21r = (
|
922
|
+
1
|
923
|
+
/ (1 - 1j)
|
924
|
+
* np.array(
|
925
|
+
[
|
926
|
+
[-1j * cmath.exp(-2j * b), cmath.exp(-2j * b)],
|
927
|
+
[1j * cmath.exp(2j * b), cmath.exp(2j * b)],
|
928
|
+
],
|
929
|
+
dtype=complex,
|
930
|
+
)
|
931
|
+
)
|
932
|
+
K22l = 1 / math.sqrt(2) * np.array([[1, -1], [1, 1]], dtype=complex)
|
933
|
+
K22r = np.array([[0, 1], [-1, 0]], dtype=complex)
|
934
|
+
K31l = (
|
935
|
+
1
|
936
|
+
/ math.sqrt(2)
|
937
|
+
* np.array(
|
938
|
+
[[cmath.exp(-1j * b), cmath.exp(-1j * b)], [-cmath.exp(1j * b), cmath.exp(1j * b)]],
|
939
|
+
dtype=complex,
|
940
|
+
)
|
941
|
+
)
|
942
|
+
K31r = 1j * np.array([[cmath.exp(1j * b), 0], [0, -cmath.exp(-1j * b)]], dtype=complex)
|
943
|
+
K32r = (
|
944
|
+
1
|
945
|
+
/ (1 - 1j)
|
946
|
+
* np.array(
|
947
|
+
[
|
948
|
+
[cmath.exp(1j * b), -cmath.exp(-1j * b)],
|
949
|
+
[-1j * cmath.exp(1j * b), -1j * cmath.exp(-1j * b)],
|
950
|
+
],
|
951
|
+
dtype=complex,
|
952
|
+
)
|
953
|
+
)
|
954
|
+
k1ld = basis.K1l.T.conj()
|
955
|
+
k1rd = basis.K1r.T.conj()
|
956
|
+
k2ld = basis.K2l.T.conj()
|
957
|
+
k2rd = basis.K2r.T.conj()
|
958
|
+
|
959
|
+
# Pre-build the fixed parts of the matrices used in 3-part decomposition
|
960
|
+
self.u0l = K31l.dot(k1ld)
|
961
|
+
self.u0r = K31r.dot(k1rd)
|
962
|
+
self.u1l = k2ld.dot(K32lK21l).dot(k1ld)
|
963
|
+
self.u1ra = k2rd.dot(K32r)
|
964
|
+
self.u1rb = K21r.dot(k1rd)
|
965
|
+
self.u2la = k2ld.dot(K22l)
|
966
|
+
self.u2lb = K11l.dot(k1ld)
|
967
|
+
self.u2ra = k2rd.dot(K22r)
|
968
|
+
self.u2rb = K11r.dot(k1rd)
|
969
|
+
self.u3l = k2ld.dot(K12l)
|
970
|
+
self.u3r = k2rd.dot(K12r)
|
971
|
+
|
972
|
+
# Pre-build the fixed parts of the matrices used in the 2-part decomposition
|
973
|
+
self.q0l = K12l.T.conj().dot(k1ld)
|
974
|
+
self.q0r = K12r.T.conj().dot(_ipz).dot(k1rd)
|
975
|
+
self.q1la = k2ld.dot(K11l.T.conj())
|
976
|
+
self.q1lb = K11l.dot(k1ld)
|
977
|
+
self.q1ra = k2rd.dot(_ipz).dot(K11r.T.conj())
|
978
|
+
self.q1rb = K11r.dot(k1rd)
|
979
|
+
self.q2l = k2ld.dot(K12l)
|
980
|
+
self.q2r = k2rd.dot(K12r)
|
981
|
+
|
982
|
+
# Decomposition into different number of gates
|
983
|
+
# In the future could use different decomposition functions for different basis classes, etc
|
984
|
+
if not self.is_supercontrolled:
|
985
|
+
warnings.warn(
|
986
|
+
"Only know how to decompose properly for supercontrolled basis gate. "
|
987
|
+
"This gate is ~Ud({}, {}, {})".format(basis.a, basis.b, basis.c),
|
988
|
+
stacklevel=2,
|
989
|
+
)
|
990
|
+
self.decomposition_fns = [
|
991
|
+
self.decomp0,
|
992
|
+
self.decomp1,
|
993
|
+
self.decomp2_supercontrolled,
|
994
|
+
self.decomp3_supercontrolled,
|
995
|
+
]
|
996
|
+
self._rqc = None
|
997
|
+
|
998
|
+
def traces(self, target):
|
999
|
+
"""Give the expected traces :math:`|Tr(U \\cdot Utarget^dag)|` for different number of
|
1000
|
+
basis gates."""
|
1001
|
+
# Future gotcha: extending this to non-supercontrolled basis.
|
1002
|
+
# Careful: closest distance between a1,b1,c1 and a2,b2,c2 may be between reflections.
|
1003
|
+
# This doesn't come up if either c1==0 or c2==0 but otherwise be careful.
|
1004
|
+
ta, tb, tc = target.a, target.b, target.c
|
1005
|
+
bb = self.basis.b
|
1006
|
+
return [
|
1007
|
+
4
|
1008
|
+
* complex(
|
1009
|
+
math.cos(ta) * math.cos(tb) * math.cos(tc),
|
1010
|
+
math.sin(ta) * math.sin(tb) * math.sin(tc),
|
1011
|
+
),
|
1012
|
+
4
|
1013
|
+
* complex(
|
1014
|
+
math.cos(math.pi / 4 - ta) * math.cos(bb - tb) * math.cos(tc),
|
1015
|
+
math.sin(math.pi / 4 - ta) * math.sin(bb - tb) * math.sin(tc),
|
1016
|
+
),
|
1017
|
+
4 * math.cos(tc),
|
1018
|
+
4,
|
1019
|
+
]
|
1020
|
+
|
1021
|
+
@staticmethod
|
1022
|
+
def decomp0(target):
|
1023
|
+
"""Decompose target ~Ud(x, y, z) with 0 uses of the basis gate.
|
1024
|
+
Result Ur has trace:
|
1025
|
+
:math:`|Tr(Ur.Utarget^dag)| = 4|(cos(x)cos(y)cos(z)+ j sin(x)sin(y)sin(z)|`,
|
1026
|
+
which is optimal for all targets and bases"""
|
1027
|
+
|
1028
|
+
U0l = target.K1l.dot(target.K2l)
|
1029
|
+
U0r = target.K1r.dot(target.K2r)
|
1030
|
+
return U0r, U0l
|
1031
|
+
|
1032
|
+
def decomp1(self, target):
|
1033
|
+
"""Decompose target ~Ud(x, y, z) with 1 uses of the basis gate ~Ud(a, b, c).
|
1034
|
+
Result Ur has trace:
|
1035
|
+
.. math::
|
1036
|
+
|
1037
|
+
|Tr(Ur.Utarget^dag)| = 4|cos(x-a)cos(y-b)cos(z-c) + j sin(x-a)sin(y-b)sin(z-c)|
|
1038
|
+
|
1039
|
+
which is optimal for all targets and bases with z==0 or c==0"""
|
1040
|
+
# FIXME: fix for z!=0 and c!=0 using closest reflection (not always in the Weyl chamber)
|
1041
|
+
U0l = target.K1l.dot(self.basis.K1l.T.conj())
|
1042
|
+
U0r = target.K1r.dot(self.basis.K1r.T.conj())
|
1043
|
+
U1l = self.basis.K2l.T.conj().dot(target.K2l)
|
1044
|
+
U1r = self.basis.K2r.T.conj().dot(target.K2r)
|
1045
|
+
|
1046
|
+
return U1r, U1l, U0r, U0l
|
1047
|
+
|
1048
|
+
def decomp2_supercontrolled(self, target):
|
1049
|
+
"""Decompose target ~Ud(x, y, z) with 2 uses of the basis gate.
|
1050
|
+
|
1051
|
+
For supercontrolled basis ~Ud(pi/4, b, 0), all b, result Ur has trace
|
1052
|
+
.. math::
|
1053
|
+
|
1054
|
+
|Tr(Ur.Utarget^dag)| = 4cos(z)
|
1055
|
+
|
1056
|
+
which is the optimal approximation for basis of CNOT-class ``~Ud(pi/4, 0, 0)``
|
1057
|
+
or DCNOT-class ``~Ud(pi/4, pi/4, 0)`` and any target.
|
1058
|
+
May be sub-optimal for b!=0 (e.g. there exists exact decomposition for any target using B
|
1059
|
+
``B~Ud(pi/4, pi/8, 0)``, but not this decomposition.)
|
1060
|
+
This is an exact decomposition for supercontrolled basis and target ``~Ud(x, y, 0)``.
|
1061
|
+
No guarantees for non-supercontrolled basis.
|
1062
|
+
"""
|
1063
|
+
|
1064
|
+
U0l = target.K1l.dot(self.q0l)
|
1065
|
+
U0r = target.K1r.dot(self.q0r)
|
1066
|
+
U1l = self.q1la.dot(rz_array(-2 * target.a)).dot(self.q1lb)
|
1067
|
+
U1r = self.q1ra.dot(rz_array(2 * target.b)).dot(self.q1rb)
|
1068
|
+
U2l = self.q2l.dot(target.K2l)
|
1069
|
+
U2r = self.q2r.dot(target.K2r)
|
1070
|
+
|
1071
|
+
return U2r, U2l, U1r, U1l, U0r, U0l
|
1072
|
+
|
1073
|
+
def decomp3_supercontrolled(self, target):
|
1074
|
+
"""Decompose target with 3 uses of the basis.
|
1075
|
+
This is an exact decomposition for supercontrolled basis ~Ud(pi/4, b, 0), all b,
|
1076
|
+
and any target. No guarantees for non-supercontrolled basis."""
|
1077
|
+
|
1078
|
+
U0l = target.K1l.dot(self.u0l)
|
1079
|
+
U0r = target.K1r.dot(self.u0r)
|
1080
|
+
U1l = self.u1l
|
1081
|
+
U1r = self.u1ra.dot(rz_array(-2 * target.c)).dot(self.u1rb)
|
1082
|
+
U2l = self.u2la.dot(rz_array(-2 * target.a)).dot(self.u2lb)
|
1083
|
+
U2r = self.u2ra.dot(rz_array(2 * target.b)).dot(self.u2rb)
|
1084
|
+
U3l = self.u3l.dot(target.K2l)
|
1085
|
+
U3r = self.u3r.dot(target.K2r)
|
1086
|
+
|
1087
|
+
return U3r, U3l, U2r, U2l, U1r, U1l, U0r, U0l
|
1088
|
+
|
1089
|
+
@deprecate_arg("target", new_alias="unitary", since="0.23.0", package_name="qiskit-terra")
|
1090
|
+
def __call__(
|
1091
|
+
self,
|
1092
|
+
unitary: Operator | np.ndarray,
|
1093
|
+
basis_fidelity: float | None = None,
|
1094
|
+
approximate: bool = True,
|
1095
|
+
*,
|
1096
|
+
_num_basis_uses: int | None = None,
|
1097
|
+
) -> QuantumCircuit:
|
1098
|
+
"""Decompose a two-qubit `unitary` over fixed basis + SU(2) using the best approximation given
|
1099
|
+
that each basis application has a finite `basis_fidelity`.
|
1100
|
+
|
1101
|
+
Args:
|
1102
|
+
unitary (Operator or ndarray): 4x4 unitary to synthesize.
|
1103
|
+
basis_fidelity (float or None): Fidelity to be assumed for applications of KAK Gate.
|
1104
|
+
If given, overrides basis_fidelity given at init.
|
1105
|
+
approximate (bool): Approximates if basis fidelities are less than 1.0.
|
1106
|
+
_num_basis_uses (int): force a particular approximation by passing a number in [0, 3].
|
1107
|
+
Returns:
|
1108
|
+
QuantumCircuit: Synthesized circuit.
|
1109
|
+
Raises:
|
1110
|
+
QiskitError: if pulse_optimize is True but we don't know how to do it.
|
1111
|
+
"""
|
1112
|
+
basis_fidelity = basis_fidelity or self.basis_fidelity
|
1113
|
+
if approximate is False:
|
1114
|
+
basis_fidelity = 1.0
|
1115
|
+
unitary = np.asarray(unitary, dtype=complex)
|
1116
|
+
|
1117
|
+
target_decomposed = TwoQubitWeylDecomposition(unitary)
|
1118
|
+
traces = self.traces(target_decomposed)
|
1119
|
+
expected_fidelities = [trace_to_fid(traces[i]) * basis_fidelity**i for i in range(4)]
|
1120
|
+
|
1121
|
+
best_nbasis = int(np.argmax(expected_fidelities))
|
1122
|
+
if _num_basis_uses is not None:
|
1123
|
+
best_nbasis = _num_basis_uses
|
1124
|
+
decomposition = self.decomposition_fns[best_nbasis](target_decomposed)
|
1125
|
+
|
1126
|
+
# attempt pulse optimal decomposition
|
1127
|
+
try:
|
1128
|
+
if self.pulse_optimize in {None, True}:
|
1129
|
+
return_circuit = self._pulse_optimal_chooser(
|
1130
|
+
best_nbasis, decomposition, target_decomposed
|
1131
|
+
)
|
1132
|
+
if return_circuit:
|
1133
|
+
return return_circuit
|
1134
|
+
except QiskitError:
|
1135
|
+
if self.pulse_optimize:
|
1136
|
+
raise
|
1137
|
+
|
1138
|
+
# do default decomposition
|
1139
|
+
q = QuantumRegister(2)
|
1140
|
+
decomposition_euler = [self._decomposer1q._decompose(x) for x in decomposition]
|
1141
|
+
return_circuit = QuantumCircuit(q)
|
1142
|
+
return_circuit.global_phase = target_decomposed.global_phase
|
1143
|
+
return_circuit.global_phase -= best_nbasis * self.basis.global_phase
|
1144
|
+
if best_nbasis == 2:
|
1145
|
+
return_circuit.global_phase += np.pi
|
1146
|
+
for i in range(best_nbasis):
|
1147
|
+
return_circuit.compose(decomposition_euler[2 * i], [q[0]], inplace=True)
|
1148
|
+
return_circuit.compose(decomposition_euler[2 * i + 1], [q[1]], inplace=True)
|
1149
|
+
return_circuit.append(self.gate, [q[0], q[1]])
|
1150
|
+
return_circuit.compose(decomposition_euler[2 * best_nbasis], [q[0]], inplace=True)
|
1151
|
+
return_circuit.compose(decomposition_euler[2 * best_nbasis + 1], [q[1]], inplace=True)
|
1152
|
+
return return_circuit
|
1153
|
+
|
1154
|
+
def _pulse_optimal_chooser(
|
1155
|
+
self, best_nbasis, decomposition, target_decomposed
|
1156
|
+
) -> QuantumCircuit:
|
1157
|
+
"""Determine method to find pulse optimal circuit. This method may be
|
1158
|
+
removed once a more general approach is used.
|
1159
|
+
|
1160
|
+
Returns:
|
1161
|
+
QuantumCircuit: pulse optimal quantum circuit.
|
1162
|
+
None: Probably nbasis=1 and original circuit is fine.
|
1163
|
+
|
1164
|
+
Raises:
|
1165
|
+
QiskitError: Decomposition for selected basis not implemented.
|
1166
|
+
"""
|
1167
|
+
circuit = None
|
1168
|
+
if self.pulse_optimize and best_nbasis in {0, 1}:
|
1169
|
+
# already pulse optimal
|
1170
|
+
return None
|
1171
|
+
elif self.pulse_optimize and best_nbasis > 3:
|
1172
|
+
raise QiskitError(
|
1173
|
+
f"Unexpected number of entangling gates ({best_nbasis}) in decomposition."
|
1174
|
+
)
|
1175
|
+
if self._decomposer1q.basis in {"ZSX", "ZSXX"}:
|
1176
|
+
if isinstance(self.gate, CXGate):
|
1177
|
+
if best_nbasis == 3:
|
1178
|
+
circuit = self._get_sx_vz_3cx_efficient_euler(decomposition, target_decomposed)
|
1179
|
+
elif best_nbasis == 2:
|
1180
|
+
circuit = self._get_sx_vz_2cx_efficient_euler(decomposition, target_decomposed)
|
1181
|
+
else:
|
1182
|
+
raise QiskitError("pulse_optimizer currently only works with CNOT entangling gate")
|
1183
|
+
else:
|
1184
|
+
raise QiskitError(
|
1185
|
+
'"pulse_optimize" currently only works with ZSX basis '
|
1186
|
+
f"({self._decomposer1q.basis} used)"
|
1187
|
+
)
|
1188
|
+
return circuit
|
1189
|
+
|
1190
|
+
def _get_sx_vz_2cx_efficient_euler(self, decomposition, target_decomposed):
|
1191
|
+
"""
|
1192
|
+
Decomposition of SU(4) gate for device with SX, virtual RZ, and CNOT gates assuming
|
1193
|
+
two CNOT gates are needed.
|
1194
|
+
|
1195
|
+
This first decomposes each unitary from the KAK decomposition into ZXZ on the source
|
1196
|
+
qubit of the CNOTs and XZX on the targets in order to commute operators to beginning and
|
1197
|
+
end of decomposition. The beginning and ending single qubit gates are then
|
1198
|
+
collapsed and re-decomposed with the single qubit decomposer. This last step could be avoided
|
1199
|
+
if performance is a concern.
|
1200
|
+
"""
|
1201
|
+
best_nbasis = 2 # by assumption
|
1202
|
+
num_1q_uni = len(decomposition)
|
1203
|
+
# list of euler angle decompositions on qubits 0 and 1
|
1204
|
+
euler_q0 = np.empty((num_1q_uni // 2, 3), dtype=float)
|
1205
|
+
euler_q1 = np.empty((num_1q_uni // 2, 3), dtype=float)
|
1206
|
+
global_phase = 0.0
|
1207
|
+
|
1208
|
+
# decompose source unitaries to zxz
|
1209
|
+
zxz_decomposer = OneQubitEulerDecomposer("ZXZ")
|
1210
|
+
for iqubit, decomp in enumerate(decomposition[0::2]):
|
1211
|
+
euler_angles = zxz_decomposer.angles_and_phase(decomp)
|
1212
|
+
euler_q0[iqubit, [1, 2, 0]] = euler_angles[:3]
|
1213
|
+
global_phase += euler_angles[3]
|
1214
|
+
# decompose target unitaries to xzx
|
1215
|
+
xzx_decomposer = OneQubitEulerDecomposer("XZX")
|
1216
|
+
for iqubit, decomp in enumerate(decomposition[1::2]):
|
1217
|
+
euler_angles = xzx_decomposer.angles_and_phase(decomp)
|
1218
|
+
euler_q1[iqubit, [1, 2, 0]] = euler_angles[:3]
|
1219
|
+
global_phase += euler_angles[3]
|
1220
|
+
qc = QuantumCircuit(2)
|
1221
|
+
qc.global_phase = target_decomposed.global_phase
|
1222
|
+
qc.global_phase -= best_nbasis * self.basis.global_phase
|
1223
|
+
qc.global_phase += global_phase
|
1224
|
+
|
1225
|
+
# TODO: make this more effecient to avoid double decomposition
|
1226
|
+
# prepare beginning 0th qubit local unitary
|
1227
|
+
circ = QuantumCircuit(1)
|
1228
|
+
circ.rz(euler_q0[0][0], 0)
|
1229
|
+
circ.rx(euler_q0[0][1], 0)
|
1230
|
+
circ.rz(euler_q0[0][2] + euler_q0[1][0] + math.pi / 2, 0)
|
1231
|
+
# re-decompose to basis of 1q decomposer
|
1232
|
+
qceuler = self._decomposer1q(Operator(circ).data)
|
1233
|
+
qc.compose(qceuler, [0], inplace=True)
|
1234
|
+
|
1235
|
+
# prepare beginning 1st qubit local unitary
|
1236
|
+
circ = QuantumCircuit(1)
|
1237
|
+
circ.rx(euler_q1[0][0], 0)
|
1238
|
+
circ.rz(euler_q1[0][1], 0)
|
1239
|
+
circ.rx(euler_q1[0][2] + euler_q1[1][0], 0)
|
1240
|
+
qceuler = self._decomposer1q(Operator(circ).data)
|
1241
|
+
qc.compose(qceuler, [1], inplace=True)
|
1242
|
+
|
1243
|
+
qc.cx(0, 1)
|
1244
|
+
# the central decompositions are dependent on the specific form of the
|
1245
|
+
# unitaries coming out of the two qubit decomposer which have some flexibility
|
1246
|
+
# of choice.
|
1247
|
+
qc.sx(0)
|
1248
|
+
qc.rz(euler_q0[1][1] - math.pi, 0)
|
1249
|
+
qc.sx(0)
|
1250
|
+
qc.rz(euler_q1[1][1], 1)
|
1251
|
+
qc.global_phase += math.pi / 2
|
1252
|
+
|
1253
|
+
qc.cx(0, 1)
|
1254
|
+
|
1255
|
+
circ = QuantumCircuit(1)
|
1256
|
+
circ.rz(euler_q0[1][2] + euler_q0[2][0] + math.pi / 2, 0)
|
1257
|
+
circ.rx(euler_q0[2][1], 0)
|
1258
|
+
circ.rz(euler_q0[2][2], 0)
|
1259
|
+
qceuler = self._decomposer1q(Operator(circ).data)
|
1260
|
+
qc.compose(qceuler, [0], inplace=True)
|
1261
|
+
circ = QuantumCircuit(1)
|
1262
|
+
circ.rx(euler_q1[1][2] + euler_q1[2][0], 0)
|
1263
|
+
circ.rz(euler_q1[2][1], 0)
|
1264
|
+
circ.rx(euler_q1[2][2], 0)
|
1265
|
+
qceuler = self._decomposer1q(Operator(circ).data)
|
1266
|
+
qc.compose(qceuler, [1], inplace=True)
|
1267
|
+
|
1268
|
+
return qc
|
1269
|
+
|
1270
|
+
def _get_sx_vz_3cx_efficient_euler(self, decomposition, target_decomposed):
|
1271
|
+
"""
|
1272
|
+
Decomposition of SU(4) gate for device with SX, virtual RZ, and CNOT gates assuming
|
1273
|
+
three CNOT gates are needed.
|
1274
|
+
|
1275
|
+
This first decomposes each unitary from the KAK decomposition into ZXZ on the source
|
1276
|
+
qubit of the CNOTs and XZX on the targets in order commute operators to beginning and
|
1277
|
+
end of decomposition. Inserting Hadamards reverses the direction of the CNOTs and transforms
|
1278
|
+
a variable Rx -> variable virtual Rz. The beginning and ending single qubit gates are then
|
1279
|
+
collapsed and re-decomposed with the single qubit decomposer. This last step could be avoided
|
1280
|
+
if performance is a concern.
|
1281
|
+
"""
|
1282
|
+
best_nbasis = 3 # by assumption
|
1283
|
+
num_1q_uni = len(decomposition)
|
1284
|
+
# create structure to hold euler angles: 1st index represents unitary "group" wrt cx
|
1285
|
+
# 2nd index represents index of euler triple.
|
1286
|
+
euler_q0 = np.empty((num_1q_uni // 2, 3), dtype=float)
|
1287
|
+
euler_q1 = np.empty((num_1q_uni // 2, 3), dtype=float)
|
1288
|
+
global_phase = 0.0
|
1289
|
+
atol = 1e-10 # absolute tolerance for floats
|
1290
|
+
|
1291
|
+
# decompose source unitaries to zxz
|
1292
|
+
zxz_decomposer = OneQubitEulerDecomposer("ZXZ")
|
1293
|
+
for iqubit, decomp in enumerate(decomposition[0::2]):
|
1294
|
+
euler_angles = zxz_decomposer.angles_and_phase(decomp)
|
1295
|
+
euler_q0[iqubit, [1, 2, 0]] = euler_angles[:3]
|
1296
|
+
global_phase += euler_angles[3]
|
1297
|
+
# decompose target unitaries to xzx
|
1298
|
+
xzx_decomposer = OneQubitEulerDecomposer("XZX")
|
1299
|
+
for iqubit, decomp in enumerate(decomposition[1::2]):
|
1300
|
+
euler_angles = xzx_decomposer.angles_and_phase(decomp)
|
1301
|
+
euler_q1[iqubit, [1, 2, 0]] = euler_angles[:3]
|
1302
|
+
global_phase += euler_angles[3]
|
1303
|
+
|
1304
|
+
qc = QuantumCircuit(2)
|
1305
|
+
qc.global_phase = target_decomposed.global_phase
|
1306
|
+
qc.global_phase -= best_nbasis * self.basis.global_phase
|
1307
|
+
qc.global_phase += global_phase
|
1308
|
+
|
1309
|
+
x12 = euler_q0[1][2] + euler_q0[2][0]
|
1310
|
+
x12_isNonZero = not math.isclose(x12, 0, abs_tol=atol)
|
1311
|
+
x12_isOddMult = None
|
1312
|
+
x12_isPiMult = math.isclose(math.sin(x12), 0, abs_tol=atol)
|
1313
|
+
if x12_isPiMult:
|
1314
|
+
x12_isOddMult = math.isclose(math.cos(x12), -1, abs_tol=atol)
|
1315
|
+
x12_phase = math.pi * math.cos(x12)
|
1316
|
+
x02_add = x12 - euler_q0[1][0]
|
1317
|
+
x12_isHalfPi = math.isclose(x12, math.pi / 2, abs_tol=atol)
|
1318
|
+
|
1319
|
+
# TODO: make this more effecient to avoid double decomposition
|
1320
|
+
circ = QuantumCircuit(1)
|
1321
|
+
circ.rz(euler_q0[0][0], 0)
|
1322
|
+
circ.rx(euler_q0[0][1], 0)
|
1323
|
+
if x12_isNonZero and x12_isPiMult:
|
1324
|
+
circ.rz(euler_q0[0][2] - x02_add, 0)
|
1325
|
+
else:
|
1326
|
+
circ.rz(euler_q0[0][2] + euler_q0[1][0], 0)
|
1327
|
+
circ.h(0)
|
1328
|
+
qceuler = self._decomposer1q(Operator(circ).data)
|
1329
|
+
qc.compose(qceuler, [0], inplace=True)
|
1330
|
+
|
1331
|
+
circ = QuantumCircuit(1)
|
1332
|
+
circ.rx(euler_q1[0][0], 0)
|
1333
|
+
circ.rz(euler_q1[0][1], 0)
|
1334
|
+
circ.rx(euler_q1[0][2] + euler_q1[1][0], 0)
|
1335
|
+
circ.h(0)
|
1336
|
+
qceuler = self._decomposer1q(Operator(circ).data)
|
1337
|
+
qc.compose(qceuler, [1], inplace=True)
|
1338
|
+
|
1339
|
+
qc.cx(1, 0)
|
1340
|
+
|
1341
|
+
if x12_isPiMult:
|
1342
|
+
# even or odd multiple
|
1343
|
+
if x12_isNonZero:
|
1344
|
+
qc.global_phase += x12_phase
|
1345
|
+
if x12_isNonZero and x12_isOddMult:
|
1346
|
+
qc.rz(-euler_q0[1][1], 0)
|
1347
|
+
else:
|
1348
|
+
qc.rz(euler_q0[1][1], 0)
|
1349
|
+
qc.global_phase += math.pi
|
1350
|
+
if x12_isHalfPi:
|
1351
|
+
qc.sx(0)
|
1352
|
+
qc.global_phase -= math.pi / 4
|
1353
|
+
elif x12_isNonZero and not x12_isPiMult:
|
1354
|
+
# this is non-optimal but doesn't seem to occur currently
|
1355
|
+
if self.pulse_optimize is None:
|
1356
|
+
qc.compose(self._decomposer1q(Operator(RXGate(x12)).data), [0], inplace=True)
|
1357
|
+
else:
|
1358
|
+
raise QiskitError("possible non-pulse-optimal decomposition encountered")
|
1359
|
+
if math.isclose(euler_q1[1][1], math.pi / 2, abs_tol=atol):
|
1360
|
+
qc.sx(1)
|
1361
|
+
qc.global_phase -= math.pi / 4
|
1362
|
+
else:
|
1363
|
+
# this is non-optimal but doesn't seem to occur currently
|
1364
|
+
if self.pulse_optimize is None:
|
1365
|
+
qc.compose(
|
1366
|
+
self._decomposer1q(Operator(RXGate(euler_q1[1][1])).data), [1], inplace=True
|
1367
|
+
)
|
1368
|
+
else:
|
1369
|
+
raise QiskitError("possible non-pulse-optimal decomposition encountered")
|
1370
|
+
qc.rz(euler_q1[1][2] + euler_q1[2][0], 1)
|
1371
|
+
|
1372
|
+
qc.cx(1, 0)
|
1373
|
+
|
1374
|
+
qc.rz(euler_q0[2][1], 0)
|
1375
|
+
if math.isclose(euler_q1[2][1], math.pi / 2, abs_tol=atol):
|
1376
|
+
qc.sx(1)
|
1377
|
+
qc.global_phase -= math.pi / 4
|
1378
|
+
else:
|
1379
|
+
# this is non-optimal but doesn't seem to occur currently
|
1380
|
+
if self.pulse_optimize is None:
|
1381
|
+
qc.compose(
|
1382
|
+
self._decomposer1q(Operator(RXGate(euler_q1[2][1])).data), [1], inplace=True
|
1383
|
+
)
|
1384
|
+
else:
|
1385
|
+
raise QiskitError("possible non-pulse-optimal decomposition encountered")
|
1386
|
+
|
1387
|
+
qc.cx(1, 0)
|
1388
|
+
|
1389
|
+
circ = QuantumCircuit(1)
|
1390
|
+
circ.h(0)
|
1391
|
+
circ.rz(euler_q0[2][2] + euler_q0[3][0], 0)
|
1392
|
+
circ.rx(euler_q0[3][1], 0)
|
1393
|
+
circ.rz(euler_q0[3][2], 0)
|
1394
|
+
qceuler = self._decomposer1q(Operator(circ).data)
|
1395
|
+
qc.compose(qceuler, [0], inplace=True)
|
1396
|
+
|
1397
|
+
circ = QuantumCircuit(1)
|
1398
|
+
circ.h(0)
|
1399
|
+
circ.rx(euler_q1[2][2] + euler_q1[3][0], 0)
|
1400
|
+
circ.rz(euler_q1[3][1], 0)
|
1401
|
+
circ.rx(euler_q1[3][2], 0)
|
1402
|
+
qceuler = self._decomposer1q(Operator(circ).data)
|
1403
|
+
qc.compose(qceuler, [1], inplace=True)
|
1404
|
+
|
1405
|
+
# TODO: fix the sign problem to avoid correction here
|
1406
|
+
if cmath.isclose(
|
1407
|
+
target_decomposed.unitary_matrix[0, 0], -(Operator(qc).data[0, 0]), abs_tol=atol
|
1408
|
+
):
|
1409
|
+
qc.global_phase += math.pi
|
1410
|
+
return qc
|
1411
|
+
|
1412
|
+
def num_basis_gates(self, unitary):
|
1413
|
+
"""Computes the number of basis gates needed in
|
1414
|
+
a decomposition of input unitary
|
1415
|
+
"""
|
1416
|
+
unitary = np.asarray(unitary, dtype=complex)
|
1417
|
+
a, b, c = weyl_coordinates(unitary)[:]
|
1418
|
+
traces = [
|
1419
|
+
4
|
1420
|
+
* (
|
1421
|
+
math.cos(a) * math.cos(b) * math.cos(c)
|
1422
|
+
+ 1j * math.sin(a) * math.sin(b) * math.sin(c)
|
1423
|
+
),
|
1424
|
+
4
|
1425
|
+
* (
|
1426
|
+
math.cos(np.pi / 4 - a) * math.cos(self.basis.b - b) * math.cos(c)
|
1427
|
+
+ 1j * math.sin(np.pi / 4 - a) * math.sin(self.basis.b - b) * math.sin(c)
|
1428
|
+
),
|
1429
|
+
4 * math.cos(c),
|
1430
|
+
4,
|
1431
|
+
]
|
1432
|
+
return np.argmax([trace_to_fid(traces[i]) * self.basis_fidelity**i for i in range(4)])
|
1433
|
+
|
1434
|
+
|
1435
|
+
class TwoQubitDecomposeUpToDiagonal:
|
1436
|
+
"""
|
1437
|
+
Class to decompose two qubit unitaries into the product of a diagonal gate
|
1438
|
+
and another unitary gate which can be represented by two CX gates instead of the
|
1439
|
+
usual three. This can be used when neighboring gates commute with the diagonal to
|
1440
|
+
potentially reduce overall CX count.
|
1441
|
+
"""
|
1442
|
+
|
1443
|
+
def __init__(self):
|
1444
|
+
sy = np.array([[0, -1j], [1j, 0]])
|
1445
|
+
self.sysy = np.kron(sy, sy)
|
1446
|
+
|
1447
|
+
def _u4_to_su4(self, u4):
|
1448
|
+
phase_factor = np.conj(np.linalg.det(u4) ** (-1 / u4.shape[0]))
|
1449
|
+
su4 = u4 / phase_factor
|
1450
|
+
return su4, cmath.phase(phase_factor)
|
1451
|
+
|
1452
|
+
def _gamma(self, mat):
|
1453
|
+
"""
|
1454
|
+
proposition II.1: this invariant characterizes when two operators in U(4),
|
1455
|
+
say u, v, are equivalent up to single qubit gates:
|
1456
|
+
|
1457
|
+
u ≡ v -> Det(γ(u)) = Det(±(γ(v)))
|
1458
|
+
"""
|
1459
|
+
sumat, _ = self._u4_to_su4(mat)
|
1460
|
+
sysy = self.sysy
|
1461
|
+
return sumat @ sysy @ sumat.T @ sysy
|
1462
|
+
|
1463
|
+
def _cx0_test(self, mat):
|
1464
|
+
# proposition III.1: zero cx sufficient
|
1465
|
+
gamma = self._gamma(mat)
|
1466
|
+
evals = np.linalg.eigvals(gamma)
|
1467
|
+
return np.all(np.isclose(evals, np.ones(4)))
|
1468
|
+
|
1469
|
+
def _cx1_test(self, mat):
|
1470
|
+
# proposition III.2: one cx sufficient
|
1471
|
+
gamma = self._gamma(mat)
|
1472
|
+
evals = np.linalg.eigvals(gamma)
|
1473
|
+
uvals, ucnts = np.unique(np.round(evals, 10), return_counts=True)
|
1474
|
+
return (
|
1475
|
+
len(uvals) == 2
|
1476
|
+
and all(ucnts == 2)
|
1477
|
+
and all((np.isclose(x, 1j)) or np.isclose(x, -1j) for x in uvals)
|
1478
|
+
)
|
1479
|
+
|
1480
|
+
def _cx2_test(self, mat):
|
1481
|
+
# proposition III.3: two cx sufficient
|
1482
|
+
gamma = self._gamma(mat)
|
1483
|
+
return np.isclose(np.trace(gamma).imag, 0)
|
1484
|
+
|
1485
|
+
def _real_trace_transform(self, mat):
|
1486
|
+
"""
|
1487
|
+
Determine diagonal gate such that
|
1488
|
+
|
1489
|
+
U3 = D U2
|
1490
|
+
|
1491
|
+
Where U3 is a general two-qubit gate which takes 3 cnots, D is a
|
1492
|
+
diagonal gate, and U2 is a gate which takes 2 cnots.
|
1493
|
+
"""
|
1494
|
+
a1 = (
|
1495
|
+
-mat[1, 3] * mat[2, 0]
|
1496
|
+
+ mat[1, 2] * mat[2, 1]
|
1497
|
+
+ mat[1, 1] * mat[2, 2]
|
1498
|
+
- mat[1, 0] * mat[2, 3]
|
1499
|
+
)
|
1500
|
+
a2 = (
|
1501
|
+
mat[0, 3] * mat[3, 0]
|
1502
|
+
- mat[0, 2] * mat[3, 1]
|
1503
|
+
- mat[0, 1] * mat[3, 2]
|
1504
|
+
+ mat[0, 0] * mat[3, 3]
|
1505
|
+
)
|
1506
|
+
theta = 0 # arbitrary
|
1507
|
+
phi = 0 # arbitrary
|
1508
|
+
psi = np.arctan2(a1.imag + a2.imag, a1.real - a2.real) - phi
|
1509
|
+
diag = np.diag(np.exp(-1j * np.array([theta, phi, psi, -(theta + phi + psi)])))
|
1510
|
+
return diag
|
1511
|
+
|
1512
|
+
def __call__(self, mat):
|
1513
|
+
"""do the decomposition"""
|
1514
|
+
su4, phase = self._u4_to_su4(mat)
|
1515
|
+
real_map = self._real_trace_transform(su4)
|
1516
|
+
mapped_su4 = real_map @ su4
|
1517
|
+
if not self._cx2_test(mapped_su4):
|
1518
|
+
warnings.warn("Unitary decomposition up to diagonal may use an additionl CX gate.")
|
1519
|
+
circ = two_qubit_cnot_decompose(mapped_su4)
|
1520
|
+
circ.global_phase += phase
|
1521
|
+
return real_map.conj(), circ
|
1522
|
+
|
1523
|
+
|
1524
|
+
# This weird duplicated lazy structure is for backwards compatibility; Qiskit has historically
|
1525
|
+
# always made ``two_qubit_cnot_decompose`` available publicly immediately on import, but it's quite
|
1526
|
+
# expensive to construct, and we want to defer the obejct's creation until it's actually used. We
|
1527
|
+
# only need to pass through the public methods that take `self` as a parameter. Using `__getattr__`
|
1528
|
+
# doesn't work because it is only called if the normal resolution methods fail. Using
|
1529
|
+
# `__getattribute__` is too messy for a simple one-off use object.
|
1530
|
+
|
1531
|
+
|
1532
|
+
class _LazyTwoQubitCXDecomposer(TwoQubitBasisDecomposer):
|
1533
|
+
__slots__ = ("_inner",)
|
1534
|
+
|
1535
|
+
def __init__(self): # pylint: disable=super-init-not-called
|
1536
|
+
self._inner = None
|
1537
|
+
|
1538
|
+
def _load(self):
|
1539
|
+
if self._inner is None:
|
1540
|
+
self._inner = TwoQubitBasisDecomposer(CXGate())
|
1541
|
+
|
1542
|
+
def __call__(self, *args, **kwargs) -> QuantumCircuit:
|
1543
|
+
self._load()
|
1544
|
+
return self._inner(*args, **kwargs)
|
1545
|
+
|
1546
|
+
def traces(self, target):
|
1547
|
+
self._load()
|
1548
|
+
return self._inner.traces(target)
|
1549
|
+
|
1550
|
+
def decomp1(self, target):
|
1551
|
+
self._load()
|
1552
|
+
return self._inner.decomp1(target)
|
1553
|
+
|
1554
|
+
def decomp2_supercontrolled(self, target):
|
1555
|
+
self._load()
|
1556
|
+
return self._inner.decomp2_supercontrolled(target)
|
1557
|
+
|
1558
|
+
def decomp3_supercontrolled(self, target):
|
1559
|
+
self._load()
|
1560
|
+
return self._inner.decomp3_supercontrolled(target)
|
1561
|
+
|
1562
|
+
def num_basis_gates(self, unitary):
|
1563
|
+
self._load()
|
1564
|
+
return self._inner.num_basis_gates(unitary)
|
1565
|
+
|
1566
|
+
|
1567
|
+
two_qubit_cnot_decompose = _LazyTwoQubitCXDecomposer()
|