Skip to content

Commit d217616

Browse files
0.4.2 patch release (#234)
* adding sympy as an explicit requirement (#233) * Add warning for JAX versions on import of Dynamics (#232) * Add probability normalization to DynamicsBackend sampling routine (#239) * Add warning if digital carrier exceeds Nyquist frequency in pulse -> signal conversion (#242) * Fix bug with carrier_freq being a JAX tracer if envelope is constant in Signal (#247) * Remove subsystem_labels option from DynamicsBackend (#248) * Rename subsystem_dims Dict to subsystem_dims_dict (#250) * Fix ClassicalRegister counting in DynamicsBackend (#252) * temporary fix for docs (#253) * Drop support for backendV2 in from_backend (#249) * incrementing version number * cleaning up reno files --------- Co-authored-by: Kento Ueda <[email protected]>
1 parent 807edf9 commit d217616

26 files changed

+447
-121
lines changed

docs/conf.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
# The short X.Y version
2222
version = ''
2323
# The full version, including alpha/beta/rc tags
24-
release = '0.4.1'
24+
release = '0.4.2'
2525

2626
extensions = [
2727
'sphinx.ext.napoleon',
@@ -82,3 +82,7 @@
8282
nbsphinx_execute = 'always'
8383
nbsphinx_widgets_path = ''
8484
exclude_patterns = ['_build', '**.ipynb_checkpoints']
85+
86+
# this is tied to the temporary restriction to JAX versions <=0.4.6. See issue #190
87+
import os
88+
os.environ["JAX_JIT_PJIT_API_MERGE"] = "0"

docs/release_notes.rst

Lines changed: 152 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,152 @@
1-
.. release-notes:: Release Notes
1+
=============
2+
Release Notes
3+
=============
4+
5+
.. _Release Notes_0.4.1-12:
6+
7+
0.4.1-12
8+
========
9+
10+
.. _Release Notes_0.4.1-12_Prelude:
11+
12+
Prelude
13+
-------
14+
15+
.. releasenotes/notes/patch-0.4.2-6a7c7bf380e54187.yaml @ None
16+
17+
Qiskit Dynamics 0.4.2 is an incremental release with minor bug fixes and additional warnings to help guide users through issues.
18+
19+
20+
.. _Release Notes_0.4.1-12_Upgrade Notes:
21+
22+
Upgrade Notes
23+
-------------
24+
25+
.. releasenotes/notes/subsystem_labels-removal-9fcc71c310eff220.yaml @ b'cf256192ce1c0ef7c2f4c696d9be64234b48b68f'
26+
27+
- The ``subsystem_labels`` option has been removed from the :class:`.DynamicsBackend`. This
28+
removal impacts some technical aspects of the backend returned by
29+
:meth:`.DynamicsBackend.from_backend` when the ``subsystem_list`` argument is used. Using the
30+
``subsystem_list`` argument with :meth:`.DynamicsBackend.from_backend` restricts the internally
31+
constructed model to the qubits in ``subsystem_list``. When doing so previously, the option
32+
``subsystem_labels`` would be set to ``subsystem_labels``, and ``subsystem_dims`` would record
33+
only the dimensions for the systems in ``subsystem_labels``. To account for the fact that
34+
``subsystem_labels`` no longer exists, :meth:`.DynamicsBackend.from_backend` now constructs
35+
``subsystem_dims`` to list a dimension for all of the qubits in the original backend, however
36+
now the dimensions of the removed systems are given as 1 (i.e. they are treated as trivial
37+
quantum systems with a single state). This change is made only for technical bookkeping
38+
purposes, and has no impact on the core simulation behaviour.
39+
40+
41+
.. _Release Notes_0.4.1-12_Bug Fixes:
42+
43+
Bug Fixes
44+
---------
45+
46+
.. releasenotes/notes/carrier-freq-0-19ad4362c874944f.yaml @ None
47+
48+
- In the case that ``envelope`` is a constant, the :meth:`.Signal.__init__` method has been
49+
updated to not attempt to evaluate ``carrier_freq == 0.0`` if ``carrier_freq`` is a JAX tracer.
50+
In this case, it is not possible to determine if the :class:`.Signal` instance is constant. This
51+
resolves an error that was being raised during JAX tracing if ``carrier_freq`` is abstract.
52+
53+
.. releasenotes/notes/classical-registers-9bb117398a4d21d5.yaml @ None
54+
55+
- Fixes bug in :meth:`.DynamicsBackend.run` that caused miscounting of the number of classical
56+
registers in a :class:`~qiskit.circuit.QuantumCircuit` (issue #251).
57+
58+
.. releasenotes/notes/normalize-probabilities-d729245bb3fe5f10.yaml @ b'6ede10a2bc8c61e8640db9085d4d1d9423341550'
59+
60+
- ``DynamicsBackend.options.normalize_states`` now also controls whether or not the probability
61+
distribution over outcomes is normalized before sampling outcomes.
62+
63+
64+
.. _Release Notes_0.4.1-12_Other Notes:
65+
66+
Other Notes
67+
-----------
68+
69+
.. releasenotes/notes/patch-0.4.2-6a7c7bf380e54187.yaml @ None
70+
71+
- For users that have JAX installed, a warning has been added upon import of Qiskit Dynamics to
72+
notify the user of issues with certain versions: JAX versions newer than ``0.4.6`` break the
73+
``perturbation`` module, and to use ``perturbation`` module with versions ``0.4.4``, ``0.4.5``,
74+
or ``0.4.6``, it is necessary to set ``os.environ['JAX_JIT_PJIT_API_MERGE'] = '0'`` before
75+
importing JAX or Dynamics.
76+
77+
.. releasenotes/notes/patch-0.4.2-6a7c7bf380e54187.yaml @ None
78+
79+
- A warning has been added to :class:`.InstructionToSignals` class when converting pulse schedules
80+
to signals to notify the user if the usage of ``SetFrequency`` or ``ShiftFrequency`` commands
81+
result in a digital carrier frequency larger than the Nyquist frequency of the envelope sample
82+
size ``dt``.
83+
84+
85+
.. _Release Notes_0.4.1:
86+
87+
0.4.1
88+
=====
89+
90+
.. _Release Notes_0.4.1_Prelude:
91+
92+
Prelude
93+
-------
94+
95+
.. releasenotes/notes/0.4/patch-0.4.1-d339aa8669341341.yaml @ b'd6e280259d120d31723e0220a91cbd7dd8099298'
96+
97+
Qiskit Dynamics 0.4.1 is an incremental release with minor bug fixes, documentation updates, and usability features.
98+
99+
.. _Release Notes_0.4.1_New Features:
100+
101+
New Features
102+
------------
103+
104+
.. releasenotes/notes/measurement_property_bug_fix-12461088823a943c.yaml @ b'807edf92d7f5d6f34715fff9d21614d77cd096d3'
105+
106+
- The :meth:`DynamicsBackend.from_backend` method has been updated to automatically populate the
107+
``control_channel_map`` option based on the supplied backend if the user does not supply one.
108+
109+
110+
.. _Release Notes_0.4.1_Known Issues:
111+
112+
Known Issues
113+
------------
114+
115+
.. releasenotes/notes/0.4/diffrax-bound-0bd80c01b7f4b48f.yaml @ b'd6e280259d120d31723e0220a91cbd7dd8099298'
116+
117+
- Due to a bug in JAX, Dynamics can only be used with jax<=0.4.6. As they depend on newer versions
118+
of JAX, Dynamics is also now only compatible with diffrax<=0.3.1 and equinox<=0.10.3.
119+
120+
121+
.. _Release Notes_0.4.1_Bug Fixes:
122+
123+
Bug Fixes
124+
---------
125+
126+
.. releasenotes/notes/0.4/multiset-order-bug-fix-1f1603ee1e230cba.yaml @ b'd6e280259d120d31723e0220a91cbd7dd8099298'
127+
128+
- Fixes a bug in the perturbation module with internal sorting of ``Multiset`` instances, which
129+
caused incorrect computation of perturbation theory terms when ``>10`` perturbations are
130+
present.
131+
132+
.. releasenotes/notes/measurement_property_bug_fix-12461088823a943c.yaml @ b'807edf92d7f5d6f34715fff9d21614d77cd096d3'
133+
134+
- A bug in :meth:`DynamicsBackend.__init__` causing existing measurement instructions for a
135+
user-supplied :class:`Target` to be overwritten has been fixed.
136+
137+
138+
.. _Release Notes_0.4.1_Other Notes:
139+
140+
Other Notes
141+
-----------
142+
143+
.. releasenotes/notes/0.4/move-repo-c0b48ba3b0ced8db.yaml @ b'd6e280259d120d31723e0220a91cbd7dd8099298'
144+
145+
- The repository has been moved from
146+
[github.com/Qiskit/qiskit-dynamics](https://github.com/Qiskit/qiskit-dynamics) to
147+
[github.com/Qiskit-Extensions/qiskit-dynamics](https://github.com/Qiskit-Extensions/qiskit-dynamics),
148+
and the documentation has been moved from
149+
[qiskit.org/documentation/dynamics](https://qiskit.org/documentation/dynamics) to
150+
[qiskit.org/ecosystem/dynamics](https://qiskit.org/ecosystem/dynamics/).
151+
152+

qiskit_dynamics/VERSION.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.4.1
1+
0.4.2

qiskit_dynamics/backend/backend_string_parser/hamiltonian_string_parser.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,12 +163,12 @@ def parse_backend_hamiltonian_dict(
163163
# force keys in hamiltonian['qub'] to be ints
164164
qub_dict = {int(key): val for key, val in hamiltonian_dict["qub"].items()}
165165

166-
subsystem_dims = {int(qubit): qub_dict[int(qubit)] for qubit in subsystem_list}
166+
subsystem_dims_dict = {int(qubit): qub_dict[int(qubit)] for qubit in subsystem_list}
167167

168168
# Parse the Hamiltonian
169169
system = _regex_parser(
170170
operator_str=hamiltonian_dict["h_str"],
171-
subsystem_dims=subsystem_dims,
171+
subsystem_dims_dict=subsystem_dims_dict,
172172
subsystem_list=subsystem_list,
173173
)
174174

@@ -227,7 +227,12 @@ def parse_backend_hamiltonian_dict(
227227
*sorted(zip(reduced_channels, hamiltonian_operators))
228228
)
229229

230-
return static_hamiltonian, list(hamiltonian_operators), list(reduced_channels), subsystem_dims
230+
return (
231+
static_hamiltonian,
232+
list(hamiltonian_operators),
233+
list(reduced_channels),
234+
subsystem_dims_dict,
235+
)
231236

232237

233238
def _hamiltonian_pre_parse_exceptions(hamiltonian_dict: dict):

qiskit_dynamics/backend/backend_string_parser/operator_from_string.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@
2626

2727

2828
def _operator_from_string(
29-
op_label: str, subsystem_label: int, subsystem_dims: Dict[int, int]
29+
op_label: str, subsystem_label: int, subsystem_dims_dict: Dict[int, int]
3030
) -> np.ndarray:
3131
r"""Generates a dense operator acting on a single subsystem, tensoring
3232
identities for remaining subsystems.
3333
3434
The single system operator is specified via a string in ``op_label``,
3535
the list of subsystems and their corresponding dimensions are specified in the
36-
dictionary ``subsystem_dims``, with system label being the keys specified as ``int``s,
36+
dictionary ``subsystem_dims_dict``, with system label being the keys specified as ``int``s,
3737
and system dimensions the values also specified as ``int``s, and ``subsystem_label``
3838
indicates which subsystem the operator specified by ``op_label`` acts on.
3939
@@ -61,7 +61,7 @@ def _operator_from_string(
6161
Args:
6262
op_label: The string labelling the single system operator.
6363
subsystem_label: Index of the subsystem to apply the operator.
64-
subsystem_dims: Dictionary of subsystem labels and dimensions.
64+
subsystem_dims_dict: Dictionary of subsystem labels and dimensions.
6565
6666
Returns:
6767
np.ndarray corresponding to the specified operator.
@@ -75,12 +75,12 @@ def _operator_from_string(
7575
if op_func is None:
7676
raise QiskitError(f"String {op_label} does not correspond to a known operator.")
7777

78-
dim = subsystem_dims[subsystem_label]
78+
dim = subsystem_dims_dict[subsystem_label]
7979
out = qi.Operator(op_func(dim), input_dims=[dim], output_dims=[dim])
8080

8181
# sort subsystem labels and dimensions according to subsystem label
8282
sorted_subsystem_keys, sorted_subsystem_dims = zip(
83-
*sorted(zip(subsystem_dims.keys(), subsystem_dims.values()))
83+
*sorted(zip(subsystem_dims_dict.keys(), subsystem_dims_dict.values()))
8484
)
8585

8686
# get subsystem location in ordered list

qiskit_dynamics/backend/backend_string_parser/regex_parser.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,20 @@
2929

3030

3131
def _regex_parser(
32-
operator_str: List[str], subsystem_dims: Dict[int, int], subsystem_list: List[int]
32+
operator_str: List[str], subsystem_dims_dict: Dict[int, int], subsystem_list: List[int]
3333
) -> List[Tuple[np.array, str]]:
3434
"""Function wrapper for regex parsing object.
3535
3636
Args:
3737
operator_str: List of strings in accepted format as described in
3838
string_model_parser.parse_hamiltonian_dict.
39-
subsystem_dims: Dictionary mapping subsystem labels to dimensions.
39+
subsystem_dims_dict: Dictionary mapping subsystem labels to dimensions.
4040
subsystem_list: List of subsystems on which the operators are to be constructed.
4141
Returns:
4242
List of tuples containing pairs operators and their string coefficients.
4343
"""
4444

45-
return _HamiltonianParser(h_str=operator_str, subsystem_dims=subsystem_dims).parse(
45+
return _HamiltonianParser(h_str=operator_str, subsystem_dims_dict=subsystem_dims_dict).parse(
4646
subsystem_list
4747
)
4848

@@ -66,15 +66,17 @@ class _HamiltonianParser:
6666
BrkR=re.compile(r"\)"),
6767
)
6868

69-
def __init__(self, h_str, subsystem_dims):
69+
def __init__(self, h_str, subsystem_dims_dict):
7070
"""Create new quantum operator generator
7171
7272
Parameters:
7373
h_str (list): list of Hamiltonian string
74-
subsystem_dims (dict): dimension of subsystems
74+
subsystem_dims_dict (dict): dimension of subsystems
7575
"""
7676
self.h_str = h_str
77-
self.subsystem_dims = {int(label): int(dim) for label, dim in subsystem_dims.items()}
77+
self.subsystem_dims_dict = {
78+
int(label): int(dim) for label, dim in subsystem_dims_dict.items()
79+
}
7880
self.str2qopr = {}
7981

8082
def parse(self, qubit_list=None):
@@ -194,15 +196,15 @@ def _tokenizer(self, op_str, qubit_list=None):
194196
if qubit_list is not None and idx not in qubit_list:
195197
return 0, None
196198
name = p.group("opr")
197-
opr = _operator_from_string(name, idx, self.subsystem_dims)
199+
opr = _operator_from_string(name, idx, self.subsystem_dims_dict)
198200
self.str2qopr[p.group()] = opr
199201
elif key == "PrjOpr":
200202
_key = key
201203
_name = p.group()
202204
if p.group() not in self.str2qopr:
203205
idx = int(p.group("idx"))
204206
name = "P"
205-
opr = _operator_from_string(name, idx, self.subsystem_dims)
207+
opr = _operator_from_string(name, idx, self.subsystem_dims_dict)
206208
self.str2qopr[p.group()] = opr
207209
elif key in ["Func", "Ext"]:
208210
_name = p.group("name")

qiskit_dynamics/backend/backend_utils.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,21 +146,31 @@ def _get_memory_slot_probabilities(
146146

147147

148148
def _sample_probability_dict(
149-
probability_dict: Dict, shots: int, seed: Optional[int] = None
149+
probability_dict: Dict,
150+
shots: int,
151+
normalize_probabilities: bool = True,
152+
seed: Optional[int] = None,
150153
) -> List[str]:
151154
"""Sample outcomes based on probability dictionary.
152155
153156
Args:
154157
probability_dict: Dictionary representing probability distribution, with keys being
155158
outcomes, values being probabilities.
156159
shots: Number of shots.
160+
normalize_probabilities: Whether or not to normalize the probabilities to sum to 1 before
161+
sampling.
157162
seed: Seed to use in rng construction.
158163
159164
Return:
160165
List: of entries of probability_dict, sampled according to the probabilities.
161166
"""
162167
rng = np.random.default_rng(seed=seed)
163168
alphabet, probs = zip(*probability_dict.items())
169+
170+
if normalize_probabilities:
171+
probs = np.array(probs)
172+
probs = probs / probs.sum()
173+
164174
return rng.choice(alphabet, size=shots, replace=True, p=probs)
165175

166176

0 commit comments

Comments
 (0)