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
@@ -15,78 +15,151 @@ Dataclass tools for data namespaces (bins)
|
|
15
15
|
"""
|
16
16
|
from __future__ import annotations
|
17
17
|
|
18
|
-
from
|
19
|
-
from dataclasses import make_dataclass
|
18
|
+
from typing import Any, ItemsView, Iterable, KeysView, ValuesView
|
20
19
|
|
20
|
+
import numpy as np
|
21
21
|
|
22
|
-
|
23
|
-
|
22
|
+
from .shape import ShapedMixin, ShapeInput, shape_tuple
|
23
|
+
|
24
|
+
|
25
|
+
def _value_repr(value: Any) -> str:
|
26
|
+
"""Helper function for :meth:`DataBin.__repr__`."""
|
27
|
+
if isinstance(value, np.ndarray):
|
28
|
+
return f"np.ndarray(<shape={value.shape}, dtype={value.dtype}>)"
|
29
|
+
return repr(value)
|
24
30
|
|
25
|
-
This is so that the class has a custom repr with DataBin<*shape> notation.
|
26
|
-
"""
|
27
31
|
|
28
|
-
|
29
|
-
|
30
|
-
if cls._SHAPE is None:
|
31
|
-
return name
|
32
|
-
shape = ",".join(map(str, cls._SHAPE))
|
33
|
-
return f"{name}<{shape}>"
|
32
|
+
class DataBin(ShapedMixin):
|
33
|
+
"""Namespace for storing data.
|
34
34
|
|
35
|
+
.. code-block:: python
|
36
|
+
|
37
|
+
data = DataBin(
|
38
|
+
alpha=BitArray.from_bitstrings(["0010"]),
|
39
|
+
beta=np.array([1.2])
|
40
|
+
)
|
35
41
|
|
36
|
-
|
37
|
-
|
42
|
+
print("alpha data:", data.alpha)
|
43
|
+
print("beta data:", data.beta)
|
38
44
|
|
39
|
-
Subclasses are typically made via :class:`~make_data_bin`, which is a specialization of
|
40
|
-
:class:`make_dataclass`.
|
41
45
|
"""
|
42
46
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
47
|
+
__slots__ = ("_data", "_shape")
|
48
|
+
|
49
|
+
_RESTRICTED_NAMES = frozenset(
|
50
|
+
{
|
51
|
+
"_RESTRICTED_NAMES",
|
52
|
+
"_SHAPE",
|
53
|
+
"_FIELDS",
|
54
|
+
"_FIELD_TYPES",
|
55
|
+
"_data",
|
56
|
+
"_shape",
|
57
|
+
"keys",
|
58
|
+
"values",
|
59
|
+
"items",
|
60
|
+
"shape",
|
61
|
+
"ndim",
|
62
|
+
"size",
|
63
|
+
}
|
64
|
+
)
|
65
|
+
|
66
|
+
def __init__(self, *, shape: ShapeInput = (), **data):
|
67
|
+
"""
|
68
|
+
Args:
|
69
|
+
data: Name/value data to place in the data bin.
|
70
|
+
shape: The leading shape common to all entries in the data bin. This defaults to
|
71
|
+
the trivial leading shape of ``()`` that is compatible with all objects.
|
72
|
+
|
73
|
+
Raises:
|
74
|
+
ValueError: If a name overlaps with a method name on this class.
|
75
|
+
ValueError: If some value is inconsistent with the provided shape.
|
76
|
+
"""
|
77
|
+
if not self._RESTRICTED_NAMES.isdisjoint(data):
|
78
|
+
bad_names = sorted(self._RESTRICTED_NAMES.intersection(data))
|
79
|
+
raise ValueError(f"Cannot assign with these field names: {bad_names}")
|
80
|
+
|
81
|
+
_setattr = super().__setattr__
|
82
|
+
_setattr("_shape", shape_tuple(shape))
|
83
|
+
_setattr("_data", data)
|
84
|
+
|
85
|
+
ndim = len(self._shape)
|
86
|
+
for name, value in data.items():
|
87
|
+
if getattr(value, "shape", shape)[:ndim] != shape:
|
88
|
+
raise ValueError(f"The value of '{name}' does not lead with the shape {shape}.")
|
89
|
+
_setattr(name, value)
|
90
|
+
|
91
|
+
super().__init__()
|
49
92
|
|
50
93
|
def __len__(self):
|
51
|
-
return len(self.
|
94
|
+
return len(self._data)
|
95
|
+
|
96
|
+
def __setattr__(self, *_):
|
97
|
+
raise NotImplementedError
|
52
98
|
|
53
99
|
def __repr__(self):
|
54
|
-
vals =
|
55
|
-
|
100
|
+
vals = [f"{name}={_value_repr(val)}" for name, val in self.items()]
|
101
|
+
if self.ndim:
|
102
|
+
vals.append(f"shape={self.shape}")
|
103
|
+
return f"{type(self).__name__}({', '.join(vals)})"
|
56
104
|
|
105
|
+
def __getitem__(self, key: str) -> Any:
|
106
|
+
try:
|
107
|
+
return self._data[key]
|
108
|
+
except KeyError as ex:
|
109
|
+
raise KeyError(f"Key ({key}) does not exist in this data bin.") from ex
|
57
110
|
|
58
|
-
def
|
59
|
-
|
60
|
-
) -> DataBinMeta:
|
61
|
-
"""Return a new subclass of :class:`~DataBin` with the provided fields and shape.
|
111
|
+
def __contains__(self, key: str) -> bool:
|
112
|
+
return key in self._data
|
62
113
|
|
63
|
-
|
114
|
+
def __iter__(self) -> Iterable[str]:
|
115
|
+
return iter(self._data)
|
64
116
|
|
65
|
-
|
117
|
+
def keys(self) -> KeysView[str]:
|
118
|
+
"""Return a view of field names."""
|
119
|
+
return self._data.keys()
|
66
120
|
|
67
|
-
|
68
|
-
|
121
|
+
def values(self) -> ValuesView[Any]:
|
122
|
+
"""Return a view of values."""
|
123
|
+
return self._data.values()
|
124
|
+
|
125
|
+
def items(self) -> ItemsView[str, Any]:
|
126
|
+
"""Return a view of field names and values"""
|
127
|
+
return self._data.items()
|
128
|
+
|
129
|
+
# The following properties exist to provide support to legacy private class attributes which
|
130
|
+
# gained widespread prior to qiskit 1.1. These properties will be removed once the internal
|
131
|
+
# projects have made the appropriate changes.
|
132
|
+
|
133
|
+
@property
|
134
|
+
def _FIELDS(self) -> tuple[str, ...]: # pylint: disable=invalid-name
|
135
|
+
return tuple(self._data)
|
136
|
+
|
137
|
+
@property
|
138
|
+
def _FIELD_TYPES(self) -> tuple[Any, ...]: # pylint: disable=invalid-name
|
139
|
+
return tuple(map(type, self.values()))
|
140
|
+
|
141
|
+
@property
|
142
|
+
def _SHAPE(self) -> tuple[int, ...]: # pylint: disable=invalid-name
|
143
|
+
return self.shape
|
144
|
+
|
145
|
+
|
146
|
+
# pylint: disable=unused-argument
|
147
|
+
def make_data_bin(
|
148
|
+
fields: Iterable[tuple[str, type]], shape: tuple[int, ...] | None = None
|
149
|
+
) -> type[DataBin]:
|
150
|
+
"""Return the :class:`~DataBin` type.
|
151
|
+
|
152
|
+
.. note::
|
153
|
+
This class used to return a subclass of :class:`~DataBin`. However, that caused confusion
|
154
|
+
and didn't have a useful purpose. Several internal projects made use of this internal
|
155
|
+
function prior to qiskit 1.1. This function will be removed once these internal projects
|
156
|
+
have made the appropriate changes.
|
69
157
|
|
70
158
|
Args:
|
71
159
|
fields: Tuples ``(name, type)`` specifying the attributes of the returned class.
|
72
160
|
shape: The intended shape of every attribute of this class.
|
73
161
|
|
74
162
|
Returns:
|
75
|
-
|
163
|
+
The :class:`DataBin` type.
|
76
164
|
"""
|
77
|
-
|
78
|
-
for name in field_names:
|
79
|
-
if name in DataBin._RESTRICTED_NAMES:
|
80
|
-
raise ValueError(f"'{name}' is a restricted name for a DataBin.")
|
81
|
-
cls = make_dataclass(
|
82
|
-
"DataBin",
|
83
|
-
dict(zip(field_names, field_types)),
|
84
|
-
bases=(DataBin,),
|
85
|
-
frozen=True,
|
86
|
-
unsafe_hash=True,
|
87
|
-
repr=False,
|
88
|
-
)
|
89
|
-
cls._SHAPE = shape
|
90
|
-
cls._FIELDS = field_names
|
91
|
-
cls._FIELD_TYPES = field_types
|
92
|
-
return cls
|
165
|
+
return DataBin
|
@@ -132,6 +132,15 @@ class EstimatorPub(ShapedMixin):
|
|
132
132
|
validate=False, # Assume Pub is already validated
|
133
133
|
)
|
134
134
|
return pub
|
135
|
+
|
136
|
+
if isinstance(pub, QuantumCircuit):
|
137
|
+
raise ValueError(
|
138
|
+
f"An invalid Estimator pub-like was given ({type(pub)}). "
|
139
|
+
"If you want to run a single pub, you need to wrap it with `[]` like "
|
140
|
+
"`estimator.run([(circuit, observables, param_values)])` "
|
141
|
+
"instead of `estimator.run((circuit, observables, param_values))`."
|
142
|
+
)
|
143
|
+
|
135
144
|
if len(pub) not in [2, 3, 4]:
|
136
145
|
raise ValueError(
|
137
146
|
f"The length of pub must be 2, 3 or 4, but length {len(pub)} is given."
|
@@ -208,8 +217,6 @@ estimator, if ``precision=None`` the estimator will determine the target precisi
|
|
208
217
|
An Estimator Pub can also be initialized in the following formats which
|
209
218
|
will be converted to the full Pub tuple:
|
210
219
|
|
211
|
-
* ``circuit
|
212
|
-
* ``(circuit,)``
|
213
220
|
* ``(circuit, observables)``
|
214
|
-
* ``(circuit,
|
221
|
+
* ``(circuit, observables, parameter_values)``
|
215
222
|
"""
|
@@ -101,10 +101,10 @@ class ObservablesArray(ShapedMixin):
|
|
101
101
|
"""Convert to a nested list"""
|
102
102
|
return self._array.tolist()
|
103
103
|
|
104
|
-
def __array__(self, dtype=None):
|
104
|
+
def __array__(self, dtype=None, copy=None):
|
105
105
|
"""Convert to an Numpy.ndarray"""
|
106
106
|
if dtype is None or dtype == object:
|
107
|
-
return self._array
|
107
|
+
return self._array.copy() if copy else self._array
|
108
108
|
raise ValueError("Type must be 'None' or 'object'")
|
109
109
|
|
110
110
|
@overload
|
@@ -18,10 +18,11 @@ Sampler Pub class
|
|
18
18
|
from __future__ import annotations
|
19
19
|
|
20
20
|
from collections.abc import Mapping
|
21
|
-
from typing import Tuple, Union
|
22
21
|
from numbers import Integral
|
22
|
+
from typing import Tuple, Union
|
23
23
|
|
24
24
|
from qiskit import QuantumCircuit
|
25
|
+
from qiskit.circuit import CircuitInstruction
|
25
26
|
|
26
27
|
from .bindings_array import BindingsArray, BindingsArrayLike
|
27
28
|
from .shape import ShapedMixin
|
@@ -113,6 +114,14 @@ class SamplerPub(ShapedMixin):
|
|
113
114
|
if isinstance(pub, QuantumCircuit):
|
114
115
|
return cls(circuit=pub, shots=shots, validate=True)
|
115
116
|
|
117
|
+
if isinstance(pub, CircuitInstruction):
|
118
|
+
raise ValueError(
|
119
|
+
f"An invalid Sampler pub-like was given ({type(pub)}). "
|
120
|
+
"If you want to run a single circuit, "
|
121
|
+
"you need to wrap it with `[]` like `sampler.run([circuit])` "
|
122
|
+
"instead of `sampler.run(circuit)`."
|
123
|
+
)
|
124
|
+
|
116
125
|
if len(pub) not in [1, 2, 3]:
|
117
126
|
raise ValueError(
|
118
127
|
f"The length of pub must be 1, 2 or 3, but length {len(pub)} is given."
|
@@ -147,10 +156,17 @@ class SamplerPub(ShapedMixin):
|
|
147
156
|
# Cross validate circuits and parameter values
|
148
157
|
num_parameters = self.parameter_values.num_parameters
|
149
158
|
if num_parameters != self.circuit.num_parameters:
|
150
|
-
|
159
|
+
message = (
|
151
160
|
f"The number of values ({num_parameters}) does not match "
|
152
161
|
f"the number of parameters ({self.circuit.num_parameters}) for the circuit."
|
153
162
|
)
|
163
|
+
if num_parameters == 0:
|
164
|
+
message += (
|
165
|
+
" Note that if you want to run a single pub, you need to wrap it with `[]` like "
|
166
|
+
"`sampler.run([(circuit, param_values)])` instead of "
|
167
|
+
"`sampler.run((circuit, param_values))`."
|
168
|
+
)
|
169
|
+
raise ValueError(message)
|
154
170
|
|
155
171
|
|
156
172
|
SamplerPubLike = Union[
|
@@ -171,7 +187,7 @@ if ``shots=None`` the number of run shots is determined by the sampler.
|
|
171
187
|
A Sampler Pub can also be initialized in the following formats which
|
172
188
|
will be converted to the full Pub tuple:
|
173
189
|
|
174
|
-
* ``circuit
|
190
|
+
* ``circuit``
|
175
191
|
* ``(circuit,)``
|
176
192
|
* ``(circuit, parameter_values)``
|
177
193
|
"""
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2024.
|
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
|
+
"""
|
14
|
+
Sampler Pub result class
|
15
|
+
"""
|
16
|
+
|
17
|
+
from __future__ import annotations
|
18
|
+
|
19
|
+
from typing import Iterable
|
20
|
+
|
21
|
+
import numpy as np
|
22
|
+
|
23
|
+
from .bit_array import BitArray
|
24
|
+
from .pub_result import PubResult
|
25
|
+
|
26
|
+
|
27
|
+
class SamplerPubResult(PubResult):
|
28
|
+
"""Result of Sampler Pub."""
|
29
|
+
|
30
|
+
def join_data(self, names: Iterable[str] | None = None) -> BitArray | np.ndarray:
|
31
|
+
"""Join data from many registers into one data container.
|
32
|
+
|
33
|
+
Data is joined along the bits axis. For example, for :class:`~.BitArray` data, this corresponds
|
34
|
+
to bitstring concatenation.
|
35
|
+
|
36
|
+
Args:
|
37
|
+
names: Which registers to join. Their order is maintained, for example, given
|
38
|
+
``["alpha", "beta"]``, the data from register ``alpha`` is placed to the left of the
|
39
|
+
data from register ``beta``. When ``None`` is given, this value is set to the
|
40
|
+
ordered list of register names, which will have been preserved from the input circuit
|
41
|
+
order.
|
42
|
+
|
43
|
+
Returns:
|
44
|
+
Joint data.
|
45
|
+
|
46
|
+
Raises:
|
47
|
+
ValueError: If specified names are empty.
|
48
|
+
ValueError: If specified name does not exist.
|
49
|
+
TypeError: If specified data comes from incompatible types.
|
50
|
+
"""
|
51
|
+
if names is None:
|
52
|
+
names = list(self.data)
|
53
|
+
if not names:
|
54
|
+
raise ValueError("No entry exists in the data bin.")
|
55
|
+
else:
|
56
|
+
names = list(names)
|
57
|
+
if not names:
|
58
|
+
raise ValueError("An empty name list is given.")
|
59
|
+
for name in names:
|
60
|
+
if name not in self.data:
|
61
|
+
raise ValueError(f"Name '{name}' does not exist.")
|
62
|
+
|
63
|
+
data = [self.data[name] for name in names]
|
64
|
+
if isinstance(data[0], BitArray):
|
65
|
+
if not all(isinstance(datum, BitArray) for datum in data):
|
66
|
+
raise TypeError("Data comes from incompatible types.")
|
67
|
+
joint_data = BitArray.concatenate_bits(data)
|
68
|
+
elif isinstance(data[0], np.ndarray):
|
69
|
+
if not all(isinstance(datum, np.ndarray) for datum in data):
|
70
|
+
raise TypeError("Data comes from incompatible types.")
|
71
|
+
joint_data = np.concatenate(data, axis=-1)
|
72
|
+
else:
|
73
|
+
raise TypeError("Data comes from incompatible types.")
|
74
|
+
return joint_data
|
@@ -59,15 +59,15 @@ class ShapedMixin(Shaped):
|
|
59
59
|
return f"{type(self).__name__}(<{self.shape}>)"
|
60
60
|
|
61
61
|
@property
|
62
|
-
def shape(self):
|
62
|
+
def shape(self) -> tuple[int, ...]:
|
63
63
|
return self._shape
|
64
64
|
|
65
65
|
@property
|
66
|
-
def ndim(self):
|
66
|
+
def ndim(self) -> int:
|
67
67
|
return len(self._shape)
|
68
68
|
|
69
69
|
@property
|
70
|
-
def size(self):
|
70
|
+
def size(self) -> int:
|
71
71
|
return int(np.prod(self._shape, dtype=int))
|
72
72
|
|
73
73
|
|
@@ -85,7 +85,7 @@ def array_coerce(arr: ArrayLike | Shaped) -> NDArray | Shaped:
|
|
85
85
|
"""
|
86
86
|
if isinstance(arr, Shaped):
|
87
87
|
return arr
|
88
|
-
return np.
|
88
|
+
return np.asarray(arr)
|
89
89
|
|
90
90
|
|
91
91
|
def _flatten_to_ints(arg: ShapeInput) -> Iterable[int]:
|
@@ -22,7 +22,7 @@ import numpy as np
|
|
22
22
|
from qiskit.quantum_info import SparsePauliOp, Statevector
|
23
23
|
|
24
24
|
from .base import BaseEstimatorV2
|
25
|
-
from .containers import EstimatorPubLike, PrimitiveResult, PubResult
|
25
|
+
from .containers import DataBin, EstimatorPubLike, PrimitiveResult, PubResult
|
26
26
|
from .containers.estimator_pub import EstimatorPub
|
27
27
|
from .primitive_job import PrimitiveJob
|
28
28
|
from .utils import bound_circuit_to_instruction
|
@@ -160,6 +160,6 @@ class StatevectorEstimator(BaseEstimatorV2):
|
|
160
160
|
raise ValueError("Given operator is not Hermitian and noise cannot be added.")
|
161
161
|
expectation_value = rng.normal(expectation_value, precision)
|
162
162
|
evs[index] = expectation_value
|
163
|
-
|
164
|
-
|
165
|
-
return PubResult(
|
163
|
+
|
164
|
+
data = DataBin(evs=evs, stds=stds, shape=evs.shape)
|
165
|
+
return PubResult(data, metadata={"precision": precision})
|
@@ -15,9 +15,9 @@ Statevector Sampler class
|
|
15
15
|
|
16
16
|
from __future__ import annotations
|
17
17
|
|
18
|
+
import warnings
|
18
19
|
from dataclasses import dataclass
|
19
20
|
from typing import Iterable
|
20
|
-
import warnings
|
21
21
|
|
22
22
|
import numpy as np
|
23
23
|
from numpy.typing import NDArray
|
@@ -30,10 +30,10 @@ from .base import BaseSamplerV2
|
|
30
30
|
from .base.validation import _has_measure
|
31
31
|
from .containers import (
|
32
32
|
BitArray,
|
33
|
+
DataBin,
|
33
34
|
PrimitiveResult,
|
34
|
-
|
35
|
+
SamplerPubResult,
|
35
36
|
SamplerPubLike,
|
36
|
-
make_data_bin,
|
37
37
|
)
|
38
38
|
from .containers.sampler_pub import SamplerPub
|
39
39
|
from .containers.bit_array import _min_num_bytes
|
@@ -154,7 +154,7 @@ class StatevectorSampler(BaseSamplerV2):
|
|
154
154
|
|
155
155
|
def run(
|
156
156
|
self, pubs: Iterable[SamplerPubLike], *, shots: int | None = None
|
157
|
-
) -> PrimitiveJob[PrimitiveResult[
|
157
|
+
) -> PrimitiveJob[PrimitiveResult[SamplerPubResult]]:
|
158
158
|
if shots is None:
|
159
159
|
shots = self._default_shots
|
160
160
|
coerced_pubs = [SamplerPub.coerce(pub, shots) for pub in pubs]
|
@@ -169,11 +169,11 @@ class StatevectorSampler(BaseSamplerV2):
|
|
169
169
|
job._submit()
|
170
170
|
return job
|
171
171
|
|
172
|
-
def _run(self, pubs: Iterable[SamplerPub]) -> PrimitiveResult[
|
172
|
+
def _run(self, pubs: Iterable[SamplerPub]) -> PrimitiveResult[SamplerPubResult]:
|
173
173
|
results = [self._run_pub(pub) for pub in pubs]
|
174
174
|
return PrimitiveResult(results)
|
175
175
|
|
176
|
-
def _run_pub(self, pub: SamplerPub) ->
|
176
|
+
def _run_pub(self, pub: SamplerPub) -> SamplerPubResult:
|
177
177
|
circuit, qargs, meas_info = _preprocess_circuit(pub.circuit)
|
178
178
|
bound_circuits = pub.parameter_values.bind_all(circuit)
|
179
179
|
arrays = {
|
@@ -194,15 +194,10 @@ class StatevectorSampler(BaseSamplerV2):
|
|
194
194
|
ary = _samples_to_packed_array(samples_array, item.num_bits, item.qreg_indices)
|
195
195
|
arrays[item.creg_name][index] = ary
|
196
196
|
|
197
|
-
data_bin_cls = make_data_bin(
|
198
|
-
[(item.creg_name, BitArray) for item in meas_info],
|
199
|
-
shape=bound_circuits.shape,
|
200
|
-
)
|
201
197
|
meas = {
|
202
198
|
item.creg_name: BitArray(arrays[item.creg_name], item.num_bits) for item in meas_info
|
203
199
|
}
|
204
|
-
|
205
|
-
return PubResult(data_bin, metadata={"shots": pub.shots})
|
200
|
+
return SamplerPubResult(DataBin(**meas, shape=pub.shape), metadata={"shots": pub.shots})
|
206
201
|
|
207
202
|
|
208
203
|
def _preprocess_circuit(circuit: QuantumCircuit):
|