qiskit 2.0.3__cp39-abi3-manylinux2014_aarch64.manylinux_2_17_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 +141 -0
- qiskit/_accelerate.abi3.so +0 -0
- qiskit/_numpy_compat.py +73 -0
- qiskit/circuit/__init__.py +1343 -0
- qiskit/circuit/_add_control.py +312 -0
- qiskit/circuit/_classical_resource_map.py +150 -0
- qiskit/circuit/_standard_gates_commutations.py +3849 -0
- qiskit/circuit/_utils.py +167 -0
- qiskit/circuit/annotated_operation.py +279 -0
- qiskit/circuit/barrier.py +46 -0
- qiskit/circuit/classical/__init__.py +41 -0
- qiskit/circuit/classical/expr/__init__.py +266 -0
- qiskit/circuit/classical/expr/constructors.py +764 -0
- qiskit/circuit/classical/expr/expr.py +498 -0
- qiskit/circuit/classical/expr/visitors.py +375 -0
- qiskit/circuit/classical/types/__init__.py +113 -0
- qiskit/circuit/classical/types/ordering.py +229 -0
- qiskit/circuit/classical/types/types.py +153 -0
- qiskit/circuit/commutation_checker.py +133 -0
- qiskit/circuit/commutation_library.py +20 -0
- qiskit/circuit/controlflow/__init__.py +59 -0
- qiskit/circuit/controlflow/_builder_utils.py +211 -0
- qiskit/circuit/controlflow/box.py +163 -0
- qiskit/circuit/controlflow/break_loop.py +56 -0
- qiskit/circuit/controlflow/builder.py +791 -0
- qiskit/circuit/controlflow/continue_loop.py +56 -0
- qiskit/circuit/controlflow/control_flow.py +94 -0
- qiskit/circuit/controlflow/for_loop.py +218 -0
- qiskit/circuit/controlflow/if_else.py +498 -0
- qiskit/circuit/controlflow/switch_case.py +411 -0
- qiskit/circuit/controlflow/while_loop.py +166 -0
- qiskit/circuit/controlledgate.py +274 -0
- qiskit/circuit/delay.py +157 -0
- qiskit/circuit/duration.py +80 -0
- qiskit/circuit/equivalence.py +94 -0
- qiskit/circuit/equivalence_library.py +18 -0
- qiskit/circuit/exceptions.py +19 -0
- qiskit/circuit/gate.py +261 -0
- qiskit/circuit/instruction.py +564 -0
- qiskit/circuit/instructionset.py +132 -0
- qiskit/circuit/library/__init__.py +984 -0
- qiskit/circuit/library/arithmetic/__init__.py +40 -0
- qiskit/circuit/library/arithmetic/adders/__init__.py +18 -0
- qiskit/circuit/library/arithmetic/adders/adder.py +235 -0
- qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +123 -0
- qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +129 -0
- qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +95 -0
- qiskit/circuit/library/arithmetic/exact_reciprocal.py +131 -0
- qiskit/circuit/library/arithmetic/functional_pauli_rotations.py +114 -0
- qiskit/circuit/library/arithmetic/integer_comparator.py +200 -0
- qiskit/circuit/library/arithmetic/linear_amplitude_function.py +363 -0
- qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +243 -0
- qiskit/circuit/library/arithmetic/multipliers/__init__.py +17 -0
- qiskit/circuit/library/arithmetic/multipliers/hrs_cumulative_multiplier.py +145 -0
- qiskit/circuit/library/arithmetic/multipliers/multiplier.py +201 -0
- qiskit/circuit/library/arithmetic/multipliers/rg_qft_multiplier.py +108 -0
- qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +502 -0
- qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +387 -0
- qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +493 -0
- qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +389 -0
- qiskit/circuit/library/arithmetic/quadratic_form.py +364 -0
- qiskit/circuit/library/arithmetic/weighted_adder.py +409 -0
- qiskit/circuit/library/basis_change/__init__.py +15 -0
- qiskit/circuit/library/basis_change/qft.py +316 -0
- qiskit/circuit/library/bit_flip_oracle.py +130 -0
- qiskit/circuit/library/blueprintcircuit.py +316 -0
- qiskit/circuit/library/boolean_logic/__init__.py +18 -0
- qiskit/circuit/library/boolean_logic/inner_product.py +157 -0
- qiskit/circuit/library/boolean_logic/quantum_and.py +204 -0
- qiskit/circuit/library/boolean_logic/quantum_or.py +206 -0
- qiskit/circuit/library/boolean_logic/quantum_xor.py +167 -0
- qiskit/circuit/library/data_preparation/__init__.py +57 -0
- qiskit/circuit/library/data_preparation/_z_feature_map.py +115 -0
- qiskit/circuit/library/data_preparation/_zz_feature_map.py +150 -0
- qiskit/circuit/library/data_preparation/initializer.py +107 -0
- qiskit/circuit/library/data_preparation/pauli_feature_map.py +656 -0
- qiskit/circuit/library/data_preparation/state_preparation.py +336 -0
- qiskit/circuit/library/fourier_checking.py +160 -0
- qiskit/circuit/library/generalized_gates/__init__.py +30 -0
- qiskit/circuit/library/generalized_gates/diagonal.py +159 -0
- qiskit/circuit/library/generalized_gates/gms.py +175 -0
- qiskit/circuit/library/generalized_gates/gr.py +219 -0
- qiskit/circuit/library/generalized_gates/isometry.py +370 -0
- qiskit/circuit/library/generalized_gates/linear_function.py +318 -0
- qiskit/circuit/library/generalized_gates/mcg_up_to_diagonal.py +143 -0
- qiskit/circuit/library/generalized_gates/mcmt.py +316 -0
- qiskit/circuit/library/generalized_gates/pauli.py +84 -0
- qiskit/circuit/library/generalized_gates/permutation.py +198 -0
- qiskit/circuit/library/generalized_gates/rv.py +96 -0
- qiskit/circuit/library/generalized_gates/uc.py +303 -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 +217 -0
- qiskit/circuit/library/graph_state.py +172 -0
- qiskit/circuit/library/grover_operator.py +583 -0
- qiskit/circuit/library/hamiltonian_gate.py +142 -0
- qiskit/circuit/library/hidden_linear_function.py +163 -0
- qiskit/circuit/library/iqp.py +180 -0
- qiskit/circuit/library/n_local/__init__.py +45 -0
- qiskit/circuit/library/n_local/efficient_su2.py +282 -0
- qiskit/circuit/library/n_local/evolved_operator_ansatz.py +520 -0
- qiskit/circuit/library/n_local/excitation_preserving.py +303 -0
- qiskit/circuit/library/n_local/n_local.py +1477 -0
- qiskit/circuit/library/n_local/pauli_two_design.py +246 -0
- qiskit/circuit/library/n_local/qaoa_ansatz.py +367 -0
- qiskit/circuit/library/n_local/real_amplitudes.py +312 -0
- qiskit/circuit/library/n_local/two_local.py +289 -0
- qiskit/circuit/library/overlap.py +183 -0
- qiskit/circuit/library/pauli_evolution.py +201 -0
- qiskit/circuit/library/phase_estimation.py +177 -0
- qiskit/circuit/library/phase_oracle.py +239 -0
- qiskit/circuit/library/quantum_volume.py +180 -0
- qiskit/circuit/library/standard_gates/__init__.py +141 -0
- qiskit/circuit/library/standard_gates/dcx.py +77 -0
- qiskit/circuit/library/standard_gates/ecr.py +129 -0
- qiskit/circuit/library/standard_gates/equivalence_library.py +1800 -0
- qiskit/circuit/library/standard_gates/global_phase.py +84 -0
- qiskit/circuit/library/standard_gates/h.py +253 -0
- qiskit/circuit/library/standard_gates/i.py +76 -0
- qiskit/circuit/library/standard_gates/iswap.py +133 -0
- qiskit/circuit/library/standard_gates/p.py +422 -0
- qiskit/circuit/library/standard_gates/r.py +114 -0
- qiskit/circuit/library/standard_gates/rx.py +293 -0
- qiskit/circuit/library/standard_gates/rxx.py +180 -0
- qiskit/circuit/library/standard_gates/ry.py +286 -0
- qiskit/circuit/library/standard_gates/ryy.py +180 -0
- qiskit/circuit/library/standard_gates/rz.py +307 -0
- qiskit/circuit/library/standard_gates/rzx.py +226 -0
- qiskit/circuit/library/standard_gates/rzz.py +193 -0
- qiskit/circuit/library/standard_gates/s.py +419 -0
- qiskit/circuit/library/standard_gates/swap.py +281 -0
- qiskit/circuit/library/standard_gates/sx.py +310 -0
- qiskit/circuit/library/standard_gates/t.py +178 -0
- qiskit/circuit/library/standard_gates/u.py +395 -0
- qiskit/circuit/library/standard_gates/u1.py +490 -0
- qiskit/circuit/library/standard_gates/u2.py +145 -0
- qiskit/circuit/library/standard_gates/u3.py +428 -0
- qiskit/circuit/library/standard_gates/x.py +1481 -0
- qiskit/circuit/library/standard_gates/xx_minus_yy.py +202 -0
- qiskit/circuit/library/standard_gates/xx_plus_yy.py +236 -0
- qiskit/circuit/library/standard_gates/y.py +257 -0
- qiskit/circuit/library/standard_gates/z.py +338 -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 +34 -0
- qiskit/circuit/library/templates/clifford/clifford_2_2.py +35 -0
- qiskit/circuit/library/templates/clifford/clifford_2_3.py +34 -0
- qiskit/circuit/library/templates/clifford/clifford_2_4.py +34 -0
- qiskit/circuit/library/templates/clifford/clifford_3_1.py +35 -0
- qiskit/circuit/library/templates/clifford/clifford_4_1.py +38 -0
- qiskit/circuit/library/templates/clifford/clifford_4_2.py +37 -0
- qiskit/circuit/library/templates/clifford/clifford_4_3.py +38 -0
- qiskit/circuit/library/templates/clifford/clifford_4_4.py +37 -0
- qiskit/circuit/library/templates/clifford/clifford_5_1.py +40 -0
- qiskit/circuit/library/templates/clifford/clifford_6_1.py +40 -0
- qiskit/circuit/library/templates/clifford/clifford_6_2.py +40 -0
- qiskit/circuit/library/templates/clifford/clifford_6_3.py +40 -0
- qiskit/circuit/library/templates/clifford/clifford_6_4.py +38 -0
- qiskit/circuit/library/templates/clifford/clifford_6_5.py +40 -0
- qiskit/circuit/library/templates/clifford/clifford_8_1.py +42 -0
- qiskit/circuit/library/templates/clifford/clifford_8_2.py +42 -0
- qiskit/circuit/library/templates/clifford/clifford_8_3.py +41 -0
- qiskit/circuit/library/templates/nct/__init__.py +67 -0
- qiskit/circuit/library/templates/nct/template_nct_2a_1.py +34 -0
- qiskit/circuit/library/templates/nct/template_nct_2a_2.py +35 -0
- qiskit/circuit/library/templates/nct/template_nct_2a_3.py +37 -0
- qiskit/circuit/library/templates/nct/template_nct_4a_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_4a_2.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_4a_3.py +39 -0
- qiskit/circuit/library/templates/nct/template_nct_4b_1.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_4b_2.py +39 -0
- qiskit/circuit/library/templates/nct/template_nct_5a_1.py +40 -0
- qiskit/circuit/library/templates/nct/template_nct_5a_2.py +40 -0
- qiskit/circuit/library/templates/nct/template_nct_5a_3.py +40 -0
- qiskit/circuit/library/templates/nct/template_nct_5a_4.py +39 -0
- qiskit/circuit/library/templates/nct/template_nct_6a_1.py +40 -0
- qiskit/circuit/library/templates/nct/template_nct_6a_2.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_6a_3.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_6a_4.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_6b_1.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_6b_2.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_6c_1.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_7a_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_7b_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_7c_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_7d_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_7e_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_9a_1.py +45 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_10.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_11.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_12.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_2.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_3.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_4.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_5.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_6.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_7.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_8.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_9.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_10.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_2.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_3.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_4.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_5.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_6.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_7.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_8.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_9.py +44 -0
- qiskit/circuit/library/templates/rzx/__init__.py +25 -0
- qiskit/circuit/library/templates/rzx/rzx_cy.py +47 -0
- qiskit/circuit/library/templates/rzx/rzx_xz.py +54 -0
- qiskit/circuit/library/templates/rzx/rzx_yz.py +45 -0
- qiskit/circuit/library/templates/rzx/rzx_zz1.py +69 -0
- qiskit/circuit/library/templates/rzx/rzx_zz2.py +59 -0
- qiskit/circuit/library/templates/rzx/rzx_zz3.py +59 -0
- qiskit/circuit/measure.py +53 -0
- qiskit/circuit/operation.py +68 -0
- qiskit/circuit/parameter.py +179 -0
- qiskit/circuit/parameterexpression.py +703 -0
- qiskit/circuit/parametertable.py +119 -0
- qiskit/circuit/parametervector.py +140 -0
- qiskit/circuit/quantumcircuit.py +7540 -0
- qiskit/circuit/quantumcircuitdata.py +136 -0
- qiskit/circuit/random/__init__.py +15 -0
- qiskit/circuit/random/utils.py +366 -0
- qiskit/circuit/reset.py +37 -0
- qiskit/circuit/singleton.py +600 -0
- qiskit/circuit/store.py +89 -0
- qiskit/circuit/tools/__init__.py +16 -0
- qiskit/circuit/tools/pi_check.py +193 -0
- qiskit/circuit/twirling.py +145 -0
- qiskit/compiler/__init__.py +27 -0
- qiskit/compiler/transpiler.py +375 -0
- qiskit/converters/__init__.py +74 -0
- qiskit/converters/circuit_to_dag.py +80 -0
- qiskit/converters/circuit_to_dagdependency.py +49 -0
- qiskit/converters/circuit_to_dagdependency_v2.py +46 -0
- qiskit/converters/circuit_to_gate.py +107 -0
- qiskit/converters/circuit_to_instruction.py +142 -0
- qiskit/converters/dag_to_circuit.py +79 -0
- qiskit/converters/dag_to_dagdependency.py +54 -0
- qiskit/converters/dag_to_dagdependency_v2.py +43 -0
- qiskit/converters/dagdependency_to_circuit.py +40 -0
- qiskit/converters/dagdependency_to_dag.py +48 -0
- qiskit/dagcircuit/__init__.py +55 -0
- qiskit/dagcircuit/collect_blocks.py +407 -0
- qiskit/dagcircuit/dagcircuit.py +24 -0
- qiskit/dagcircuit/dagdependency.py +612 -0
- qiskit/dagcircuit/dagdependency_v2.py +566 -0
- qiskit/dagcircuit/dagdepnode.py +160 -0
- qiskit/dagcircuit/dagnode.py +188 -0
- qiskit/dagcircuit/exceptions.py +42 -0
- qiskit/exceptions.py +153 -0
- qiskit/passmanager/__init__.py +258 -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 +116 -0
- qiskit/passmanager/passmanager.py +353 -0
- qiskit/primitives/__init__.py +490 -0
- qiskit/primitives/backend_estimator_v2.py +530 -0
- qiskit/primitives/backend_sampler_v2.py +339 -0
- qiskit/primitives/base/__init__.py +20 -0
- qiskit/primitives/base/base_estimator.py +247 -0
- qiskit/primitives/base/base_primitive_job.py +78 -0
- qiskit/primitives/base/base_primitive_v1.py +45 -0
- qiskit/primitives/base/base_result_v1.py +65 -0
- qiskit/primitives/base/base_sampler.py +196 -0
- qiskit/primitives/base/estimator_result_v1.py +46 -0
- qiskit/primitives/base/sampler_result_v1.py +45 -0
- qiskit/primitives/base/validation_v1.py +250 -0
- qiskit/primitives/containers/__init__.py +26 -0
- qiskit/primitives/containers/bindings_array.py +391 -0
- qiskit/primitives/containers/bit_array.py +764 -0
- qiskit/primitives/containers/data_bin.py +175 -0
- qiskit/primitives/containers/estimator_pub.py +222 -0
- qiskit/primitives/containers/object_array.py +94 -0
- qiskit/primitives/containers/observables_array.py +296 -0
- qiskit/primitives/containers/primitive_result.py +53 -0
- qiskit/primitives/containers/pub_result.py +51 -0
- qiskit/primitives/containers/sampler_pub.py +193 -0
- qiskit/primitives/containers/sampler_pub_result.py +74 -0
- qiskit/primitives/containers/shape.py +129 -0
- qiskit/primitives/primitive_job.py +81 -0
- qiskit/primitives/statevector_estimator.py +175 -0
- qiskit/primitives/statevector_sampler.py +290 -0
- qiskit/primitives/utils.py +72 -0
- qiskit/providers/__init__.py +677 -0
- qiskit/providers/backend.py +364 -0
- qiskit/providers/basic_provider/__init__.py +47 -0
- qiskit/providers/basic_provider/basic_provider.py +121 -0
- qiskit/providers/basic_provider/basic_provider_job.py +65 -0
- qiskit/providers/basic_provider/basic_provider_tools.py +218 -0
- qiskit/providers/basic_provider/basic_simulator.py +693 -0
- qiskit/providers/basic_provider/exceptions.py +30 -0
- qiskit/providers/exceptions.py +33 -0
- qiskit/providers/fake_provider/__init__.py +69 -0
- qiskit/providers/fake_provider/generic_backend_v2.py +374 -0
- qiskit/providers/fake_provider/utils/__init__.py +15 -0
- qiskit/providers/job.py +147 -0
- qiskit/providers/jobstatus.py +30 -0
- qiskit/providers/options.py +273 -0
- qiskit/providers/providerutils.py +110 -0
- qiskit/qasm/libs/dummy/stdgates.inc +75 -0
- qiskit/qasm/libs/qelib1.inc +266 -0
- qiskit/qasm/libs/stdgates.inc +82 -0
- qiskit/qasm2/__init__.py +669 -0
- qiskit/qasm2/exceptions.py +27 -0
- qiskit/qasm2/export.py +364 -0
- qiskit/qasm2/parse.py +438 -0
- qiskit/qasm3/__init__.py +372 -0
- qiskit/qasm3/ast.py +782 -0
- qiskit/qasm3/exceptions.py +27 -0
- qiskit/qasm3/experimental.py +70 -0
- qiskit/qasm3/exporter.py +1340 -0
- qiskit/qasm3/printer.py +608 -0
- qiskit/qpy/__init__.py +1965 -0
- qiskit/qpy/binary_io/__init__.py +35 -0
- qiskit/qpy/binary_io/circuits.py +1455 -0
- qiskit/qpy/binary_io/parse_sympy_repr.py +121 -0
- qiskit/qpy/binary_io/schedules.py +308 -0
- qiskit/qpy/binary_io/value.py +1165 -0
- qiskit/qpy/common.py +353 -0
- qiskit/qpy/exceptions.py +53 -0
- qiskit/qpy/formats.py +442 -0
- qiskit/qpy/interface.py +344 -0
- qiskit/qpy/type_keys.py +409 -0
- qiskit/quantum_info/__init__.py +162 -0
- qiskit/quantum_info/analysis/__init__.py +17 -0
- qiskit/quantum_info/analysis/average.py +47 -0
- qiskit/quantum_info/analysis/distance.py +104 -0
- qiskit/quantum_info/analysis/make_observable.py +44 -0
- qiskit/quantum_info/analysis/z2_symmetries.py +484 -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 +191 -0
- qiskit/quantum_info/operators/channel/choi.py +218 -0
- qiskit/quantum_info/operators/channel/kraus.py +337 -0
- qiskit/quantum_info/operators/channel/ptm.py +204 -0
- qiskit/quantum_info/operators/channel/quantum_channel.py +348 -0
- qiskit/quantum_info/operators/channel/stinespring.py +296 -0
- qiskit/quantum_info/operators/channel/superop.py +373 -0
- qiskit/quantum_info/operators/channel/transformations.py +490 -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 +511 -0
- qiskit/quantum_info/operators/dihedral/dihedral_circuits.py +216 -0
- qiskit/quantum_info/operators/dihedral/polynomial.py +313 -0
- qiskit/quantum_info/operators/dihedral/random.py +64 -0
- qiskit/quantum_info/operators/linear_op.py +25 -0
- qiskit/quantum_info/operators/measures.py +418 -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 +525 -0
- qiskit/quantum_info/operators/operator.py +869 -0
- qiskit/quantum_info/operators/operator_utils.py +76 -0
- qiskit/quantum_info/operators/predicates.py +183 -0
- qiskit/quantum_info/operators/random.py +154 -0
- qiskit/quantum_info/operators/scalar_op.py +254 -0
- qiskit/quantum_info/operators/symplectic/__init__.py +23 -0
- qiskit/quantum_info/operators/symplectic/base_pauli.py +719 -0
- qiskit/quantum_info/operators/symplectic/clifford.py +1032 -0
- qiskit/quantum_info/operators/symplectic/clifford_circuits.py +558 -0
- qiskit/quantum_info/operators/symplectic/pauli.py +755 -0
- qiskit/quantum_info/operators/symplectic/pauli_list.py +1242 -0
- qiskit/quantum_info/operators/symplectic/pauli_utils.py +40 -0
- qiskit/quantum_info/operators/symplectic/random.py +117 -0
- qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +1239 -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/quaternion.py +156 -0
- qiskit/quantum_info/random.py +26 -0
- qiskit/quantum_info/states/__init__.py +28 -0
- qiskit/quantum_info/states/densitymatrix.py +857 -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 +805 -0
- qiskit/quantum_info/states/statevector.py +977 -0
- qiskit/quantum_info/states/utils.py +247 -0
- qiskit/result/__init__.py +61 -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/models.py +241 -0
- qiskit/result/postprocess.py +239 -0
- qiskit/result/result.py +385 -0
- qiskit/result/sampled_expval.py +74 -0
- qiskit/result/utils.py +294 -0
- qiskit/synthesis/__init__.py +240 -0
- qiskit/synthesis/arithmetic/__init__.py +18 -0
- qiskit/synthesis/arithmetic/adders/__init__.py +17 -0
- qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +154 -0
- qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +103 -0
- qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +161 -0
- qiskit/synthesis/arithmetic/comparators/__init__.py +16 -0
- qiskit/synthesis/arithmetic/comparators/compare_2s.py +112 -0
- qiskit/synthesis/arithmetic/comparators/compare_greedy.py +66 -0
- qiskit/synthesis/arithmetic/multipliers/__init__.py +16 -0
- qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +103 -0
- qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +100 -0
- qiskit/synthesis/arithmetic/weighted_sum.py +155 -0
- qiskit/synthesis/boolean/__init__.py +13 -0
- qiskit/synthesis/boolean/boolean_expression.py +231 -0
- qiskit/synthesis/boolean/boolean_expression_synth.py +124 -0
- qiskit/synthesis/boolean/boolean_expression_visitor.py +96 -0
- qiskit/synthesis/clifford/__init__.py +19 -0
- qiskit/synthesis/clifford/clifford_decompose_ag.py +178 -0
- qiskit/synthesis/clifford/clifford_decompose_bm.py +46 -0
- qiskit/synthesis/clifford/clifford_decompose_full.py +64 -0
- qiskit/synthesis/clifford/clifford_decompose_greedy.py +58 -0
- qiskit/synthesis/clifford/clifford_decompose_layers.py +447 -0
- qiskit/synthesis/cnotdihedral/__init__.py +17 -0
- qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_full.py +52 -0
- qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_general.py +141 -0
- qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_two_qubits.py +266 -0
- qiskit/synthesis/discrete_basis/__init__.py +16 -0
- qiskit/synthesis/discrete_basis/commutator_decompose.py +265 -0
- qiskit/synthesis/discrete_basis/gate_sequence.py +421 -0
- qiskit/synthesis/discrete_basis/generate_basis_approximations.py +165 -0
- qiskit/synthesis/discrete_basis/solovay_kitaev.py +240 -0
- qiskit/synthesis/evolution/__init__.py +21 -0
- qiskit/synthesis/evolution/evolution_synthesis.py +48 -0
- qiskit/synthesis/evolution/lie_trotter.py +120 -0
- qiskit/synthesis/evolution/matrix_synthesis.py +47 -0
- qiskit/synthesis/evolution/pauli_network.py +80 -0
- qiskit/synthesis/evolution/product_formula.py +313 -0
- qiskit/synthesis/evolution/qdrift.py +130 -0
- qiskit/synthesis/evolution/suzuki_trotter.py +224 -0
- qiskit/synthesis/linear/__init__.py +26 -0
- qiskit/synthesis/linear/cnot_synth.py +69 -0
- qiskit/synthesis/linear/linear_circuits_utils.py +128 -0
- qiskit/synthesis/linear/linear_depth_lnn.py +61 -0
- qiskit/synthesis/linear/linear_matrix_utils.py +27 -0
- qiskit/synthesis/linear_phase/__init__.py +17 -0
- qiskit/synthesis/linear_phase/cnot_phase_synth.py +206 -0
- qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +61 -0
- qiskit/synthesis/linear_phase/cz_depth_lnn.py +58 -0
- qiskit/synthesis/multi_controlled/__init__.py +25 -0
- qiskit/synthesis/multi_controlled/mcmt_vchain.py +52 -0
- qiskit/synthesis/multi_controlled/mcx_synthesis.py +359 -0
- qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +206 -0
- qiskit/synthesis/one_qubit/__init__.py +15 -0
- qiskit/synthesis/one_qubit/one_qubit_decompose.py +288 -0
- qiskit/synthesis/permutation/__init__.py +18 -0
- qiskit/synthesis/permutation/permutation_full.py +78 -0
- qiskit/synthesis/permutation/permutation_lnn.py +54 -0
- qiskit/synthesis/permutation/permutation_reverse_lnn.py +93 -0
- qiskit/synthesis/permutation/permutation_utils.py +16 -0
- qiskit/synthesis/qft/__init__.py +16 -0
- qiskit/synthesis/qft/qft_decompose_full.py +97 -0
- qiskit/synthesis/qft/qft_decompose_lnn.py +79 -0
- qiskit/synthesis/stabilizer/__init__.py +16 -0
- qiskit/synthesis/stabilizer/stabilizer_circuit.py +149 -0
- qiskit/synthesis/stabilizer/stabilizer_decompose.py +194 -0
- qiskit/synthesis/two_qubit/__init__.py +20 -0
- qiskit/synthesis/two_qubit/local_invariance.py +63 -0
- qiskit/synthesis/two_qubit/two_qubit_decompose.py +583 -0
- qiskit/synthesis/two_qubit/xx_decompose/__init__.py +19 -0
- qiskit/synthesis/two_qubit/xx_decompose/circuits.py +300 -0
- qiskit/synthesis/two_qubit/xx_decompose/decomposer.py +324 -0
- qiskit/synthesis/two_qubit/xx_decompose/embodiments.py +163 -0
- qiskit/synthesis/two_qubit/xx_decompose/paths.py +412 -0
- qiskit/synthesis/two_qubit/xx_decompose/polytopes.py +262 -0
- qiskit/synthesis/two_qubit/xx_decompose/utilities.py +40 -0
- qiskit/synthesis/two_qubit/xx_decompose/weyl.py +133 -0
- qiskit/synthesis/unitary/__init__.py +13 -0
- qiskit/synthesis/unitary/aqc/__init__.py +177 -0
- qiskit/synthesis/unitary/aqc/approximate.py +116 -0
- qiskit/synthesis/unitary/aqc/aqc.py +175 -0
- qiskit/synthesis/unitary/aqc/cnot_structures.py +300 -0
- qiskit/synthesis/unitary/aqc/cnot_unit_circuit.py +103 -0
- qiskit/synthesis/unitary/aqc/cnot_unit_objective.py +299 -0
- qiskit/synthesis/unitary/aqc/elementary_operations.py +108 -0
- qiskit/synthesis/unitary/aqc/fast_gradient/__init__.py +164 -0
- qiskit/synthesis/unitary/aqc/fast_gradient/fast_grad_utils.py +237 -0
- qiskit/synthesis/unitary/aqc/fast_gradient/fast_gradient.py +226 -0
- qiskit/synthesis/unitary/aqc/fast_gradient/layer.py +370 -0
- qiskit/synthesis/unitary/aqc/fast_gradient/pmatrix.py +312 -0
- qiskit/synthesis/unitary/qsd.py +288 -0
- qiskit/transpiler/__init__.py +1345 -0
- qiskit/transpiler/basepasses.py +190 -0
- qiskit/transpiler/coupling.py +500 -0
- qiskit/transpiler/exceptions.py +59 -0
- qiskit/transpiler/instruction_durations.py +281 -0
- qiskit/transpiler/layout.py +740 -0
- qiskit/transpiler/passes/__init__.py +276 -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 +19 -0
- qiskit/transpiler/passes/basis/basis_translator.py +138 -0
- qiskit/transpiler/passes/basis/decompose.py +137 -0
- qiskit/transpiler/passes/basis/translate_parameterized.py +175 -0
- qiskit/transpiler/passes/basis/unroll_3q_or_more.py +84 -0
- qiskit/transpiler/passes/basis/unroll_custom_definitions.py +110 -0
- qiskit/transpiler/passes/layout/__init__.py +26 -0
- qiskit/transpiler/passes/layout/_csp_custom_solver.py +65 -0
- qiskit/transpiler/passes/layout/apply_layout.py +128 -0
- qiskit/transpiler/passes/layout/csp_layout.py +132 -0
- qiskit/transpiler/passes/layout/dense_layout.py +177 -0
- qiskit/transpiler/passes/layout/disjoint_utils.py +219 -0
- qiskit/transpiler/passes/layout/enlarge_with_ancilla.py +49 -0
- qiskit/transpiler/passes/layout/full_ancilla_allocation.py +116 -0
- qiskit/transpiler/passes/layout/layout_2q_distance.py +77 -0
- qiskit/transpiler/passes/layout/sabre_layout.py +506 -0
- qiskit/transpiler/passes/layout/sabre_pre_layout.py +225 -0
- qiskit/transpiler/passes/layout/set_layout.py +69 -0
- qiskit/transpiler/passes/layout/trivial_layout.py +66 -0
- qiskit/transpiler/passes/layout/vf2_layout.py +256 -0
- qiskit/transpiler/passes/layout/vf2_post_layout.py +376 -0
- qiskit/transpiler/passes/layout/vf2_utils.py +235 -0
- qiskit/transpiler/passes/optimization/__init__.py +42 -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 +117 -0
- qiskit/transpiler/passes/optimization/collect_cliffords.py +109 -0
- qiskit/transpiler/passes/optimization/collect_linear_functions.py +85 -0
- qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +242 -0
- qiskit/transpiler/passes/optimization/commutation_analysis.py +44 -0
- qiskit/transpiler/passes/optimization/commutative_cancellation.py +82 -0
- qiskit/transpiler/passes/optimization/commutative_inverse_cancellation.py +140 -0
- qiskit/transpiler/passes/optimization/consolidate_blocks.py +176 -0
- qiskit/transpiler/passes/optimization/contract_idle_wires_in_control_flow.py +104 -0
- qiskit/transpiler/passes/optimization/elide_permutations.py +91 -0
- qiskit/transpiler/passes/optimization/hoare_opt.py +420 -0
- qiskit/transpiler/passes/optimization/inverse_cancellation.py +95 -0
- qiskit/transpiler/passes/optimization/light_cone.py +135 -0
- qiskit/transpiler/passes/optimization/optimize_1q_commutation.py +267 -0
- qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +250 -0
- qiskit/transpiler/passes/optimization/optimize_1q_gates.py +384 -0
- qiskit/transpiler/passes/optimization/optimize_annotated.py +449 -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 +41 -0
- qiskit/transpiler/passes/optimization/remove_final_reset.py +37 -0
- qiskit/transpiler/passes/optimization/remove_identity_equiv.py +70 -0
- qiskit/transpiler/passes/optimization/remove_reset_in_zero_state.py +37 -0
- qiskit/transpiler/passes/optimization/reset_after_measure_simplification.py +50 -0
- qiskit/transpiler/passes/optimization/split_2q_unitaries.py +63 -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 +452 -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 +639 -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 +166 -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 +397 -0
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/pauli_2q_evolution_commutation.py +145 -0
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/swap_strategy.py +306 -0
- qiskit/transpiler/passes/routing/layout_transformation.py +119 -0
- qiskit/transpiler/passes/routing/lookahead_swap.py +390 -0
- qiskit/transpiler/passes/routing/sabre_swap.py +463 -0
- qiskit/transpiler/passes/routing/star_prerouting.py +408 -0
- qiskit/transpiler/passes/routing/utils.py +35 -0
- qiskit/transpiler/passes/scheduling/__init__.py +21 -0
- qiskit/transpiler/passes/scheduling/alignments/__init__.py +79 -0
- qiskit/transpiler/passes/scheduling/alignments/check_durations.py +70 -0
- qiskit/transpiler/passes/scheduling/alignments/reschedule.py +251 -0
- qiskit/transpiler/passes/scheduling/padding/__init__.py +16 -0
- qiskit/transpiler/passes/scheduling/padding/base_padding.py +284 -0
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +415 -0
- qiskit/transpiler/passes/scheduling/padding/pad_delay.py +90 -0
- qiskit/transpiler/passes/scheduling/scheduling/__init__.py +17 -0
- qiskit/transpiler/passes/scheduling/scheduling/alap.py +93 -0
- qiskit/transpiler/passes/scheduling/scheduling/asap.py +100 -0
- qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +88 -0
- qiskit/transpiler/passes/scheduling/scheduling/set_io_latency.py +64 -0
- qiskit/transpiler/passes/scheduling/time_unit_conversion.py +237 -0
- qiskit/transpiler/passes/synthesis/__init__.py +20 -0
- qiskit/transpiler/passes/synthesis/aqc_plugin.py +153 -0
- qiskit/transpiler/passes/synthesis/default_unitary_synth_plugin.py +653 -0
- qiskit/transpiler/passes/synthesis/high_level_synthesis.py +429 -0
- qiskit/transpiler/passes/synthesis/hls_plugins.py +1963 -0
- qiskit/transpiler/passes/synthesis/linear_functions_synthesis.py +41 -0
- qiskit/transpiler/passes/synthesis/plugin.py +738 -0
- qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +313 -0
- qiskit/transpiler/passes/synthesis/unitary_synthesis.py +425 -0
- qiskit/transpiler/passes/utils/__init__.py +32 -0
- qiskit/transpiler/passes/utils/barrier_before_final_measurements.py +41 -0
- qiskit/transpiler/passes/utils/check_gate_direction.py +60 -0
- qiskit/transpiler/passes/utils/check_map.py +78 -0
- qiskit/transpiler/passes/utils/contains_instruction.py +45 -0
- qiskit/transpiler/passes/utils/control_flow.py +61 -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 +66 -0
- qiskit/transpiler/passes/utils/fixed_point.py +48 -0
- qiskit/transpiler/passes/utils/gate_direction.py +93 -0
- qiskit/transpiler/passes/utils/gates_basis.py +51 -0
- qiskit/transpiler/passes/utils/merge_adjacent_barriers.py +163 -0
- qiskit/transpiler/passes/utils/minimum_point.py +118 -0
- qiskit/transpiler/passes/utils/remove_barriers.py +50 -0
- qiskit/transpiler/passes/utils/remove_final_measurements.py +121 -0
- qiskit/transpiler/passes/utils/unroll_forloops.py +81 -0
- qiskit/transpiler/passmanager.py +503 -0
- qiskit/transpiler/passmanager_config.py +151 -0
- qiskit/transpiler/preset_passmanagers/__init__.py +93 -0
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +993 -0
- qiskit/transpiler/preset_passmanagers/common.py +672 -0
- qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +437 -0
- qiskit/transpiler/preset_passmanagers/level0.py +104 -0
- qiskit/transpiler/preset_passmanagers/level1.py +108 -0
- qiskit/transpiler/preset_passmanagers/level2.py +109 -0
- qiskit/transpiler/preset_passmanagers/level3.py +110 -0
- qiskit/transpiler/preset_passmanagers/plugin.py +346 -0
- qiskit/transpiler/target.py +905 -0
- qiskit/transpiler/timing_constraints.py +59 -0
- qiskit/user_config.py +266 -0
- qiskit/utils/__init__.py +90 -0
- qiskit/utils/classtools.py +146 -0
- qiskit/utils/deprecation.py +382 -0
- qiskit/utils/lazy_tester.py +363 -0
- qiskit/utils/optionals.py +354 -0
- qiskit/utils/parallel.py +318 -0
- qiskit/utils/units.py +146 -0
- qiskit/version.py +84 -0
- qiskit/visualization/__init__.py +290 -0
- qiskit/visualization/array.py +207 -0
- qiskit/visualization/bloch.py +778 -0
- qiskit/visualization/circuit/__init__.py +15 -0
- qiskit/visualization/circuit/_utils.py +675 -0
- qiskit/visualization/circuit/circuit_visualization.py +735 -0
- qiskit/visualization/circuit/latex.py +661 -0
- qiskit/visualization/circuit/matplotlib.py +2019 -0
- qiskit/visualization/circuit/qcstyle.py +278 -0
- qiskit/visualization/circuit/styles/__init__.py +13 -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 +1849 -0
- qiskit/visualization/circuit_visualization.py +19 -0
- qiskit/visualization/counts_visualization.py +487 -0
- qiskit/visualization/dag_visualization.py +318 -0
- qiskit/visualization/exceptions.py +21 -0
- qiskit/visualization/gate_map.py +1424 -0
- qiskit/visualization/library.py +40 -0
- qiskit/visualization/pass_manager_visualization.py +312 -0
- qiskit/visualization/state_visualization.py +1546 -0
- qiskit/visualization/timeline/__init__.py +21 -0
- qiskit/visualization/timeline/core.py +495 -0
- qiskit/visualization/timeline/drawings.py +260 -0
- qiskit/visualization/timeline/generators.py +506 -0
- qiskit/visualization/timeline/interface.py +444 -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 +195 -0
- qiskit/visualization/timeline/stylesheet.py +301 -0
- qiskit/visualization/timeline/types.py +148 -0
- qiskit/visualization/transition_visualization.py +369 -0
- qiskit/visualization/utils.py +49 -0
- qiskit-2.0.3.dist-info/METADATA +220 -0
- qiskit-2.0.3.dist-info/RECORD +690 -0
- qiskit-2.0.3.dist-info/WHEEL +6 -0
- qiskit-2.0.3.dist-info/entry_points.txt +82 -0
- qiskit-2.0.3.dist-info/licenses/LICENSE.txt +203 -0
- qiskit-2.0.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,103 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2017, 2021.
|
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
|
+
"""Compute the product of two qubit registers using classical multiplication approach."""
|
14
|
+
|
15
|
+
from __future__ import annotations
|
16
|
+
|
17
|
+
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
18
|
+
from qiskit.circuit import QuantumRegister
|
19
|
+
|
20
|
+
|
21
|
+
def multiplier_cumulative_h18(
|
22
|
+
num_state_qubits: int, num_result_qubits: int | None = None
|
23
|
+
) -> QuantumCircuit:
|
24
|
+
r"""A multiplication circuit to store product of two input registers out-of-place.
|
25
|
+
|
26
|
+
The circuit uses the approach from Ref. [1]. As an example, a multiplier circuit that
|
27
|
+
performs a non-modular multiplication on two 3-qubit sized registers is:
|
28
|
+
|
29
|
+
.. plot::
|
30
|
+
:alt: Circuit diagram output by the previous code.
|
31
|
+
:include-source:
|
32
|
+
|
33
|
+
from qiskit.synthesis.arithmetic import multiplier_cumulative_h18
|
34
|
+
|
35
|
+
num_state_qubits = 3
|
36
|
+
circuit = multiplier_cumulative_h18(num_state_qubits)
|
37
|
+
circuit.draw("mpl")
|
38
|
+
|
39
|
+
Multiplication in this circuit is implemented in a classical approach by performing
|
40
|
+
a series of shifted additions using one of the input registers while the qubits
|
41
|
+
from the other input register act as control qubits for the adders.
|
42
|
+
|
43
|
+
Args:
|
44
|
+
num_state_qubits: The number of qubits in either input register for
|
45
|
+
state :math:`|a\rangle` or :math:`|b\rangle`. The two input
|
46
|
+
registers must have the same number of qubits.
|
47
|
+
num_result_qubits: The number of result qubits to limit the output to.
|
48
|
+
If number of result qubits is :math:`n`, multiplication modulo :math:`2^n` is performed
|
49
|
+
to limit the output to the specified number of qubits. Default
|
50
|
+
value is ``2 * num_state_qubits`` to represent any possible
|
51
|
+
result from the multiplication of the two inputs.
|
52
|
+
|
53
|
+
Raises:
|
54
|
+
ValueError: If ``num_result_qubits`` is given and not valid, meaning not
|
55
|
+
in ``[num_state_qubits, 2 * num_state_qubits]``.
|
56
|
+
|
57
|
+
**References:**
|
58
|
+
|
59
|
+
[1] Häner et al., Optimizing Quantum Circuits for Arithmetic, 2018.
|
60
|
+
`arXiv:1805.12445 <https://arxiv.org/pdf/1805.12445.pdf>`_
|
61
|
+
|
62
|
+
"""
|
63
|
+
if num_result_qubits is None:
|
64
|
+
num_result_qubits = 2 * num_state_qubits
|
65
|
+
elif num_result_qubits < num_state_qubits or num_result_qubits > 2 * num_state_qubits:
|
66
|
+
raise ValueError(
|
67
|
+
f"num_result_qubits ({num_result_qubits}) must be in between num_state_qubits "
|
68
|
+
f"({num_state_qubits}) and 2 * num_state_qubits ({2 * num_state_qubits})"
|
69
|
+
)
|
70
|
+
|
71
|
+
# define the registers
|
72
|
+
qr_a = QuantumRegister(num_state_qubits, name="a")
|
73
|
+
qr_b = QuantumRegister(num_state_qubits, name="b")
|
74
|
+
qr_out = QuantumRegister(num_result_qubits, name="out")
|
75
|
+
|
76
|
+
circuit = QuantumCircuit(qr_a, qr_b, qr_out)
|
77
|
+
|
78
|
+
# prepare adder as controlled gate
|
79
|
+
# pylint: disable=cyclic-import
|
80
|
+
from qiskit.circuit.library.arithmetic import HalfAdderGate, ModularAdderGate
|
81
|
+
|
82
|
+
adder = HalfAdderGate(num_state_qubits)
|
83
|
+
controlled_adder = adder.control(annotated=True)
|
84
|
+
|
85
|
+
# build multiplication circuit
|
86
|
+
for i in range(num_state_qubits):
|
87
|
+
excess_qubits = max(0, num_state_qubits + i + 1 - num_result_qubits)
|
88
|
+
if excess_qubits == 0:
|
89
|
+
num_adder_qubits = num_state_qubits
|
90
|
+
this_controlled = controlled_adder
|
91
|
+
else:
|
92
|
+
num_adder_qubits = num_state_qubits - excess_qubits + 1
|
93
|
+
modular = ModularAdderGate(num_adder_qubits)
|
94
|
+
this_controlled = modular.control(annotated=True)
|
95
|
+
|
96
|
+
qr_list = (
|
97
|
+
[qr_a[i]]
|
98
|
+
+ qr_b[:num_adder_qubits]
|
99
|
+
+ qr_out[i : num_state_qubits + i + 1 - excess_qubits]
|
100
|
+
)
|
101
|
+
circuit.append(this_controlled, qr_list)
|
102
|
+
|
103
|
+
return circuit
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2017, 2021.
|
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
|
+
"""Compute the product of two qubit registers using QFT."""
|
14
|
+
|
15
|
+
from __future__ import annotations
|
16
|
+
|
17
|
+
import numpy as np
|
18
|
+
|
19
|
+
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
20
|
+
from qiskit.circuit import QuantumRegister
|
21
|
+
from qiskit.circuit.library.standard_gates import PhaseGate
|
22
|
+
from qiskit.circuit.library.basis_change import QFTGate
|
23
|
+
|
24
|
+
|
25
|
+
def multiplier_qft_r17(
|
26
|
+
num_state_qubits: int, num_result_qubits: int | None = None
|
27
|
+
) -> QuantumCircuit:
|
28
|
+
r"""A QFT multiplication circuit to store product of two input registers out-of-place.
|
29
|
+
|
30
|
+
Multiplication in this circuit is implemented using the procedure of Fig. 3 in [1], where
|
31
|
+
weighted sum rotations are implemented as given in Fig. 5 in [1]. QFT is used on the output
|
32
|
+
register and is followed by rotations controlled by input registers. The rotations
|
33
|
+
transform the state into the product of two input registers in QFT base, which is
|
34
|
+
reverted from QFT base using inverse QFT.
|
35
|
+
For example, on 3 state qubits, a full multiplier is given by:
|
36
|
+
|
37
|
+
.. plot::
|
38
|
+
:alt: Circuit diagram output by the previous code.
|
39
|
+
:include-source:
|
40
|
+
|
41
|
+
from qiskit.synthesis.arithmetic import multiplier_qft_r17
|
42
|
+
|
43
|
+
num_state_qubits = 3
|
44
|
+
circuit = multiplier_qft_r17(num_state_qubits)
|
45
|
+
circuit.draw("mpl")
|
46
|
+
|
47
|
+
Args:
|
48
|
+
num_state_qubits: The number of qubits in either input register for
|
49
|
+
state :math:`|a\rangle` or :math:`|b\rangle`. The two input
|
50
|
+
registers must have the same number of qubits.
|
51
|
+
num_result_qubits: The number of result qubits to limit the output to.
|
52
|
+
If number of result qubits is :math:`n`, multiplication modulo :math:`2^n` is performed
|
53
|
+
to limit the output to the specified number of qubits. Default
|
54
|
+
value is ``2 * num_state_qubits`` to represent any possible
|
55
|
+
result from the multiplication of the two inputs.
|
56
|
+
|
57
|
+
Raises:
|
58
|
+
ValueError: If ``num_result_qubits`` is given and not valid, meaning not
|
59
|
+
in ``[num_state_qubits, 2 * num_state_qubits]``.
|
60
|
+
|
61
|
+
**References:**
|
62
|
+
|
63
|
+
[1] Ruiz-Perez et al., Quantum arithmetic with the Quantum Fourier Transform, 2017.
|
64
|
+
`arXiv:1411.5949 <https://arxiv.org/pdf/1411.5949.pdf>`_
|
65
|
+
|
66
|
+
"""
|
67
|
+
# define the registers
|
68
|
+
if num_result_qubits is None:
|
69
|
+
num_result_qubits = 2 * num_state_qubits
|
70
|
+
elif num_result_qubits < num_state_qubits or num_result_qubits > 2 * num_state_qubits:
|
71
|
+
raise ValueError(
|
72
|
+
f"num_result_qubits ({num_result_qubits}) must be in between num_state_qubits "
|
73
|
+
f"({num_state_qubits}) and 2 * num_state_qubits ({2 * num_state_qubits})"
|
74
|
+
)
|
75
|
+
|
76
|
+
qr_a = QuantumRegister(num_state_qubits, name="a")
|
77
|
+
qr_b = QuantumRegister(num_state_qubits, name="b")
|
78
|
+
qr_out = QuantumRegister(num_result_qubits, name="out")
|
79
|
+
|
80
|
+
# build multiplication circuit
|
81
|
+
circuit = QuantumCircuit(qr_a, qr_b, qr_out)
|
82
|
+
qft = QFTGate(num_result_qubits)
|
83
|
+
|
84
|
+
circuit.append(qft, qr_out[:])
|
85
|
+
|
86
|
+
for j in range(1, num_state_qubits + 1):
|
87
|
+
for i in range(1, num_state_qubits + 1):
|
88
|
+
for k in range(1, num_result_qubits + 1):
|
89
|
+
lam = (2 * np.pi) / (2 ** (i + j + k - 2 * num_state_qubits))
|
90
|
+
|
91
|
+
# note: if we can synthesize the QFT without swaps, we can implement this circuit
|
92
|
+
# more efficiently and just apply phase gate on qr_out[(k - 1)] instead
|
93
|
+
circuit.append(
|
94
|
+
PhaseGate(lam).control(2),
|
95
|
+
[qr_a[num_state_qubits - j], qr_b[num_state_qubits - i], qr_out[~(k - 1)]],
|
96
|
+
)
|
97
|
+
|
98
|
+
circuit.append(qft.inverse(), qr_out[:])
|
99
|
+
|
100
|
+
return circuit
|
@@ -0,0 +1,155 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2017, 2025.
|
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
|
+
"""Implement a integer-weighted sum over a set of qubits."""
|
14
|
+
|
15
|
+
from __future__ import annotations
|
16
|
+
|
17
|
+
import typing
|
18
|
+
import numpy as np
|
19
|
+
from qiskit.circuit.quantumcircuit import QuantumCircuit, QuantumRegister, AncillaRegister
|
20
|
+
from qiskit.synthesis.multi_controlled import synth_mcx_n_clean_m15
|
21
|
+
|
22
|
+
if typing.TYPE_CHECKING:
|
23
|
+
from qiskit.circuit.library import WeightedSumGate
|
24
|
+
|
25
|
+
|
26
|
+
def synth_weighted_sum_carry(weighted_sum: WeightedSumGate) -> QuantumCircuit:
|
27
|
+
"""Synthesize a weighted sum gate, by the number of state qubits and the qubit weights.
|
28
|
+
|
29
|
+
This method is described in Appendix A of [1].
|
30
|
+
|
31
|
+
Reference:
|
32
|
+
|
33
|
+
[1] Stamatopoulos et al. Option Pricing using Quantum Computers (2020)
|
34
|
+
`Quantum 4, 291 <https://doi.org/10.22331/q-2020-07-06-291>`__
|
35
|
+
"""
|
36
|
+
|
37
|
+
num_sum_qubits = weighted_sum.num_sum_qubits
|
38
|
+
num_state_qubits = weighted_sum.num_qubits - num_sum_qubits
|
39
|
+
|
40
|
+
num_carry_qubits = num_sum_qubits - 1
|
41
|
+
num_control_qubits = int(num_sum_qubits > 2)
|
42
|
+
|
43
|
+
qr_state = QuantumRegister(num_state_qubits, "state")
|
44
|
+
qr_sum = QuantumRegister(num_sum_qubits, "sum")
|
45
|
+
qr_carry = AncillaRegister(num_carry_qubits, "carry")
|
46
|
+
qr_control = AncillaRegister(num_control_qubits, "control")
|
47
|
+
circuit = QuantumCircuit(qr_state, qr_sum, qr_carry, qr_control)
|
48
|
+
|
49
|
+
# we use a MCX v-chain decomposition of C3X here, synthesize it once and re-use
|
50
|
+
c3x = synth_mcx_n_clean_m15(3)
|
51
|
+
|
52
|
+
# loop over state qubits and corresponding weights
|
53
|
+
weights = weighted_sum.params
|
54
|
+
for i, weight in enumerate(weights):
|
55
|
+
# only act if non-trivial weight
|
56
|
+
if np.isclose(weight, 0):
|
57
|
+
continue
|
58
|
+
|
59
|
+
# get state control qubit
|
60
|
+
q_state = qr_state[i]
|
61
|
+
|
62
|
+
# get bit representation of current weight
|
63
|
+
weight_binary = f"{int(weight):b}".rjust(num_sum_qubits, "0")[::-1]
|
64
|
+
|
65
|
+
# loop over bits of current weight and add them to sum and carry registers
|
66
|
+
for j, bit in enumerate(weight_binary):
|
67
|
+
if bit == "1":
|
68
|
+
if num_sum_qubits == 1:
|
69
|
+
circuit.cx(q_state, qr_sum[j])
|
70
|
+
elif j == 0:
|
71
|
+
# compute (q_sum[0] + 1) into (q_sum[0], q_carry[0])
|
72
|
+
# - controlled by q_state[i]
|
73
|
+
circuit.ccx(q_state, qr_sum[j], qr_carry[j])
|
74
|
+
circuit.cx(q_state, qr_sum[j])
|
75
|
+
elif j == num_sum_qubits - 1:
|
76
|
+
# compute (q_sum[j] + q_carry[j-1] + 1) into (q_sum[j])
|
77
|
+
# - controlled by q_state[i] / last qubit,
|
78
|
+
# no carry needed by construction
|
79
|
+
circuit.cx(q_state, qr_sum[j])
|
80
|
+
circuit.ccx(q_state, qr_carry[j - 1], qr_sum[j])
|
81
|
+
else:
|
82
|
+
# compute (q_sum[j] + q_carry[j-1] + 1) into (q_sum[j], q_carry[j])
|
83
|
+
# - controlled by q_state[i]
|
84
|
+
circuit.x(qr_sum[j])
|
85
|
+
circuit.x(qr_carry[j - 1])
|
86
|
+
circuit.compose(
|
87
|
+
c3x,
|
88
|
+
[q_state, qr_sum[j], qr_carry[j - 1], qr_carry[j]] + qr_control[:],
|
89
|
+
inplace=True,
|
90
|
+
)
|
91
|
+
circuit.cx(q_state, qr_carry[j])
|
92
|
+
circuit.x(qr_sum[j])
|
93
|
+
circuit.x(qr_carry[j - 1])
|
94
|
+
circuit.cx(q_state, qr_sum[j])
|
95
|
+
circuit.ccx(q_state, qr_carry[j - 1], qr_sum[j])
|
96
|
+
else:
|
97
|
+
if num_sum_qubits == 1:
|
98
|
+
pass # nothing to do, since nothing to add
|
99
|
+
elif j == 0:
|
100
|
+
pass # nothing to do, since nothing to add
|
101
|
+
elif j == num_sum_qubits - 1:
|
102
|
+
# compute (q_sum[j] + q_carry[j-1]) into (q_sum[j])
|
103
|
+
# - controlled by q_state[i] / last qubit,
|
104
|
+
# no carry needed by construction
|
105
|
+
circuit.ccx(q_state, qr_carry[j - 1], qr_sum[j])
|
106
|
+
else:
|
107
|
+
# compute (q_sum[j] + q_carry[j-1]) into (q_sum[j], q_carry[j])
|
108
|
+
# - controlled by q_state[i]
|
109
|
+
circuit.compose(
|
110
|
+
c3x,
|
111
|
+
[q_state, qr_sum[j], qr_carry[j - 1], qr_carry[j]] + qr_control[:],
|
112
|
+
inplace=True,
|
113
|
+
)
|
114
|
+
circuit.ccx(q_state, qr_carry[j - 1], qr_sum[j])
|
115
|
+
|
116
|
+
# uncompute carry qubits
|
117
|
+
for j in reversed(range(len(weight_binary))):
|
118
|
+
bit = weight_binary[j]
|
119
|
+
if bit == "1":
|
120
|
+
if num_sum_qubits == 1:
|
121
|
+
pass
|
122
|
+
elif j == 0:
|
123
|
+
circuit.x(qr_sum[j])
|
124
|
+
circuit.ccx(q_state, qr_sum[j], qr_carry[j])
|
125
|
+
circuit.x(qr_sum[j])
|
126
|
+
elif j == num_sum_qubits - 1:
|
127
|
+
pass
|
128
|
+
else:
|
129
|
+
circuit.x(qr_carry[j - 1])
|
130
|
+
circuit.compose(
|
131
|
+
c3x,
|
132
|
+
[q_state, qr_sum[j], qr_carry[j - 1], qr_carry[j]] + qr_control[:],
|
133
|
+
inplace=True,
|
134
|
+
)
|
135
|
+
circuit.cx(q_state, qr_carry[j])
|
136
|
+
circuit.x(qr_carry[j - 1])
|
137
|
+
else:
|
138
|
+
if num_sum_qubits == 1:
|
139
|
+
pass
|
140
|
+
elif j == 0:
|
141
|
+
pass
|
142
|
+
elif j == num_sum_qubits - 1:
|
143
|
+
pass
|
144
|
+
else:
|
145
|
+
# compute (q_sum[j] + q_carry[j-1]) into (q_sum[j], q_carry[j])
|
146
|
+
# - controlled by q_state[i]
|
147
|
+
circuit.x(qr_sum[j])
|
148
|
+
circuit.compose(
|
149
|
+
c3x,
|
150
|
+
[q_state, qr_sum[j], qr_carry[j - 1], qr_carry[j]] + qr_control[:],
|
151
|
+
inplace=True,
|
152
|
+
)
|
153
|
+
circuit.x(qr_sum[j])
|
154
|
+
|
155
|
+
return circuit
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2025.
|
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
|
+
"""Module containing boolean expression synthesis."""
|
@@ -0,0 +1,231 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2021.
|
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
|
+
"""A class for parsing and synthesizing boolean expressions"""
|
14
|
+
|
15
|
+
import ast
|
16
|
+
import itertools
|
17
|
+
import re
|
18
|
+
from os.path import isfile
|
19
|
+
from typing import Union, Callable
|
20
|
+
import numpy as np
|
21
|
+
|
22
|
+
from .boolean_expression_visitor import (
|
23
|
+
BooleanExpressionEvalVisitor,
|
24
|
+
BooleanExpressionArgsCollectorVisitor,
|
25
|
+
)
|
26
|
+
|
27
|
+
|
28
|
+
class TruthTable:
|
29
|
+
"""A simple implementation of a truth table for a boolean function
|
30
|
+
|
31
|
+
The truth table is built from a callable which takes an assignment, which
|
32
|
+
is a tuple of boolean values of a fixed given length (the number of bits
|
33
|
+
of the truth table) and returns a boolean value.
|
34
|
+
|
35
|
+
For a number of bits at most `EXPLICIT_REP_THRESHOLD` the values of the table
|
36
|
+
are explicitly computed and stored. Otherwise, the values are computed on the fly
|
37
|
+
and stored in a dictionary."""
|
38
|
+
|
39
|
+
EXPLICIT_REP_THRESHOLD = (
|
40
|
+
12 # above this number of bits, do not explicitly save the values in a list
|
41
|
+
)
|
42
|
+
|
43
|
+
def __init__(self, func: Callable, num_bits: int):
|
44
|
+
self.func = func
|
45
|
+
self.num_bits = num_bits
|
46
|
+
self.explicit_storage = self.num_bits <= self.EXPLICIT_REP_THRESHOLD
|
47
|
+
if self.explicit_storage:
|
48
|
+
self.values = np.array(
|
49
|
+
[self.func(assignment) for assignment in self.all_assignments()],
|
50
|
+
dtype=bool,
|
51
|
+
)
|
52
|
+
else:
|
53
|
+
self.implicit_values = {}
|
54
|
+
|
55
|
+
def all_assignments(self) -> list[tuple[bool]]:
|
56
|
+
"""Return an ordered list of all assignments, ordered from right to left
|
57
|
+
i.e. 000, 100, 010, 110, 001, 101, 011, 111"""
|
58
|
+
return [
|
59
|
+
tuple(reversed(assignment))
|
60
|
+
for assignment in itertools.product([False, True], repeat=self.num_bits)
|
61
|
+
]
|
62
|
+
|
63
|
+
def __getitem__(self, key: Union[str, tuple[bool]]) -> bool:
|
64
|
+
if isinstance(key, str):
|
65
|
+
key = (bit != "0" for bit in key)
|
66
|
+
if self.explicit_storage:
|
67
|
+
key = sum(2**n for n, bit in enumerate(key) if bit)
|
68
|
+
return self.values[key]
|
69
|
+
else:
|
70
|
+
return self.implicit_values.setdefault(key, self.func(key))
|
71
|
+
|
72
|
+
def __str__(self) -> str:
|
73
|
+
if self.explicit_storage:
|
74
|
+
return "".join(
|
75
|
+
"1" if self[assignemnt] else "0" for assignemnt in self.all_assignments()
|
76
|
+
)
|
77
|
+
else:
|
78
|
+
return f"Truth table on {self.num_bits} bits (implicit representation)"
|
79
|
+
|
80
|
+
|
81
|
+
class BooleanExpression:
|
82
|
+
"""A Boolean Expression"""
|
83
|
+
|
84
|
+
def __init__(self, expression: str, var_order: list = None) -> None:
|
85
|
+
"""
|
86
|
+
Args:
|
87
|
+
expression (str): The logical expression string.
|
88
|
+
name (str): Optional. Instruction gate name. Otherwise part of the expression is
|
89
|
+
going to be used.
|
90
|
+
var_order(list): A list with the order in which variables will be created.
|
91
|
+
(default: by appearance)
|
92
|
+
"""
|
93
|
+
self.expression = expression
|
94
|
+
self.expression_ast = ast.parse(expression)
|
95
|
+
args_collector = BooleanExpressionArgsCollectorVisitor()
|
96
|
+
args_collector.visit(self.expression_ast)
|
97
|
+
self.args = args_collector.get_sorted_args()
|
98
|
+
self.num_bits = len(self.args)
|
99
|
+
if var_order is not None:
|
100
|
+
missing_args = set(self.args) - set(var_order)
|
101
|
+
if len(missing_args) > 0:
|
102
|
+
raise ValueError(f"var_order missing the variable(s) {', '.join(missing_args)}")
|
103
|
+
self.args.sort(key=var_order.index)
|
104
|
+
self.truth_table_ = None
|
105
|
+
|
106
|
+
def simulate(self, bitstring: Union[str, tuple]) -> bool:
|
107
|
+
"""Evaluate the expression on a bitstring.
|
108
|
+
|
109
|
+
This evaluation is done classically.
|
110
|
+
|
111
|
+
Args:
|
112
|
+
bitstring: The bitstring for which to evaluate,
|
113
|
+
either as a string of 0 and 1 or a tuple of booleans.
|
114
|
+
|
115
|
+
Returns:
|
116
|
+
bool: result of the evaluation.
|
117
|
+
"""
|
118
|
+
if self.num_bits != len(bitstring):
|
119
|
+
raise ValueError(
|
120
|
+
f"bitstring length differs from the number of variables "
|
121
|
+
f"({len(bitstring)} != {self.num_bits}"
|
122
|
+
)
|
123
|
+
if isinstance(bitstring, str):
|
124
|
+
bitstring = (bit != "0" for bit in bitstring)
|
125
|
+
eval_visitor = BooleanExpressionEvalVisitor()
|
126
|
+
eval_visitor.arg_values = dict(zip(self.args, bitstring))
|
127
|
+
return eval_visitor.visit(self.expression_ast)
|
128
|
+
|
129
|
+
@property
|
130
|
+
def truth_table(self) -> dict:
|
131
|
+
"""Generates the full truth table for the expression
|
132
|
+
Returns:
|
133
|
+
dict: A dictionary mapping boolean assignments to the boolean result
|
134
|
+
"""
|
135
|
+
if self.truth_table_ is None:
|
136
|
+
self.truth_table_ = TruthTable(self.simulate, self.num_bits)
|
137
|
+
return self.truth_table_
|
138
|
+
|
139
|
+
def synth(self, circuit_type: str = "bit"):
|
140
|
+
r"""Synthesize the logic network into a :class:`~qiskit.circuit.QuantumCircuit`.
|
141
|
+
There are two common types of circuits for a boolean function :math:`f(x)`:
|
142
|
+
|
143
|
+
1. **Bit-flip oracles** which compute:
|
144
|
+
|
145
|
+
.. math::
|
146
|
+
|
147
|
+
|x\rangle|y\rangle |-> |x\rangle|f(x)\oplusy\rangle
|
148
|
+
|
149
|
+
2. **Phase-flip** oracles which compute:
|
150
|
+
|
151
|
+
.. math::
|
152
|
+
|
153
|
+
|x\rangle |-> (-1)^{f(x)}|x\rangle
|
154
|
+
|
155
|
+
By default the bit-flip oracle is generated.
|
156
|
+
|
157
|
+
Args:
|
158
|
+
circuit_type: which type of oracle to create, 'bit' or 'phase' flip oracle.
|
159
|
+
Returns:
|
160
|
+
QuantumCircuit: A circuit implementing the logic network.
|
161
|
+
Raises:
|
162
|
+
ValueError: If ``circuit_type`` is not either 'bit' or 'phase'.
|
163
|
+
"""
|
164
|
+
# pylint: disable=cyclic-import
|
165
|
+
from .boolean_expression_synth import (
|
166
|
+
synth_bit_oracle_from_esop,
|
167
|
+
synth_phase_oracle_from_esop,
|
168
|
+
EsopGenerator,
|
169
|
+
) # import here to avoid cyclic import
|
170
|
+
|
171
|
+
# generating the esop currntly requires generating the full truth table
|
172
|
+
# there are many optimizations that can be done to improve this step
|
173
|
+
esop = EsopGenerator(self.truth_table).esop
|
174
|
+
if circuit_type == "bit":
|
175
|
+
return synth_bit_oracle_from_esop(esop, self.num_bits + 1)
|
176
|
+
if circuit_type == "phase":
|
177
|
+
return synth_phase_oracle_from_esop(esop, self.num_bits)
|
178
|
+
raise ValueError("'circuit_type' must be either 'bit' or 'phase'")
|
179
|
+
|
180
|
+
@staticmethod
|
181
|
+
def from_dimacs(dimacs: str):
|
182
|
+
"""Create a BooleanExpression from a string in the DIMACS format.
|
183
|
+
Args:
|
184
|
+
dimacs : A string in DIMACS format.
|
185
|
+
|
186
|
+
Returns:
|
187
|
+
BooleanExpression: A gate for the input string
|
188
|
+
|
189
|
+
Raises:
|
190
|
+
ValueError: If the string is not formatted according to DIMACS rules
|
191
|
+
"""
|
192
|
+
header_regex = re.compile(r"p\s+cnf\s+(\d+)\s+(\d+)")
|
193
|
+
clause_regex = re.compile(r"(-?\d+)")
|
194
|
+
lines = [
|
195
|
+
line for line in dimacs.split("\n") if not line.startswith("c") and line != ""
|
196
|
+
] # DIMACS comment line start with c
|
197
|
+
header_match = header_regex.match(lines[0])
|
198
|
+
if not header_match:
|
199
|
+
raise ValueError("First line must start with 'p cnf'")
|
200
|
+
num_vars, _ = map(int, header_match.groups())
|
201
|
+
variables = [f"x{i+1}" for i in range(num_vars)]
|
202
|
+
clauses = []
|
203
|
+
for line in lines[1:]:
|
204
|
+
literals = clause_regex.findall(line)
|
205
|
+
if len(literals) == 0 or literals[-1] != "0":
|
206
|
+
continue
|
207
|
+
clauses.append([int(c) for c in literals[:-1]])
|
208
|
+
clause_strings = [
|
209
|
+
" | ".join([f'{"~" if lit < 0 else ""}{variables[abs(lit)-1]}' for lit in clause])
|
210
|
+
for clause in clauses
|
211
|
+
]
|
212
|
+
expr = " & ".join([f"({c})" for c in clause_strings])
|
213
|
+
return BooleanExpression(expr, var_order=variables)
|
214
|
+
|
215
|
+
@staticmethod
|
216
|
+
def from_dimacs_file(filename: str):
|
217
|
+
"""Create a BooleanExpression from a file in the DIMACS format.
|
218
|
+
Args:
|
219
|
+
filename: A file in DIMACS format.
|
220
|
+
|
221
|
+
Returns:
|
222
|
+
BooleanExpression: A gate for the input string
|
223
|
+
|
224
|
+
Raises:
|
225
|
+
FileNotFoundError: If filename is not found.
|
226
|
+
"""
|
227
|
+
if not isfile(filename):
|
228
|
+
raise FileNotFoundError(f"The file {filename} does not exists.")
|
229
|
+
with open(filename, "r") as dimacs_file:
|
230
|
+
dimacs = dimacs_file.read()
|
231
|
+
return BooleanExpression.from_dimacs(dimacs)
|