qiskit 1.0.2__cp38-abi3-win32.whl → 1.1.0__cp38-abi3-win32.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qiskit/VERSION.txt +1 -1
- qiskit/__init__.py +27 -16
- qiskit/_accelerate.pyd +0 -0
- qiskit/_numpy_compat.py +73 -0
- qiskit/assembler/__init__.py +5 -10
- qiskit/assembler/disassemble.py +5 -6
- qiskit/circuit/__init__.py +1061 -232
- qiskit/circuit/_classical_resource_map.py +10 -6
- qiskit/circuit/_utils.py +18 -8
- qiskit/circuit/annotated_operation.py +21 -0
- qiskit/circuit/barrier.py +10 -13
- qiskit/circuit/bit.py +0 -1
- qiskit/circuit/classical/__init__.py +2 -2
- qiskit/circuit/classical/expr/__init__.py +39 -5
- qiskit/circuit/classical/expr/constructors.py +84 -1
- qiskit/circuit/classical/expr/expr.py +83 -13
- qiskit/circuit/classical/expr/visitors.py +83 -0
- qiskit/circuit/classical/types/__init__.py +5 -4
- qiskit/circuit/classicalfunction/__init__.py +1 -0
- qiskit/circuit/commutation_checker.py +86 -51
- qiskit/circuit/controlflow/_builder_utils.py +9 -1
- qiskit/circuit/controlflow/break_loop.py +8 -22
- qiskit/circuit/controlflow/builder.py +116 -1
- qiskit/circuit/controlflow/continue_loop.py +8 -22
- qiskit/circuit/controlflow/control_flow.py +47 -8
- qiskit/circuit/controlflow/for_loop.py +8 -23
- qiskit/circuit/controlflow/if_else.py +13 -27
- qiskit/circuit/controlflow/switch_case.py +14 -21
- qiskit/circuit/controlflow/while_loop.py +9 -23
- qiskit/circuit/controlledgate.py +2 -2
- qiskit/circuit/delay.py +7 -5
- qiskit/circuit/gate.py +20 -7
- qiskit/circuit/instruction.py +31 -30
- qiskit/circuit/instructionset.py +9 -22
- qiskit/circuit/library/__init__.py +3 -13
- qiskit/circuit/library/arithmetic/integer_comparator.py +2 -2
- qiskit/circuit/library/arithmetic/quadratic_form.py +3 -2
- qiskit/circuit/library/blueprintcircuit.py +29 -7
- qiskit/circuit/library/data_preparation/state_preparation.py +6 -5
- qiskit/circuit/library/generalized_gates/diagonal.py +5 -4
- qiskit/circuit/library/generalized_gates/isometry.py +51 -254
- qiskit/circuit/library/generalized_gates/pauli.py +2 -2
- qiskit/circuit/library/generalized_gates/permutation.py +4 -1
- qiskit/circuit/library/generalized_gates/rv.py +15 -11
- qiskit/circuit/library/generalized_gates/uc.py +2 -98
- qiskit/circuit/library/generalized_gates/unitary.py +9 -4
- qiskit/circuit/library/hamiltonian_gate.py +11 -5
- qiskit/circuit/library/n_local/efficient_su2.py +5 -5
- qiskit/circuit/library/n_local/n_local.py +100 -49
- qiskit/circuit/library/n_local/two_local.py +3 -59
- qiskit/circuit/library/overlap.py +3 -3
- qiskit/circuit/library/phase_oracle.py +1 -1
- qiskit/circuit/library/quantum_volume.py +39 -38
- qiskit/circuit/library/standard_gates/equivalence_library.py +50 -0
- qiskit/circuit/library/standard_gates/global_phase.py +4 -2
- qiskit/circuit/library/standard_gates/i.py +1 -2
- qiskit/circuit/library/standard_gates/iswap.py +1 -2
- qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +11 -5
- qiskit/circuit/library/standard_gates/p.py +31 -15
- qiskit/circuit/library/standard_gates/r.py +4 -3
- qiskit/circuit/library/standard_gates/rx.py +7 -4
- qiskit/circuit/library/standard_gates/rxx.py +4 -3
- qiskit/circuit/library/standard_gates/ry.py +7 -4
- qiskit/circuit/library/standard_gates/ryy.py +4 -3
- qiskit/circuit/library/standard_gates/rz.py +7 -4
- qiskit/circuit/library/standard_gates/rzx.py +4 -3
- qiskit/circuit/library/standard_gates/rzz.py +4 -3
- qiskit/circuit/library/standard_gates/s.py +4 -8
- qiskit/circuit/library/standard_gates/t.py +2 -4
- qiskit/circuit/library/standard_gates/u.py +16 -11
- qiskit/circuit/library/standard_gates/u1.py +6 -2
- qiskit/circuit/library/standard_gates/u2.py +4 -2
- qiskit/circuit/library/standard_gates/u3.py +9 -5
- qiskit/circuit/library/standard_gates/x.py +22 -11
- qiskit/circuit/library/standard_gates/xx_minus_yy.py +4 -3
- qiskit/circuit/library/standard_gates/xx_plus_yy.py +7 -5
- qiskit/circuit/library/standard_gates/z.py +1 -2
- qiskit/circuit/measure.py +4 -1
- qiskit/circuit/operation.py +13 -8
- qiskit/circuit/parameter.py +11 -6
- qiskit/circuit/quantumcircuit.py +1910 -260
- qiskit/circuit/quantumcircuitdata.py +2 -2
- qiskit/circuit/reset.py +5 -2
- qiskit/circuit/store.py +95 -0
- qiskit/compiler/assembler.py +22 -22
- qiskit/compiler/transpiler.py +63 -112
- qiskit/converters/__init__.py +17 -2
- qiskit/converters/circuit_to_dag.py +7 -0
- qiskit/converters/circuit_to_dagdependency_v2.py +47 -0
- qiskit/converters/circuit_to_gate.py +2 -0
- qiskit/converters/circuit_to_instruction.py +22 -0
- qiskit/converters/dag_to_circuit.py +4 -0
- qiskit/converters/dag_to_dagdependency_v2.py +44 -0
- qiskit/dagcircuit/collect_blocks.py +15 -10
- qiskit/dagcircuit/dagcircuit.py +434 -124
- qiskit/dagcircuit/dagdependency.py +19 -12
- qiskit/dagcircuit/dagdependency_v2.py +641 -0
- qiskit/dagcircuit/dagdepnode.py +19 -16
- qiskit/dagcircuit/dagnode.py +14 -4
- qiskit/passmanager/passmanager.py +11 -11
- qiskit/primitives/__init__.py +22 -12
- qiskit/primitives/backend_estimator.py +3 -5
- qiskit/primitives/backend_estimator_v2.py +410 -0
- qiskit/primitives/backend_sampler_v2.py +287 -0
- qiskit/primitives/base/base_estimator.py +4 -9
- qiskit/primitives/base/base_sampler.py +2 -2
- qiskit/primitives/containers/__init__.py +6 -4
- qiskit/primitives/containers/bit_array.py +293 -2
- qiskit/primitives/containers/data_bin.py +123 -50
- qiskit/primitives/containers/estimator_pub.py +10 -3
- qiskit/primitives/containers/observables_array.py +2 -2
- qiskit/primitives/containers/pub_result.py +1 -1
- qiskit/primitives/containers/sampler_pub.py +19 -3
- qiskit/primitives/containers/sampler_pub_result.py +74 -0
- qiskit/primitives/containers/shape.py +4 -4
- qiskit/primitives/statevector_estimator.py +4 -4
- qiskit/primitives/statevector_sampler.py +7 -12
- qiskit/providers/__init__.py +65 -34
- qiskit/providers/backend.py +2 -2
- qiskit/providers/backend_compat.py +8 -10
- qiskit/providers/basic_provider/__init__.py +2 -23
- qiskit/providers/basic_provider/basic_provider_tools.py +67 -31
- qiskit/providers/basic_provider/basic_simulator.py +81 -21
- qiskit/providers/fake_provider/__init__.py +1 -1
- qiskit/providers/fake_provider/fake_1q.py +1 -1
- qiskit/providers/fake_provider/fake_backend.py +3 -408
- qiskit/providers/fake_provider/generic_backend_v2.py +26 -14
- qiskit/providers/models/__init__.py +2 -2
- qiskit/providers/provider.py +16 -0
- qiskit/pulse/builder.py +4 -1
- qiskit/pulse/parameter_manager.py +60 -4
- qiskit/pulse/schedule.py +29 -13
- qiskit/pulse/utils.py +61 -20
- qiskit/qasm2/__init__.py +1 -5
- qiskit/qasm2/parse.py +1 -4
- qiskit/qasm3/__init__.py +42 -5
- qiskit/qasm3/ast.py +19 -0
- qiskit/qasm3/exporter.py +178 -106
- qiskit/qasm3/printer.py +27 -5
- qiskit/qobj/converters/pulse_instruction.py +6 -6
- qiskit/qpy/__init__.py +299 -67
- qiskit/qpy/binary_io/circuits.py +216 -47
- qiskit/qpy/binary_io/schedules.py +42 -36
- qiskit/qpy/binary_io/value.py +201 -22
- qiskit/qpy/common.py +1 -1
- qiskit/qpy/exceptions.py +20 -0
- qiskit/qpy/formats.py +29 -0
- qiskit/qpy/type_keys.py +21 -0
- qiskit/quantum_info/analysis/distance.py +3 -3
- qiskit/quantum_info/analysis/make_observable.py +2 -1
- qiskit/quantum_info/analysis/z2_symmetries.py +2 -1
- qiskit/quantum_info/operators/channel/chi.py +9 -8
- qiskit/quantum_info/operators/channel/choi.py +10 -9
- qiskit/quantum_info/operators/channel/kraus.py +2 -1
- qiskit/quantum_info/operators/channel/ptm.py +10 -9
- qiskit/quantum_info/operators/channel/quantum_channel.py +2 -1
- qiskit/quantum_info/operators/channel/stinespring.py +2 -1
- qiskit/quantum_info/operators/channel/superop.py +12 -11
- qiskit/quantum_info/operators/channel/transformations.py +12 -11
- qiskit/quantum_info/operators/dihedral/dihedral.py +5 -4
- qiskit/quantum_info/operators/operator.py +43 -30
- qiskit/quantum_info/operators/scalar_op.py +10 -9
- qiskit/quantum_info/operators/symplectic/base_pauli.py +70 -59
- qiskit/quantum_info/operators/symplectic/clifford.py +36 -9
- qiskit/quantum_info/operators/symplectic/pauli.py +53 -6
- qiskit/quantum_info/operators/symplectic/pauli_list.py +36 -14
- qiskit/quantum_info/operators/symplectic/random.py +3 -2
- qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +61 -36
- qiskit/quantum_info/states/densitymatrix.py +13 -13
- qiskit/quantum_info/states/stabilizerstate.py +3 -3
- qiskit/quantum_info/states/statevector.py +14 -13
- qiskit/quantum_info/states/utils.py +5 -3
- qiskit/result/__init__.py +6 -0
- qiskit/result/mitigation/correlated_readout_mitigator.py +3 -2
- qiskit/result/mitigation/local_readout_mitigator.py +2 -1
- qiskit/result/mitigation/utils.py +3 -2
- qiskit/scheduler/__init__.py +10 -1
- qiskit/scheduler/methods/__init__.py +1 -8
- qiskit/synthesis/__init__.py +3 -6
- qiskit/synthesis/discrete_basis/commutator_decompose.py +2 -2
- qiskit/synthesis/evolution/lie_trotter.py +7 -14
- qiskit/synthesis/evolution/qdrift.py +3 -4
- qiskit/synthesis/linear/cnot_synth.py +1 -3
- qiskit/synthesis/linear/linear_circuits_utils.py +1 -1
- qiskit/synthesis/linear_phase/cz_depth_lnn.py +4 -18
- qiskit/synthesis/permutation/__init__.py +1 -0
- qiskit/synthesis/permutation/permutation_reverse_lnn.py +90 -0
- qiskit/synthesis/qft/qft_decompose_lnn.py +2 -6
- qiskit/synthesis/two_qubit/two_qubit_decompose.py +165 -954
- qiskit/synthesis/two_qubit/xx_decompose/circuits.py +13 -12
- qiskit/synthesis/two_qubit/xx_decompose/decomposer.py +7 -1
- qiskit/synthesis/unitary/aqc/__init__.py +1 -1
- qiskit/synthesis/unitary/aqc/cnot_structures.py +2 -1
- qiskit/synthesis/unitary/aqc/fast_gradient/fast_gradient.py +2 -1
- qiskit/synthesis/unitary/qsd.py +3 -2
- qiskit/transpiler/__init__.py +7 -3
- qiskit/transpiler/layout.py +140 -61
- qiskit/transpiler/passes/__init__.py +10 -2
- qiskit/transpiler/passes/basis/basis_translator.py +9 -4
- qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -1
- qiskit/transpiler/passes/basis/unroll_custom_definitions.py +1 -1
- qiskit/transpiler/passes/calibration/rzx_builder.py +2 -1
- qiskit/transpiler/passes/layout/apply_layout.py +8 -3
- qiskit/transpiler/passes/layout/sabre_layout.py +15 -3
- qiskit/transpiler/passes/layout/set_layout.py +1 -1
- qiskit/transpiler/passes/optimization/__init__.py +2 -0
- qiskit/transpiler/passes/optimization/commutation_analysis.py +2 -2
- qiskit/transpiler/passes/optimization/commutative_cancellation.py +1 -1
- qiskit/transpiler/passes/optimization/consolidate_blocks.py +1 -1
- qiskit/transpiler/passes/optimization/cx_cancellation.py +10 -0
- qiskit/transpiler/passes/optimization/elide_permutations.py +114 -0
- qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +9 -3
- qiskit/transpiler/passes/optimization/optimize_annotated.py +248 -12
- qiskit/transpiler/passes/optimization/remove_final_reset.py +37 -0
- qiskit/transpiler/passes/optimization/template_matching/forward_match.py +1 -3
- qiskit/transpiler/passes/routing/__init__.py +1 -0
- qiskit/transpiler/passes/routing/basic_swap.py +13 -2
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +8 -1
- qiskit/transpiler/passes/routing/lookahead_swap.py +7 -1
- qiskit/transpiler/passes/routing/sabre_swap.py +10 -6
- qiskit/transpiler/passes/routing/star_prerouting.py +417 -0
- qiskit/transpiler/passes/routing/stochastic_swap.py +24 -8
- qiskit/transpiler/passes/scheduling/__init__.py +1 -1
- qiskit/transpiler/passes/scheduling/alap.py +1 -2
- qiskit/transpiler/passes/scheduling/alignments/align_measures.py +1 -2
- qiskit/transpiler/passes/scheduling/alignments/check_durations.py +9 -6
- qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +8 -0
- qiskit/transpiler/passes/scheduling/alignments/reschedule.py +13 -4
- qiskit/transpiler/passes/scheduling/asap.py +1 -2
- qiskit/transpiler/passes/scheduling/base_scheduler.py +21 -2
- qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +26 -4
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +24 -2
- qiskit/transpiler/passes/scheduling/time_unit_conversion.py +28 -4
- qiskit/transpiler/passes/synthesis/aqc_plugin.py +2 -2
- qiskit/transpiler/passes/synthesis/high_level_synthesis.py +120 -13
- qiskit/transpiler/passes/synthesis/unitary_synthesis.py +162 -55
- qiskit/transpiler/passes/utils/gates_basis.py +3 -3
- qiskit/transpiler/passmanager.py +44 -1
- qiskit/transpiler/preset_passmanagers/__init__.py +3 -3
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +34 -16
- qiskit/transpiler/preset_passmanagers/common.py +4 -6
- qiskit/transpiler/preset_passmanagers/plugin.py +9 -1
- qiskit/utils/__init__.py +3 -2
- qiskit/utils/optionals.py +6 -2
- qiskit/utils/parallel.py +24 -15
- qiskit/visualization/array.py +1 -1
- qiskit/visualization/bloch.py +2 -3
- qiskit/visualization/circuit/matplotlib.py +44 -14
- qiskit/visualization/circuit/text.py +38 -18
- qiskit/visualization/counts_visualization.py +3 -6
- qiskit/visualization/dag_visualization.py +6 -7
- qiskit/visualization/gate_map.py +9 -1
- qiskit/visualization/pulse_v2/interface.py +8 -3
- qiskit/visualization/state_visualization.py +3 -2
- qiskit/visualization/timeline/interface.py +18 -8
- {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/METADATA +12 -8
- {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/RECORD +261 -251
- {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/WHEEL +1 -1
- qiskit/_qasm2.pyd +0 -0
- qiskit/_qasm3.pyd +0 -0
- {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/LICENSE.txt +0 -0
- {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/entry_points.txt +0 -0
- {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/top_level.txt +0 -0
qiskit/qpy/type_keys.py
CHANGED
@@ -16,6 +16,7 @@
|
|
16
16
|
QPY Type keys for several namespace.
|
17
17
|
"""
|
18
18
|
|
19
|
+
import uuid
|
19
20
|
from abc import abstractmethod
|
20
21
|
from enum import Enum, IntEnum
|
21
22
|
|
@@ -456,6 +457,7 @@ class Expression(TypeKeyBase):
|
|
456
457
|
CAST = b"c"
|
457
458
|
UNARY = b"u"
|
458
459
|
BINARY = b"b"
|
460
|
+
INDEX = b"i"
|
459
461
|
|
460
462
|
@classmethod
|
461
463
|
def assign(cls, obj):
|
@@ -471,6 +473,22 @@ class Expression(TypeKeyBase):
|
|
471
473
|
raise NotImplementedError
|
472
474
|
|
473
475
|
|
476
|
+
class ExprVarDeclaration(TypeKeyBase):
|
477
|
+
"""Type keys for the ``EXPR_VAR_DECLARATION`` QPY item."""
|
478
|
+
|
479
|
+
INPUT = b"I"
|
480
|
+
CAPTURE = b"C"
|
481
|
+
LOCAL = b"L"
|
482
|
+
|
483
|
+
@classmethod
|
484
|
+
def assign(cls, obj):
|
485
|
+
raise NotImplementedError
|
486
|
+
|
487
|
+
@classmethod
|
488
|
+
def retrieve(cls, type_key):
|
489
|
+
raise NotImplementedError
|
490
|
+
|
491
|
+
|
474
492
|
class ExprType(TypeKeyBase):
|
475
493
|
"""Type keys for the ``EXPR_TYPE`` QPY item."""
|
476
494
|
|
@@ -496,9 +514,12 @@ class ExprVar(TypeKeyBase):
|
|
496
514
|
|
497
515
|
CLBIT = b"C"
|
498
516
|
REGISTER = b"R"
|
517
|
+
UUID = b"U"
|
499
518
|
|
500
519
|
@classmethod
|
501
520
|
def assign(cls, obj):
|
521
|
+
if isinstance(obj, uuid.UUID):
|
522
|
+
return cls.UUID
|
502
523
|
if isinstance(obj, Clbit):
|
503
524
|
return cls.CLBIT
|
504
525
|
if isinstance(obj, ClassicalRegister):
|
@@ -12,7 +12,7 @@
|
|
12
12
|
|
13
13
|
"""A collection of discrete probability metrics."""
|
14
14
|
from __future__ import annotations
|
15
|
-
import
|
15
|
+
import math
|
16
16
|
|
17
17
|
|
18
18
|
def hellinger_distance(dist_p: dict, dist_q: dict) -> float:
|
@@ -43,13 +43,13 @@ def hellinger_distance(dist_p: dict, dist_q: dict) -> float:
|
|
43
43
|
total = 0
|
44
44
|
for key, val in p_normed.items():
|
45
45
|
if key in q_normed:
|
46
|
-
total += (
|
46
|
+
total += (math.sqrt(val) - math.sqrt(q_normed[key])) ** 2
|
47
47
|
del q_normed[key]
|
48
48
|
else:
|
49
49
|
total += val
|
50
50
|
total += sum(q_normed.values())
|
51
51
|
|
52
|
-
dist =
|
52
|
+
dist = math.sqrt(total) / math.sqrt(2)
|
53
53
|
|
54
54
|
return dist
|
55
55
|
|
@@ -13,6 +13,7 @@
|
|
13
13
|
"""Helper functions for building dictionaries from matrices and lists."""
|
14
14
|
|
15
15
|
from __future__ import annotations
|
16
|
+
import math
|
16
17
|
import numpy as np
|
17
18
|
|
18
19
|
|
@@ -33,7 +34,7 @@ def make_dict_observable(matrix_observable: list | np.ndarray) -> dict:
|
|
33
34
|
dict_observable = {}
|
34
35
|
observable = np.array(matrix_observable)
|
35
36
|
observable_size = len(observable)
|
36
|
-
observable_bits =
|
37
|
+
observable_bits = math.ceil(math.log2(observable_size))
|
37
38
|
binary_formatter = f"0{observable_bits}b"
|
38
39
|
if observable.ndim == 2:
|
39
40
|
observable = observable.diagonal()
|
@@ -17,6 +17,7 @@ from __future__ import annotations
|
|
17
17
|
import itertools
|
18
18
|
from collections.abc import Iterable
|
19
19
|
from copy import deepcopy
|
20
|
+
import math
|
20
21
|
from typing import Union, cast
|
21
22
|
|
22
23
|
import numpy as np
|
@@ -121,7 +122,7 @@ class Z2Symmetries:
|
|
121
122
|
A list of unitaries used to diagonalize the Hamiltonian.
|
122
123
|
"""
|
123
124
|
cliffords = [
|
124
|
-
(SparsePauliOp(pauli_symm) + SparsePauliOp(sq_pauli)) /
|
125
|
+
(SparsePauliOp(pauli_symm) + SparsePauliOp(sq_pauli)) / math.sqrt(2)
|
125
126
|
for pauli_symm, sq_pauli in zip(self._symmetries, self._sq_paulis)
|
126
127
|
]
|
127
128
|
return cliffords
|
@@ -16,9 +16,11 @@ Chi-matrix representation of a Quantum Channel.
|
|
16
16
|
"""
|
17
17
|
|
18
18
|
from __future__ import annotations
|
19
|
-
import copy
|
19
|
+
import copy as _copy
|
20
|
+
import math
|
20
21
|
import numpy as np
|
21
22
|
|
23
|
+
from qiskit import _numpy_compat
|
22
24
|
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
23
25
|
from qiskit.circuit.instruction import Instruction
|
24
26
|
from qiskit.exceptions import QiskitError
|
@@ -96,7 +98,7 @@ class Chi(QuantumChannel):
|
|
96
98
|
if output_dims:
|
97
99
|
output_dim = np.prod(input_dims)
|
98
100
|
if output_dims is None and input_dims is None:
|
99
|
-
output_dim = int(
|
101
|
+
output_dim = int(math.sqrt(dim_l))
|
100
102
|
input_dim = dim_l // output_dim
|
101
103
|
elif input_dims is None:
|
102
104
|
input_dim = dim_l // output_dim
|
@@ -125,15 +127,14 @@ class Chi(QuantumChannel):
|
|
125
127
|
if output_dims is None:
|
126
128
|
output_dims = data.output_dims()
|
127
129
|
# Check input is N-qubit channel
|
128
|
-
num_qubits = int(
|
130
|
+
num_qubits = int(math.log2(input_dim))
|
129
131
|
if 2**num_qubits != input_dim or input_dim != output_dim:
|
130
132
|
raise QiskitError("Input is not an n-qubit Chi matrix.")
|
131
133
|
super().__init__(chi_mat, num_qubits=num_qubits)
|
132
134
|
|
133
|
-
def __array__(self, dtype=None):
|
134
|
-
|
135
|
-
|
136
|
-
return self.data
|
135
|
+
def __array__(self, dtype=None, copy=_numpy_compat.COPY_ONLY_IF_NEEDED):
|
136
|
+
dtype = self.data.dtype
|
137
|
+
return np.array(self.data, dtype=dtype, copy=copy)
|
137
138
|
|
138
139
|
@property
|
139
140
|
def _bipartite_shape(self):
|
@@ -180,7 +181,7 @@ class Chi(QuantumChannel):
|
|
180
181
|
|
181
182
|
@classmethod
|
182
183
|
def _tensor(cls, a, b):
|
183
|
-
ret =
|
184
|
+
ret = _copy.copy(a)
|
184
185
|
ret._op_shape = a._op_shape.tensor(b._op_shape)
|
185
186
|
ret._data = np.kron(a._data, b.data)
|
186
187
|
return ret
|
@@ -16,9 +16,11 @@ Choi-matrix representation of a Quantum Channel.
|
|
16
16
|
"""
|
17
17
|
|
18
18
|
from __future__ import annotations
|
19
|
-
import copy
|
19
|
+
import copy as _copy
|
20
|
+
import math
|
20
21
|
import numpy as np
|
21
22
|
|
23
|
+
from qiskit import _numpy_compat
|
22
24
|
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
23
25
|
from qiskit.circuit.instruction import Instruction
|
24
26
|
from qiskit.exceptions import QiskitError
|
@@ -103,7 +105,7 @@ class Choi(QuantumChannel):
|
|
103
105
|
if output_dims:
|
104
106
|
output_dim = np.prod(output_dims)
|
105
107
|
if output_dims is None and input_dims is None:
|
106
|
-
output_dim = int(
|
108
|
+
output_dim = int(math.sqrt(dim_l))
|
107
109
|
input_dim = dim_l // output_dim
|
108
110
|
elif input_dims is None:
|
109
111
|
input_dim = dim_l // output_dim
|
@@ -133,10 +135,9 @@ class Choi(QuantumChannel):
|
|
133
135
|
choi_mat = _to_choi(rep, data._data, input_dim, output_dim)
|
134
136
|
super().__init__(choi_mat, op_shape=op_shape)
|
135
137
|
|
136
|
-
def __array__(self, dtype=None):
|
137
|
-
if dtype
|
138
|
-
|
139
|
-
return self.data
|
138
|
+
def __array__(self, dtype=None, copy=_numpy_compat.COPY_ONLY_IF_NEEDED):
|
139
|
+
dtype = self.data.dtype if dtype is None else dtype
|
140
|
+
return np.array(self.data, dtype=dtype, copy=copy)
|
140
141
|
|
141
142
|
@property
|
142
143
|
def _bipartite_shape(self):
|
@@ -151,12 +152,12 @@ class Choi(QuantumChannel):
|
|
151
152
|
# ---------------------------------------------------------------------
|
152
153
|
|
153
154
|
def conjugate(self):
|
154
|
-
ret =
|
155
|
+
ret = _copy.copy(self)
|
155
156
|
ret._data = np.conj(self._data)
|
156
157
|
return ret
|
157
158
|
|
158
159
|
def transpose(self):
|
159
|
-
ret =
|
160
|
+
ret = _copy.copy(self)
|
160
161
|
ret._op_shape = self._op_shape.transpose()
|
161
162
|
# Make bipartite matrix
|
162
163
|
d_in, d_out = self.dim
|
@@ -205,7 +206,7 @@ class Choi(QuantumChannel):
|
|
205
206
|
|
206
207
|
@classmethod
|
207
208
|
def _tensor(cls, a, b):
|
208
|
-
ret =
|
209
|
+
ret = _copy.copy(a)
|
209
210
|
ret._op_shape = a._op_shape.tensor(b._op_shape)
|
210
211
|
ret._data = _bipartite_tensor(
|
211
212
|
a._data, b.data, shape1=a._bipartite_shape, shape2=b._bipartite_shape
|
@@ -16,6 +16,7 @@ Kraus representation of a Quantum Channel.
|
|
16
16
|
|
17
17
|
from __future__ import annotations
|
18
18
|
import copy
|
19
|
+
import math
|
19
20
|
from numbers import Number
|
20
21
|
import numpy as np
|
21
22
|
|
@@ -315,7 +316,7 @@ class Kraus(QuantumChannel):
|
|
315
316
|
return ret
|
316
317
|
# If the number is real we can update the Kraus operators
|
317
318
|
# directly
|
318
|
-
val =
|
319
|
+
val = math.sqrt(other)
|
319
320
|
kraus_r = None
|
320
321
|
kraus_l = [val * k for k in self._data[0]]
|
321
322
|
if self._data[1] is not None:
|
@@ -16,9 +16,11 @@ Pauli Transfer Matrix (PTM) representation of a Quantum Channel.
|
|
16
16
|
"""
|
17
17
|
|
18
18
|
from __future__ import annotations
|
19
|
-
import copy
|
19
|
+
import copy as _copy
|
20
|
+
import math
|
20
21
|
import numpy as np
|
21
22
|
|
23
|
+
from qiskit import _numpy_compat
|
22
24
|
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
23
25
|
from qiskit.circuit.instruction import Instruction
|
24
26
|
from qiskit.exceptions import QiskitError
|
@@ -100,11 +102,11 @@ class PTM(QuantumChannel):
|
|
100
102
|
if input_dims:
|
101
103
|
input_dim = np.prod(input_dims)
|
102
104
|
else:
|
103
|
-
input_dim = int(
|
105
|
+
input_dim = int(math.sqrt(din))
|
104
106
|
if output_dims:
|
105
107
|
output_dim = np.prod(input_dims)
|
106
108
|
else:
|
107
|
-
output_dim = int(
|
109
|
+
output_dim = int(math.sqrt(dout))
|
108
110
|
if output_dim**2 != dout or input_dim**2 != din or input_dim != output_dim:
|
109
111
|
raise QiskitError("Invalid shape for PTM matrix.")
|
110
112
|
else:
|
@@ -127,15 +129,14 @@ class PTM(QuantumChannel):
|
|
127
129
|
if output_dims is None:
|
128
130
|
output_dims = data.output_dims()
|
129
131
|
# Check input is N-qubit channel
|
130
|
-
num_qubits = int(
|
132
|
+
num_qubits = int(math.log2(input_dim))
|
131
133
|
if 2**num_qubits != input_dim or input_dim != output_dim:
|
132
134
|
raise QiskitError("Input is not an n-qubit Pauli transfer matrix.")
|
133
135
|
super().__init__(ptm, num_qubits=num_qubits)
|
134
136
|
|
135
|
-
def __array__(self, dtype=None):
|
136
|
-
if dtype
|
137
|
-
|
138
|
-
return self.data
|
137
|
+
def __array__(self, dtype=None, copy=_numpy_compat.COPY_ONLY_IF_NEEDED):
|
138
|
+
dtype = self.data.dtype if dtype is None else dtype
|
139
|
+
return np.array(self.data, dtype=dtype, copy=copy)
|
139
140
|
|
140
141
|
@property
|
141
142
|
def _bipartite_shape(self):
|
@@ -193,7 +194,7 @@ class PTM(QuantumChannel):
|
|
193
194
|
|
194
195
|
@classmethod
|
195
196
|
def _tensor(cls, a, b):
|
196
|
-
ret =
|
197
|
+
ret = _copy.copy(a)
|
197
198
|
ret._op_shape = a._op_shape.tensor(b._op_shape)
|
198
199
|
ret._data = np.kron(a._data, b.data)
|
199
200
|
return ret
|
@@ -16,6 +16,7 @@ Abstract base class for Quantum Channels.
|
|
16
16
|
|
17
17
|
from __future__ import annotations
|
18
18
|
import copy
|
19
|
+
import math
|
19
20
|
import sys
|
20
21
|
from abc import abstractmethod
|
21
22
|
from numbers import Number, Integral
|
@@ -249,7 +250,7 @@ class QuantumChannel(LinearOp):
|
|
249
250
|
"""
|
250
251
|
|
251
252
|
# Check if input is an N-qubit CPTP channel.
|
252
|
-
num_qubits = int(
|
253
|
+
num_qubits = int(math.log2(self._input_dim))
|
253
254
|
if self._input_dim != self._output_dim or 2**num_qubits != self._input_dim:
|
254
255
|
raise QiskitError(
|
255
256
|
"Cannot convert QuantumChannel to Instruction: channel is not an N-qubit channel."
|
@@ -15,6 +15,7 @@ Stinespring representation of a Quantum Channel.
|
|
15
15
|
|
16
16
|
from __future__ import annotations
|
17
17
|
import copy
|
18
|
+
import math
|
18
19
|
from numbers import Number
|
19
20
|
import numpy as np
|
20
21
|
|
@@ -281,7 +282,7 @@ class Stinespring(QuantumChannel):
|
|
281
282
|
return ret
|
282
283
|
# If the number is real we can update the Kraus operators
|
283
284
|
# directly
|
284
|
-
num =
|
285
|
+
num = math.sqrt(other)
|
285
286
|
stine_l, stine_r = self._data
|
286
287
|
stine_l = num * self._data[0]
|
287
288
|
stine_r = None
|
@@ -15,11 +15,13 @@ Superoperator representation of a Quantum Channel."""
|
|
15
15
|
|
16
16
|
from __future__ import annotations
|
17
17
|
|
18
|
-
import copy
|
18
|
+
import copy as _copy
|
19
|
+
import math
|
19
20
|
from typing import TYPE_CHECKING
|
20
21
|
|
21
22
|
import numpy as np
|
22
23
|
|
24
|
+
from qiskit import _numpy_compat
|
23
25
|
from qiskit.circuit.instruction import Instruction
|
24
26
|
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
25
27
|
from qiskit.exceptions import QiskitError
|
@@ -94,8 +96,8 @@ class SuperOp(QuantumChannel):
|
|
94
96
|
super_mat = np.asarray(data, dtype=complex)
|
95
97
|
# Determine total input and output dimensions
|
96
98
|
dout, din = super_mat.shape
|
97
|
-
input_dim = int(
|
98
|
-
output_dim = int(
|
99
|
+
input_dim = int(math.sqrt(din))
|
100
|
+
output_dim = int(math.sqrt(dout))
|
99
101
|
if output_dim**2 != dout or input_dim**2 != din:
|
100
102
|
raise QiskitError("Invalid shape for SuperOp matrix.")
|
101
103
|
op_shape = OpShape.auto(
|
@@ -126,10 +128,9 @@ class SuperOp(QuantumChannel):
|
|
126
128
|
# Initialize QuantumChannel
|
127
129
|
super().__init__(super_mat, op_shape=op_shape)
|
128
130
|
|
129
|
-
def __array__(self, dtype=None):
|
130
|
-
if dtype
|
131
|
-
|
132
|
-
return self.data
|
131
|
+
def __array__(self, dtype=None, copy=_numpy_compat.COPY_ONLY_IF_NEEDED):
|
132
|
+
dtype = self.data.dtype if dtype is None else dtype
|
133
|
+
return np.array(self.data, dtype=dtype, copy=copy)
|
133
134
|
|
134
135
|
@property
|
135
136
|
def _tensor_shape(self):
|
@@ -148,18 +149,18 @@ class SuperOp(QuantumChannel):
|
|
148
149
|
# ---------------------------------------------------------------------
|
149
150
|
|
150
151
|
def conjugate(self):
|
151
|
-
ret =
|
152
|
+
ret = _copy.copy(self)
|
152
153
|
ret._data = np.conj(self._data)
|
153
154
|
return ret
|
154
155
|
|
155
156
|
def transpose(self):
|
156
|
-
ret =
|
157
|
+
ret = _copy.copy(self)
|
157
158
|
ret._data = np.transpose(self._data)
|
158
159
|
ret._op_shape = self._op_shape.transpose()
|
159
160
|
return ret
|
160
161
|
|
161
162
|
def adjoint(self):
|
162
|
-
ret =
|
163
|
+
ret = _copy.copy(self)
|
163
164
|
ret._data = np.conj(np.transpose(self._data))
|
164
165
|
ret._op_shape = self._op_shape.transpose()
|
165
166
|
return ret
|
@@ -176,7 +177,7 @@ class SuperOp(QuantumChannel):
|
|
176
177
|
|
177
178
|
@classmethod
|
178
179
|
def _tensor(cls, a, b):
|
179
|
-
ret =
|
180
|
+
ret = _copy.copy(a)
|
180
181
|
ret._op_shape = a._op_shape.tensor(b._op_shape)
|
181
182
|
ret._data = _bipartite_tensor(
|
182
183
|
a._data, b.data, shape1=a._bipartite_shape, shape2=b._bipartite_shape
|
@@ -18,6 +18,7 @@ Transformations between QuantumChannel representations.
|
|
18
18
|
"""
|
19
19
|
|
20
20
|
from __future__ import annotations
|
21
|
+
import math
|
21
22
|
import numpy as np
|
22
23
|
|
23
24
|
from qiskit.exceptions import QiskitError
|
@@ -328,25 +329,25 @@ def _kraus_to_superop(data):
|
|
328
329
|
|
329
330
|
def _chi_to_choi(data, input_dim):
|
330
331
|
"""Transform Chi representation to a Choi representation."""
|
331
|
-
num_qubits = int(
|
332
|
+
num_qubits = int(math.log2(input_dim))
|
332
333
|
return _transform_from_pauli(data, num_qubits)
|
333
334
|
|
334
335
|
|
335
336
|
def _choi_to_chi(data, input_dim):
|
336
337
|
"""Transform Choi representation to the Chi representation."""
|
337
|
-
num_qubits = int(
|
338
|
+
num_qubits = int(math.log2(input_dim))
|
338
339
|
return _transform_to_pauli(data, num_qubits)
|
339
340
|
|
340
341
|
|
341
342
|
def _ptm_to_superop(data, input_dim):
|
342
343
|
"""Transform PTM representation to SuperOp representation."""
|
343
|
-
num_qubits = int(
|
344
|
+
num_qubits = int(math.log2(input_dim))
|
344
345
|
return _transform_from_pauli(data, num_qubits)
|
345
346
|
|
346
347
|
|
347
348
|
def _superop_to_ptm(data, input_dim):
|
348
349
|
"""Transform SuperOp representation to PTM representation."""
|
349
|
-
num_qubits = int(
|
350
|
+
num_qubits = int(math.log2(input_dim))
|
350
351
|
return _transform_to_pauli(data, num_qubits)
|
351
352
|
|
352
353
|
|
@@ -375,12 +376,12 @@ def _bipartite_tensor(mat1, mat2, shape1=None, shape2=None):
|
|
375
376
|
dim_a0, dim_a1 = mat1.shape
|
376
377
|
dim_b0, dim_b1 = mat2.shape
|
377
378
|
if shape1 is None:
|
378
|
-
sdim_a0 = int(
|
379
|
-
sdim_a1 = int(
|
379
|
+
sdim_a0 = int(math.sqrt(dim_a0))
|
380
|
+
sdim_a1 = int(math.sqrt(dim_a1))
|
380
381
|
shape1 = (sdim_a0, sdim_a0, sdim_a1, sdim_a1)
|
381
382
|
if shape2 is None:
|
382
|
-
sdim_b0 = int(
|
383
|
-
sdim_b1 = int(
|
383
|
+
sdim_b0 = int(math.sqrt(dim_b0))
|
384
|
+
sdim_b1 = int(math.sqrt(dim_b1))
|
384
385
|
shape2 = (sdim_b0, sdim_b0, sdim_b1, sdim_b1)
|
385
386
|
# Check dimensions
|
386
387
|
if len(shape1) != 4 or shape1[0] * shape1[1] != dim_a0 or shape1[2] * shape1[3] != dim_a1:
|
@@ -416,7 +417,7 @@ def _transform_to_pauli(data, num_qubits):
|
|
416
417
|
# to avoid rounding errors from square-roots of 2.
|
417
418
|
cob = basis_mat
|
418
419
|
for _ in range(num_qubits - 1):
|
419
|
-
dim = int(
|
420
|
+
dim = int(math.sqrt(len(cob)))
|
420
421
|
cob = np.reshape(
|
421
422
|
np.transpose(
|
422
423
|
np.reshape(np.kron(basis_mat, cob), (4, dim * dim, 2, 2, dim, dim)),
|
@@ -437,7 +438,7 @@ def _transform_from_pauli(data, num_qubits):
|
|
437
438
|
# to avoid rounding errors from square-roots of 2.
|
438
439
|
cob = basis_mat
|
439
440
|
for _ in range(num_qubits - 1):
|
440
|
-
dim = int(
|
441
|
+
dim = int(math.sqrt(len(cob)))
|
441
442
|
cob = np.reshape(
|
442
443
|
np.transpose(
|
443
444
|
np.reshape(np.kron(basis_mat, cob), (2, 2, dim, dim, 4, dim * dim)),
|
@@ -462,6 +463,6 @@ def _check_nqubit_dim(input_dim, output_dim):
|
|
462
463
|
raise QiskitError(
|
463
464
|
f"Not an n-qubit channel: input_dim ({input_dim}) != output_dim ({output_dim})"
|
464
465
|
)
|
465
|
-
num_qubits = int(
|
466
|
+
num_qubits = int(math.log2(input_dim))
|
466
467
|
if 2**num_qubits != input_dim:
|
467
468
|
raise QiskitError("Not an n-qubit channel: input_dim != 2 ** n")
|
@@ -357,10 +357,11 @@ class CNOTDihedral(BaseOperator, AdjointMixin):
|
|
357
357
|
_append_circuit(elem, circuit)
|
358
358
|
return elem
|
359
359
|
|
360
|
-
def __array__(self, dtype=None):
|
361
|
-
if
|
362
|
-
|
363
|
-
|
360
|
+
def __array__(self, dtype=None, copy=None):
|
361
|
+
if copy is False:
|
362
|
+
raise ValueError("unable to avoid copy while creating an array as requested")
|
363
|
+
arr = self.to_matrix()
|
364
|
+
return arr if dtype is None else arr.astype(dtype, copy=False)
|
364
365
|
|
365
366
|
def to_matrix(self):
|
366
367
|
"""Convert operator to Numpy matrix."""
|
@@ -16,13 +16,14 @@ Matrix Operator class.
|
|
16
16
|
|
17
17
|
from __future__ import annotations
|
18
18
|
|
19
|
-
import copy
|
19
|
+
import copy as _copy
|
20
20
|
import re
|
21
21
|
from numbers import Number
|
22
22
|
from typing import TYPE_CHECKING
|
23
23
|
|
24
24
|
import numpy as np
|
25
25
|
|
26
|
+
from qiskit import _numpy_compat
|
26
27
|
from qiskit.circuit.instruction import Instruction
|
27
28
|
from qiskit.circuit.library.standard_gates import HGate, IGate, SGate, TGate, XGate, YGate, ZGate
|
28
29
|
from qiskit.circuit.operation import Operation
|
@@ -81,6 +82,9 @@ class Operator(LinearOp):
|
|
81
82
|
a Numpy array of shape (2**N, 2**N) qubit systems will be used. If
|
82
83
|
the input operator is not an N-qubit operator, it will assign a
|
83
84
|
single subsystem with dimension specified by the shape of the input.
|
85
|
+
Note that two operators initialized via this method are only considered equivalent if they
|
86
|
+
match up to their canonical qubit order (or: permutation). See :meth:`.Operator.from_circuit`
|
87
|
+
to specify a different qubit permutation.
|
84
88
|
"""
|
85
89
|
op_shape = None
|
86
90
|
if isinstance(data, (list, np.ndarray)):
|
@@ -117,10 +121,9 @@ class Operator(LinearOp):
|
|
117
121
|
shape=self._data.shape,
|
118
122
|
)
|
119
123
|
|
120
|
-
def __array__(self, dtype=None):
|
121
|
-
if dtype
|
122
|
-
|
123
|
-
return self.data
|
124
|
+
def __array__(self, dtype=None, copy=_numpy_compat.COPY_ONLY_IF_NEEDED):
|
125
|
+
dtype = self.data.dtype if dtype is None else dtype
|
126
|
+
return np.array(self.data, dtype=dtype, copy=copy)
|
124
127
|
|
125
128
|
def __repr__(self):
|
126
129
|
prefix = "Operator("
|
@@ -391,8 +394,7 @@ class Operator(LinearOp):
|
|
391
394
|
Returns:
|
392
395
|
Operator: An operator representing the input circuit
|
393
396
|
"""
|
394
|
-
|
395
|
-
op = cls(np.eye(dimension))
|
397
|
+
|
396
398
|
if layout is None:
|
397
399
|
if not ignore_set_layout:
|
398
400
|
layout = getattr(circuit, "_layout", None)
|
@@ -403,27 +405,38 @@ class Operator(LinearOp):
|
|
403
405
|
initial_layout=layout,
|
404
406
|
input_qubit_mapping={qubit: index for index, qubit in enumerate(circuit.qubits)},
|
405
407
|
)
|
408
|
+
|
409
|
+
initial_layout = layout.initial_layout if layout is not None else None
|
410
|
+
|
406
411
|
if final_layout is None:
|
407
412
|
if not ignore_set_layout and layout is not None:
|
408
413
|
final_layout = getattr(layout, "final_layout", None)
|
409
414
|
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
# Convert circuit to an instruction
|
421
|
-
instruction = circuit.to_instruction()
|
422
|
-
op._append_instruction(instruction, qargs=qargs)
|
423
|
-
# If final layout is set permute output indices based on layout
|
415
|
+
from qiskit.synthesis.permutation.permutation_utils import _inverse_pattern
|
416
|
+
|
417
|
+
if initial_layout is not None:
|
418
|
+
input_qubits = [None] * len(layout.input_qubit_mapping)
|
419
|
+
for q, p in layout.input_qubit_mapping.items():
|
420
|
+
input_qubits[p] = q
|
421
|
+
|
422
|
+
initial_permutation = initial_layout.to_permutation(input_qubits)
|
423
|
+
initial_permutation_inverse = _inverse_pattern(initial_permutation)
|
424
|
+
|
424
425
|
if final_layout is not None:
|
425
|
-
|
426
|
-
|
426
|
+
final_permutation = final_layout.to_permutation(circuit.qubits)
|
427
|
+
final_permutation_inverse = _inverse_pattern(final_permutation)
|
428
|
+
|
429
|
+
op = Operator(circuit)
|
430
|
+
|
431
|
+
if initial_layout:
|
432
|
+
op = op.apply_permutation(initial_permutation, True)
|
433
|
+
|
434
|
+
if final_layout:
|
435
|
+
op = op.apply_permutation(final_permutation_inverse, False)
|
436
|
+
|
437
|
+
if initial_layout:
|
438
|
+
op = op.apply_permutation(initial_permutation_inverse, False)
|
439
|
+
|
427
440
|
return op
|
428
441
|
|
429
442
|
def is_unitary(self, atol=None, rtol=None):
|
@@ -447,13 +460,13 @@ class Operator(LinearOp):
|
|
447
460
|
|
448
461
|
def conjugate(self):
|
449
462
|
# Make a shallow copy and update array
|
450
|
-
ret =
|
463
|
+
ret = _copy.copy(self)
|
451
464
|
ret._data = np.conj(self._data)
|
452
465
|
return ret
|
453
466
|
|
454
467
|
def transpose(self):
|
455
468
|
# Make a shallow copy and update array
|
456
|
-
ret =
|
469
|
+
ret = _copy.copy(self)
|
457
470
|
ret._data = np.transpose(self._data)
|
458
471
|
ret._op_shape = self._op_shape.transpose()
|
459
472
|
return ret
|
@@ -523,7 +536,7 @@ class Operator(LinearOp):
|
|
523
536
|
"""
|
524
537
|
if self.input_dims() != self.output_dims():
|
525
538
|
raise QiskitError("Can only power with input_dims = output_dims.")
|
526
|
-
ret =
|
539
|
+
ret = _copy.copy(self)
|
527
540
|
if isinstance(n, int):
|
528
541
|
ret._data = np.linalg.matrix_power(self.data, n)
|
529
542
|
else:
|
@@ -550,7 +563,7 @@ class Operator(LinearOp):
|
|
550
563
|
|
551
564
|
@classmethod
|
552
565
|
def _tensor(cls, a, b):
|
553
|
-
ret =
|
566
|
+
ret = _copy.copy(a)
|
554
567
|
ret._op_shape = a._op_shape.tensor(b._op_shape)
|
555
568
|
ret._data = np.kron(a.data, b.data)
|
556
569
|
return ret
|
@@ -585,7 +598,7 @@ class Operator(LinearOp):
|
|
585
598
|
self._op_shape._validate_add(other._op_shape, qargs)
|
586
599
|
other = ScalarOp._pad_with_identity(self, other, qargs)
|
587
600
|
|
588
|
-
ret =
|
601
|
+
ret = _copy.copy(self)
|
589
602
|
ret._data = self.data + other.data
|
590
603
|
return ret
|
591
604
|
|
@@ -603,7 +616,7 @@ class Operator(LinearOp):
|
|
603
616
|
"""
|
604
617
|
if not isinstance(other, Number):
|
605
618
|
raise QiskitError("other is not a number")
|
606
|
-
ret =
|
619
|
+
ret = _copy.copy(self)
|
607
620
|
ret._data = other * self._data
|
608
621
|
return ret
|
609
622
|
|
@@ -643,7 +656,7 @@ class Operator(LinearOp):
|
|
643
656
|
Returns:
|
644
657
|
Operator: the operator with reversed subsystem order.
|
645
658
|
"""
|
646
|
-
ret =
|
659
|
+
ret = _copy.copy(self)
|
647
660
|
axes = tuple(range(self._op_shape._num_qargs_l - 1, -1, -1))
|
648
661
|
axes = axes + tuple(len(axes) + i for i in axes)
|
649
662
|
ret._data = np.reshape(
|