1458 lines
143 KiB
Plaintext
1458 lines
143 KiB
Plaintext
---
|
||
title: Qiskit 0.33 release notes
|
||
description: Changes made in Qiskit 0.33
|
||
in_page_toc_max_heading_level: 4
|
||
---
|
||
|
||
# Qiskit 0.33 release notes
|
||
|
||
## 0.33.1
|
||
|
||
<span id="release-notes-0-19-1-terra" />
|
||
|
||
<span id="id172" />
|
||
|
||
### Terra 0.19.1
|
||
|
||
<span id="release-notes-0-19-1-terra-prelude" />
|
||
|
||
<span id="id173" />
|
||
|
||
#### Prelude
|
||
|
||
Qiskit Terra 0.19.1 is a bugfix release, solving some issues in 0.19.0 concerning circuits constructed by the control-flow builder interface, conditional gates and QPY serialisation of newer Terra objects.
|
||
|
||
<span id="release-notes-0-19-1-terra-deprecation-notes" />
|
||
|
||
<span id="id174" />
|
||
|
||
#### Deprecation Notes
|
||
|
||
* The loose functions `qiskit.circuit.measure.measure()` and `qiskit.circuit.reset.reset()` are deprecated, and will be removed in a future release. Instead, you should access these as methods on [`QuantumCircuit`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit"):
|
||
|
||
```python
|
||
from qiskit import QuantumCircuit
|
||
circuit = QuantumCircuit(1, 1)
|
||
|
||
# Replace this deprecated form ...
|
||
from qiskit.circuit.measure import measure
|
||
measure(circuit, 0, 0)
|
||
|
||
# ... with either of the next two lines:
|
||
circuit.measure(0, 0)
|
||
QuantumCircuit.measure(circuit, 0, 0)
|
||
```
|
||
|
||
<span id="release-notes-0-19-1-terra-bug-fixes" />
|
||
|
||
<span id="id175" />
|
||
|
||
#### Bug Fixes
|
||
|
||
* Fixed an error in the circuit conversion functions [`circuit_to_gate()`](/api/qiskit/0.45/converters#qiskit.converters.circuit_to_gate "qiskit.converters.circuit_to_gate") and [`circuit_to_instruction()`](/api/qiskit/0.45/converters#qiskit.converters.circuit_to_instruction "qiskit.converters.circuit_to_instruction") (and their associated circuit methods [`QuantumCircuit.to_gate()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#to_gate "qiskit.circuit.QuantumCircuit.to_gate") and [`QuantumCircuit.to_instruction()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#to_instruction "qiskit.circuit.QuantumCircuit.to_instruction")) when acting on a circuit with registerless bits, or bits in more than one register. Previously, the number of bits necessary for the created gate or instruction would be calculated incorrectly, often causing an exception during the conversion.
|
||
|
||
* Fixed an issue where calling [`QuantumCircuit.copy()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#copy "qiskit.circuit.QuantumCircuit.copy") on the “body” circuits of a control-flow operation created with the builder interface would raise an error. For example, this was previously an error, but will now return successfully:
|
||
|
||
```python
|
||
from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
|
||
|
||
qreg = QuantumRegister(4)
|
||
creg = ClassicalRegister(1)
|
||
circ = QuantumCircuit(qreg, creg)
|
||
|
||
with circ.if_test((creg, 0)):
|
||
circ.h(0)
|
||
|
||
if_else_instruction, _, _ = circ.data[0]
|
||
true_body = if_else_instruction.params[0]
|
||
true_body.copy()
|
||
```
|
||
|
||
* The control-flow builder interface now supports using [`ClassicalRegister`](/api/qiskit/0.45/qiskit.circuit.ClassicalRegister "qiskit.circuit.ClassicalRegister")s as conditions in nested control-flow scopes. Previously, doing this would not raise an error immediately, but the internal circuit blocks would not have the correct registers defined, and so later logic that worked with the inner blocks would fail.
|
||
|
||
For example, previously the drawers would fail when trying to draw an inner block conditioned on a classical register, whereas now it will succeed, such as in this example:
|
||
|
||
```python
|
||
from qiskit import QuantumCircuit
|
||
from qiskit.circuit import QuantumRegister, ClassicalRegister
|
||
|
||
qreg = QuantumRegister(4)
|
||
creg = ClassicalRegister(1)
|
||
circ = QuantumCircuit(qreg, creg)
|
||
|
||
with circ.for_loop(range(10)) as a:
|
||
circ.ry(a, 0)
|
||
with circ.if_test((creg, 1)):
|
||
circ.break_loop()
|
||
|
||
print(circ.draw(cregbundle=False))
|
||
print(circ.data[0][0].blocks[0].draw(cregbundle=False))
|
||
```
|
||
|
||
* Fixed `qpy_serialization` support for serializing [`QuantumCircuit`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") objects that are using [`ParameterVector`](/api/qiskit/0.45/qiskit.circuit.ParameterVector "qiskit.circuit.ParameterVector") or `ParameterVectorElement` as parameters. Previously, a `ParameterVectorElement` parameter was just treated as a [`Parameter`](/api/qiskit/0.45/qiskit.circuit.Parameter "qiskit.circuit.Parameter") for QPY serialization which meant the [`ParameterVector`](/api/qiskit/0.45/qiskit.circuit.ParameterVector "qiskit.circuit.ParameterVector") context was lost in QPY and the output order of [`parameters`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#parameters "qiskit.circuit.QuantumCircuit.parameters") could be incorrect.
|
||
|
||
To fix this issue a new QPY format version, [Version 3](/api/qiskit/0.45/qpy#qpy-version-3), was required. This new format version includes a representation of the `ParameterVectorElement` class which is described in the `qpy_serialization` documentation at [PARAMETER\_VECTOR\_ELEMENT](/api/qiskit/0.45/qpy#qpy-param-vector).
|
||
|
||
* Fixed the `qpy_serialization` support for serializing a [`PauliEvolutionGate`](/api/qiskit/0.45/qiskit.circuit.library.PauliEvolutionGate "qiskit.circuit.library.PauliEvolutionGate") object. Previously, the [`PauliEvolutionGate`](/api/qiskit/0.45/qiskit.circuit.library.PauliEvolutionGate "qiskit.circuit.library.PauliEvolutionGate") was treated as a custom gate for serialization and would be deserialized as a [`Gate`](/api/qiskit/0.45/qiskit.circuit.Gate "qiskit.circuit.Gate") object that had the same definition and name as the original [`PauliEvolutionGate`](/api/qiskit/0.45/qiskit.circuit.library.PauliEvolutionGate "qiskit.circuit.library.PauliEvolutionGate"). However, this would lose the original state from the [`PauliEvolutionGate`](/api/qiskit/0.45/qiskit.circuit.library.PauliEvolutionGate "qiskit.circuit.library.PauliEvolutionGate"). This has been fixed so that starting in this release a [`PauliEvolutionGate`](/api/qiskit/0.45/qiskit.circuit.library.PauliEvolutionGate "qiskit.circuit.library.PauliEvolutionGate") in the circuit will be preserved 1:1 across QPY serialization now. The only limitation with this is that it does not support custom [`EvolutionSynthesis`](/api/qiskit/0.45/qiskit.synthesis.EvolutionSynthesis "qiskit.synthesis.EvolutionSynthesis") classes. Only the classes available from [`qiskit.synthesis`](/api/qiskit/0.45/synthesis#module-qiskit.synthesis "qiskit.synthesis") can be used with a [`PauliEvolutionGate`](/api/qiskit/0.45/qiskit.circuit.library.PauliEvolutionGate "qiskit.circuit.library.PauliEvolutionGate") for qpy serialization.
|
||
|
||
To fix this issue a new QPY format version, [Version 3](/api/qiskit/0.45/qpy#qpy-version-3), was required. This new format version includes a representation of the [`PauliEvolutionGate`](/api/qiskit/0.45/qiskit.circuit.library.PauliEvolutionGate "qiskit.circuit.library.PauliEvolutionGate") class which is described in the `qpy_serialization` documentation at [PAULI\_EVOLUTION](/api/qiskit/0.45/qpy#pauli-evo-qpy).
|
||
|
||
* Two loose functions `qiskit.circuit.measure.measure()` and `qiskit.circuit.reset.reset()` were accidentally removed without a deprecation period. They have been reinstated, but are marked as deprecated in favour of the methods [`QuantumCircuit.measure()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#measure "qiskit.circuit.QuantumCircuit.measure") and [`QuantumCircuit.reset()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#reset "qiskit.circuit.QuantumCircuit.reset"), respectively, and will be removed in a future release.
|
||
|
||
<span id="release-notes-0-19-1-terra-other-notes" />
|
||
|
||
<span id="id176" />
|
||
|
||
#### Other Notes
|
||
|
||
* The new control-flow builder interface uses various context managers and helper objects to do its work. These should not be considered part of the public API, and are liable to be changed and removed without warning. The *usage* of the builder interface has stability guarantees, in the sense that the behaviour described by [`QuantumCircuit.for_loop()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#for_loop "qiskit.circuit.QuantumCircuit.for_loop"), [`while_loop()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#while_loop "qiskit.circuit.QuantumCircuit.while_loop") and [`if_test()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#if_test "qiskit.circuit.QuantumCircuit.if_test") for the builder interface are subject to the standard deprecation policies, but the actual objects used to effect this are not. You should not rely on the objects (such as `IfContext` or `ControlFlowBuilderBlock`) existing in their current locations, or having any methods or attributes attached to them.
|
||
|
||
This was not previously clear in the 0.19.0 release. All such objects now have a warning in their documentation strings making this explicit. It is likely in the future that their locations and backing implementations will become quite different.
|
||
|
||
<span id="aer-0-9-1" />
|
||
|
||
### Aer 0.9.1
|
||
|
||
No change
|
||
|
||
<span id="id177" />
|
||
|
||
### Ignis 0.7.0
|
||
|
||
No change
|
||
|
||
<span id="ibm-q-provider-0-18-2" />
|
||
|
||
<span id="release-notes-0-18-2-ibmq" />
|
||
|
||
### IBM Q Provider 0.18.2
|
||
|
||
<span id="release-notes-0-18-2-ibmq-bug-fixes" />
|
||
|
||
<span id="id178" />
|
||
|
||
#### Bug Fixes
|
||
|
||
* Fix delivered in [#1065](https://github.com/Qiskit/qiskit-ibmq-provider/pull/1065) for the issue where job kept crashing when `Parameter` was passed in circuit metadata.
|
||
* Fix delivered in [#1094](https://github.com/Qiskit/qiskit-ibmq-provider/pull/1094) for the issue wherein `qiskit.providers.ibmq.runtime.RuntimeEncoder` does an extra decompose() if the circuit being serialized is a `BlueprintCircuit`.
|
||
|
||
<span id="qiskit-0-33-0" />
|
||
|
||
## 0.33.0
|
||
|
||
This release officially marks the end of support for the Qiskit Aqua project in Qiskit. It was originally deprecated in the 0.25.0 release and as was documented in that release the `qiskit-aqua` package has been removed from the Qiskit metapackage, which means `pip install qiskit` will no longer include `qiskit-aqua`. However, because of limitations in python packaging we cannot automatically remove a pre-existing install of `qiskit-aqua` when upgrading a previous version of Qiskit to this release (or a future release) with `pip install -U qiskit`. If you are upgrading from a previous version it’s recommended that you manually uninstall Qiskit Aqua with `pip uninstall qiskit-aqua` or install in a fresh python environment.
|
||
|
||
The application modules that were provided by `qiskit-aqua` have been split into several new packages: `qiskit-optimization`, `qiskit-nature`, `qiskit-machine-learning`, and `qiskit-finance`. These packages can be installed by themselves (via the standard pip install command, e.g. `pip install qiskit-nature`) or with the rest of the Qiskit metapackage as optional extras (e.g. `pip install 'qiskit[finance,optimization]'` or `pip install 'qiskit[all]'`). The core algorithms and the operator flow now exist as part of Qiskit Terra at `qiskit.algorithms` and `qiskit.opflow`. Depending on your existing usage of Aqua you should either use the application packages or the new modules in Qiskit Terra. For more details on how to migrate from Qiskit Aqua you can refer to the [Aqua Migration Guide](https://github.com/qiskit-community/qiskit-aqua/blob/main/docs/tutorials/Qiskit%20Algorithms%20Migration%20Guide.ipynb).
|
||
|
||
This release also officially deprecates the Qiskit Ignis project. Accordingly, in a future release the `qiskit-ignis` package will be removed from the Qiskit metapackage, which means in that future release `pip install qiskit` will no longer include `qiskit-ignis`. Qiskit Ignis has been supersceded by the [Qiskit Experiments](https://qiskit.org/documentation/experiments/) project and active development has ceased. While deprecated, critical bug fixes and compatibility fixes will continue to be made to provide users a sufficient opportunity to migrate off of Ignis. After the deprecation period (which will be no shorter than 3 months from this release) the project will be retired and archived. You can refer to the [migration guide](https://github.com/qiskit-community/qiskit-ignis#migration-guide) for details on how to switch from Qiskit Ignis to Qiskit Experiments.
|
||
|
||
<span id="terra-0-19-0" />
|
||
|
||
<span id="release-notes-0-19-0" />
|
||
|
||
### Terra 0.19.0
|
||
|
||
<span id="release-notes-0-19-0-prelude" />
|
||
|
||
<span id="id179" />
|
||
|
||
#### Prelude
|
||
|
||
The Qiskit Terra 0.19 release highlights are:
|
||
|
||
* A new version of the abstract Qiskit/hardware interface, in the form of [`BackendV2`](/api/qiskit/0.45/qiskit.providers.BackendV2 "qiskit.providers.BackendV2"), which comes with a new data structure [`Target`](/api/qiskit/0.45/qiskit.transpiler.Target "qiskit.transpiler.Target") to allow backends to better model their constraints for the [transpiler](/api/qiskit/0.45/transpiler#qiskit-transpiler).
|
||
* An [extensible plugin interface](/api/qiskit/0.45/transpiler_plugins#qiskit-transpiler-plugins) to the [`UnitarySynthesis`](/api/qiskit/0.45/qiskit.transpiler.passes.UnitarySynthesis "qiskit.transpiler.passes.UnitarySynthesis") transpiler pass, allowing users or other packages to extend Qiskit Terra’s synthesis routines with new methods.
|
||
* Control-flow instructions, for representing `for` and `while` loops and `if`/`else` statements in [`QuantumCircuit`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit"). The simulators in Qiskit Aer will soon be able to work with these new instructions, allowing you to write more dynamic quantum programs.
|
||
* Preliminary support for the evolving [OpenQASM 3 specification](https://openqasm.com/). You can use the new [`qiskit.qasm3`](/api/qiskit/0.45/qasm3#module-qiskit.qasm3 "qiskit.qasm3") module to serialize your [`QuantumCircuit`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit")s into OpenQASM 3, including the new control-flow constructs.
|
||
|
||
This release marks the end of support for Python 3.6 in Qiskit. This release of Qiskit Terra, and any subsequent bugfix releases in the 0.19.x series, will be the last to work with Python 3.6. Starting from the next minor release (0.20.0) of Qiskit Terra, the minimum required Python version will be 3.7.
|
||
|
||
As always, there are many more features and fixes in this release as well, which you can read about below.
|
||
|
||
<span id="release-notes-0-19-0-new-features" />
|
||
|
||
<span id="id180" />
|
||
|
||
#### New Features
|
||
|
||
* [`QuantumCircuit.decompose()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#decompose "qiskit.circuit.QuantumCircuit.decompose") and its corresponding transpiler pass [`Decompose`](/api/qiskit/0.45/qiskit.transpiler.passes.Decompose "qiskit.transpiler.passes.Decompose") now optionally accept a parameter containing a collection of gate names. If this parameter is given, then only gates with matching names will be decomposed. This supports Unix-shell-style wildcard matches. For example:
|
||
|
||
```python
|
||
qc.decompose(["h", "r[xz]"])
|
||
```
|
||
|
||
will decompose any `h`, `rx` or `rz` gates, but leave (for example) `x` gates untouched.
|
||
|
||
* Added the `termination_checker` argument to the [`SPSA`](/api/qiskit/0.45/qiskit.algorithms.optimizers.SPSA "qiskit.algorithms.optimizers.SPSA") optimizer. This allows the user to implement a custom termination criterion.
|
||
|
||
```python
|
||
import numpy as np
|
||
from qiskit.algorithms.optimizers import SPSA
|
||
|
||
def objective(x):
|
||
return np.linalg.norm(x) + .04*np.random.rand(1)
|
||
|
||
class TerminationChecker:
|
||
|
||
def __init__(self, N : int):
|
||
"""
|
||
Callback to terminate optimization when the average decrease over
|
||
the last N data points is smaller than the specified tolerance.
|
||
"""
|
||
self.N = N
|
||
self.values = []
|
||
|
||
def __call__(self, nfev, parameters, value, stepsize, accepted) -> bool:
|
||
"""
|
||
Returns:
|
||
True if the optimization loop should be terminated.
|
||
"""
|
||
self.values.append(value)
|
||
|
||
if len(self.values) > self.N:
|
||
last_values = self.values[-self.N:]
|
||
pp = np.polyfit(range(self.N), last_values, 1)
|
||
slope = pp[0] / self.N
|
||
|
||
if slope > 0:
|
||
return True
|
||
return False
|
||
|
||
maxiter = 400
|
||
spsa = SPSA(maxiter=maxiter, termination_checker=TerminationChecker(10))
|
||
parameters, value, niter = spsa.optimize(2, objective, initial_point=np.array([0.5, 0.5]))
|
||
```
|
||
|
||
* Added a new version of the [`Backend`](/api/qiskit/0.45/qiskit.providers.Backend "qiskit.providers.Backend") interface, [`BackendV2`](/api/qiskit/0.45/qiskit.providers.BackendV2 "qiskit.providers.BackendV2"). This new version is a large change from the previous version, [`BackendV1`](/api/qiskit/0.45/qiskit.providers.BackendV1 "qiskit.providers.BackendV1") and changes both the user access pattern for properties of the backend (like number of qubits, etc) and how the backend represents its constraints to the transpiler. The execution of circuits (via the [`run()`](/api/qiskit/0.45/qiskit.providers.BackendV2#run "qiskit.providers.BackendV2.run") method) remains unchanged. With a [`BackendV2`](/api/qiskit/0.45/qiskit.providers.BackendV2 "qiskit.providers.BackendV2") backend instead of having a separate [`configuration()`](/api/qiskit/0.45/qiskit.providers.BackendV1#configuration "qiskit.providers.BackendV1.configuration"), [`properties()`](/api/qiskit/0.45/qiskit.providers.BackendV1#properties "qiskit.providers.BackendV1.properties"), and `defaults()` methods that construct [`BackendConfiguration`](/api/qiskit/0.45/qiskit.providers.models.BackendConfiguration "qiskit.providers.models.BackendConfiguration"), [`BackendProperties`](/api/qiskit/0.45/qiskit.providers.models.BackendProperties "qiskit.providers.models.BackendProperties"), and [`PulseDefaults`](/api/qiskit/0.45/qiskit.providers.models.PulseDefaults "qiskit.providers.models.PulseDefaults") objects respectively, like in the [`BackendV1`](/api/qiskit/0.45/qiskit.providers.BackendV1 "qiskit.providers.BackendV1") interface, the attributes contained in those output objects are accessible directly as attributes of the [`BackendV2`](/api/qiskit/0.45/qiskit.providers.BackendV2 "qiskit.providers.BackendV2") object. For example, to get the number of qubits for a backend with [`BackendV1`](/api/qiskit/0.45/qiskit.providers.BackendV1 "qiskit.providers.BackendV1") you would do:
|
||
|
||
```python
|
||
num_qubits = backend.configuration().n_qubits
|
||
```
|
||
|
||
while with [`BackendV2`](/api/qiskit/0.45/qiskit.providers.BackendV2 "qiskit.providers.BackendV2") it is:
|
||
|
||
```python
|
||
num_qubits = backend.num_qubits
|
||
```
|
||
|
||
The other change around this is that the number of attributes exposed in the abstract [`BackendV2`](/api/qiskit/0.45/qiskit.providers.BackendV2 "qiskit.providers.BackendV2") class is designed to be a hardware/vendor agnostic set of the required or optional fields that the rest of Qiskit can use today with any backend. Subclasses of the abstract [`BackendV2`](/api/qiskit/0.45/qiskit.providers.BackendV2 "qiskit.providers.BackendV2") class can add support for additional attributes and methods beyond those defined in [`BackendV2`](/api/qiskit/0.45/qiskit.providers.BackendV2 "qiskit.providers.BackendV2"), but these will not be supported universally throughout Qiskit.
|
||
|
||
The other critical change that is primarily important for provider authors is how a [`BackendV2`](/api/qiskit/0.45/qiskit.providers.BackendV2 "qiskit.providers.BackendV2") exposes the properties of a particular backend to the transpiler. With [`BackendV2`](/api/qiskit/0.45/qiskit.providers.BackendV2 "qiskit.providers.BackendV2") this is done via a [`Target`](/api/qiskit/0.45/qiskit.transpiler.Target "qiskit.transpiler.Target") object. The [`Target`](/api/qiskit/0.45/qiskit.transpiler.Target "qiskit.transpiler.Target"), which is exposed via the [`target`](/api/qiskit/0.45/qiskit.providers.BackendV2#target "qiskit.providers.BackendV2.target") attribute, is used to represent the set of constraints for running circuits on a particular backend. It contains the subset of information previously exposed by the [`BackendConfiguration`](/api/qiskit/0.45/qiskit.providers.models.BackendConfiguration "qiskit.providers.models.BackendConfiguration"), [`BackendProperties`](/api/qiskit/0.45/qiskit.providers.models.BackendProperties "qiskit.providers.models.BackendProperties"), and [`PulseDefaults`](/api/qiskit/0.45/qiskit.providers.models.PulseDefaults "qiskit.providers.models.PulseDefaults") classes which the transpiler can actively use. When migrating a provider to use [`BackendV2`](/api/qiskit/0.45/qiskit.providers.BackendV2 "qiskit.providers.BackendV2") (or when creating a new provider package) the construction of backend objects will primarily be around creating a [`Target`](/api/qiskit/0.45/qiskit.transpiler.Target "qiskit.transpiler.Target") object for the backend.
|
||
|
||
* Added a new [`Target`](/api/qiskit/0.45/qiskit.transpiler.Target "qiskit.transpiler.Target") class to the [`transpiler`](/api/qiskit/0.45/transpiler#module-qiskit.transpiler "qiskit.transpiler") module. The [`Target`](/api/qiskit/0.45/qiskit.transpiler.Target "qiskit.transpiler.Target") class is designed to represent the constraints of backend to the compiler. The [`Target`](/api/qiskit/0.45/qiskit.transpiler.Target "qiskit.transpiler.Target") class is intended to be used with a [`BackendV2`](/api/qiskit/0.45/qiskit.providers.BackendV2 "qiskit.providers.BackendV2") backend and is how backends will model their constraints for the transpiler moving forward. It combines the previously distinct fields used for controlling the [`transpile()`](/api/qiskit/0.45/compiler#qiskit.compiler.transpile "qiskit.compiler.transpile") target device (e.g. `basis_gates`, `coupling_map`, `instruction_durations`, etc) into a single data structure. It also adds additional functionality on top of what was available previously such as representing heterogeneous gate sets, multi-qubit gate connectivity, and tuned variants of the same gates. Currently the transpiler doesn’t factor in all these constraints, but over time it will grow to leverage the extra functionality.
|
||
|
||
* The [`Options`](/api/qiskit/0.45/qiskit.providers.Options "qiskit.providers.Options") class now has optional support for specifying validators. This enables [`Backend`](/api/qiskit/0.45/qiskit.providers.Backend "qiskit.providers.Backend") authors to optionally specify basic validation on the user supplied values for fields in the [`Options`](/api/qiskit/0.45/qiskit.providers.Options "qiskit.providers.Options") object. For example, if you had an [`Options`](/api/qiskit/0.45/qiskit.providers.Options "qiskit.providers.Options") object defined with:
|
||
|
||
```python
|
||
from qiskit.providers.Options
|
||
options = Options(shots=1024)
|
||
```
|
||
|
||
you can set a validator on shots for it to be between 1 and 4096 with:
|
||
|
||
```python
|
||
options.set_validator('shots', (1, 4096))
|
||
```
|
||
|
||
With the validator set any call to the [`update_options()`](/api/qiskit/0.45/qiskit.providers.Options#update_options "qiskit.providers.Options.update_options") method will check that if `shots` is being updated the proposed new value is within the valid range.
|
||
|
||
* Added a new transpiler analysis pass, [`ContainsInstruction`](/api/qiskit/0.45/qiskit.transpiler.passes.ContainsInstruction "qiskit.transpiler.passes.ContainsInstruction"), to the [`qiskit.transpiler.passes`](/api/qiskit/0.45/transpiler_passes#module-qiskit.transpiler.passes "qiskit.transpiler.passes") module. This pass is used to determine if a circuit contains a specific instruction. It takes in a single parameter at initialization, the name of the instruction to check for and set a boolean in the property set whether the circuit contains that instruction or not. For example:
|
||
|
||
```python
|
||
from qiskit.transpiler.passes import ContainsInstruction
|
||
from qiskit.circuit import QuantumCircuit
|
||
|
||
circuit = QuantumCircuit(2)
|
||
circuit.h(0)
|
||
circuit.cx(0, 1)
|
||
circuit.measure_all()
|
||
|
||
property_set = {}
|
||
# Contains Hadamard
|
||
contains_h = ContainsInstruction("h")
|
||
contains_h(circuit, property_set)
|
||
assert property_set["contains_h"] == True
|
||
# Not contains SX
|
||
contains_sx = ContainsInstruction("sx")
|
||
contains_sx(circuit, property_set)
|
||
assert property_set["contains_sx"] == False
|
||
```
|
||
|
||
* Added a utility function [`qiskit.utils.detach_prefix()`](/api/qiskit/0.45/utils#qiskit.utils.detach_prefix "qiskit.utils.detach_prefix") that is a counterpart of [`apply_prefix()`](/api/qiskit/0.45/utils#qiskit.utils.apply_prefix "qiskit.utils.apply_prefix"). The new function returns a tuple of scaled value and prefix from a given float value. For example, a value `1.3e8` will be converted into `(130, "M")` that can be used to display a value in the user friendly format, such as `130 MHz`.
|
||
|
||
* The values `"gate_error"` and `"balanced"` are now available for the `objective` option in the construction of the `BIPMapping` object, and `"balanced"` is now the default.
|
||
|
||
The `"gate_error"` objective requires passing a [`BackendProperties`](/api/qiskit/0.45/qiskit.providers.models.BackendProperties "qiskit.providers.models.BackendProperties") instance in the `backend_prop` kwarg, which contains the 2q-gate gate errors used in the computation of the objectives. The `"balanced"` objective will use the [`BackendProperties`](/api/qiskit/0.45/qiskit.providers.models.BackendProperties "qiskit.providers.models.BackendProperties") instance if it is given, but otherwise will assume a CX error rate as given in the new parameter `default_cx_error_rate`. The relative weights of the gate-error and depth components of the balanced objective can be controlled with the new `depth_obj_weight` parameter.
|
||
|
||
* Every attribute of the [`VQE`](/api/qiskit/0.45/qiskit.algorithms.VQE "qiskit.algorithms.VQE") class that is set at the initialization is now accessible with getters and setters. Further, the default values of the VQE attributes `ansatz` and `optimizer` can be reset by assigning `None` to them:
|
||
|
||
```python
|
||
vqe = VQE(my_ansatz, my_optimizer)
|
||
vqe.ansatz = None # reset to default: RealAmplitudes ansatz
|
||
vqe.optimizer = None # reset to default: SLSQP optimizer
|
||
```
|
||
|
||
* Added a new method [`PauliList.group_qubit_wise_commuting()`](/api/qiskit/0.45/qiskit.quantum_info.PauliList#group_qubit_wise_commuting "qiskit.quantum_info.PauliList.group_qubit_wise_commuting") that partitions a [`PauliList`](/api/qiskit/0.45/qiskit.quantum_info.PauliList "qiskit.quantum_info.PauliList") into sets of mutually qubit-wise commuting [`Pauli`](/api/qiskit/0.45/qiskit.quantum_info.Pauli "qiskit.quantum_info.Pauli") operators. For example:
|
||
|
||
```python
|
||
from qiskit.quantum_info import PauliList, Pauli
|
||
pauli_list = PauliList([Pauli("IY"), Pauli("XX"), Pauli("YY"), Pauli("YX")])
|
||
pauli_list.group_qubit_wise_commuting()
|
||
```
|
||
|
||
* Added a new coupling-map constructor method [`CouplingMap.from_hexagonal_lattice()`](/api/qiskit/0.45/qiskit.transpiler.CouplingMap#from_hexagonal_lattice "qiskit.transpiler.CouplingMap.from_hexagonal_lattice") for constructing a hexagonal lattice coupling map. For example, to construct a 2x2 hexagonal lattice coupling map:
|
||
|
||
```python
|
||
from qiskit.transpiler import CouplingMap
|
||
cmap = CouplingMap.from_hexagonal_lattice(2, 2)
|
||
cmap.draw()
|
||
```
|
||
|
||
* New fake backend classes are available under `qiskit.test.mock`. These include mocked versions of `ibmq_brooklyn`, `ibmq_manila`, `ibmq_jakarta`, and `ibmq_lagos`. As with the other fake backends, these include snapshots of calibration data (i.e. `backend.defaults()`) and error data (i.e. `backend.properties()`) taken from the real system, and can be used for local testing, compilation and simulation.
|
||
|
||
* Added the [`OperatorBase.is_hermitian()`](/api/qiskit/0.45/qiskit.opflow.OperatorBase#is_hermitian "qiskit.opflow.OperatorBase.is_hermitian") method to check whether the operator is Hermitian or not. [`NumPyEigensolver`](/api/qiskit/0.45/qiskit.algorithms.NumPyEigensolver "qiskit.algorithms.NumPyEigensolver") and [`NumPyMinimumEigensolver`](/api/qiskit/0.45/qiskit.algorithms.NumPyMinimumEigensolver "qiskit.algorithms.NumPyMinimumEigensolver") use `eigh` or `eigsh` to solve the eigenvalue problem when the operator is Hermitian.
|
||
|
||
* Added a new constructor method [`PassManagerConfig.from_backend()`](/api/qiskit/0.45/qiskit.transpiler.PassManagerConfig#from_backend "qiskit.transpiler.PassManagerConfig.from_backend"). It constructs a [`PassManagerConfig`](/api/qiskit/0.45/qiskit.transpiler.PassManagerConfig "qiskit.transpiler.PassManagerConfig") object with user options and the configuration of a backend. With this feature, a preset passmanager can be built easier. For example:
|
||
|
||
```python
|
||
from qiskit.transpiler.passmanager_config import PassManagerConfig
|
||
from qiskit.transpiler.preset_passmanagers import level_1_pass_manager
|
||
from qiskit.test.mock import FakeMelbourne
|
||
|
||
pass_manager = level_1_pass_manager(
|
||
PassManagerConfig.from_backend(FakeMelbourne(), seed_transpiler=42)
|
||
)
|
||
```
|
||
|
||
* A new transpiler pass, [`PulseGates`](/api/qiskit/0.45/qiskit.transpiler.passes.PulseGates "qiskit.transpiler.passes.PulseGates"), was added, which automatically extracts user-provided calibrations from the instruction schedule map and attaches the gate schedule to the given (transpiled) quantum circuit as a pulse gate.
|
||
|
||
The [`PulseGates`](/api/qiskit/0.45/qiskit.transpiler.passes.PulseGates "qiskit.transpiler.passes.PulseGates") transpiler pass is applied to all optimization levels from 0 to 3. No gate implementation is updated unless the end-user explicitly overrides the `backend.defaults().instruction_schedule_map`. This pass saves users from individually calling [`QuantumCircuit.add_calibration()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#add_calibration "qiskit.circuit.QuantumCircuit.add_calibration") for every circuit run on the hardware.
|
||
|
||
To supplement this new pass, a schedule was added to [`InstructionScheduleMap`](/api/qiskit/0.45/qiskit.pulse.InstructionScheduleMap "qiskit.pulse.InstructionScheduleMap") and is implicitly updated with a metadata field `"publisher"`. Backend-calibrated gate schedules have a special publisher kind to avoid overriding circuits with calibrations of already known schedules. Usually, end-users don’t need to take care of this metadata as it is applied automatically. You can call [`InstructionScheduleMap.has_custom_gate()`](/api/qiskit/0.45/qiskit.pulse.InstructionScheduleMap#has_custom_gate "qiskit.pulse.InstructionScheduleMap.has_custom_gate") to check if the map has custom gate calibration.
|
||
|
||
See the below code example to learn how to apply custom gate implementation for all circuits under execution.
|
||
|
||
```python
|
||
from qiskit.test.mock import FakeGuadalupe
|
||
from qiskit import pulse, circuit, transpile
|
||
|
||
backend = FakeGuadalupe()
|
||
|
||
with pulse.build(backend, name="x") as x_q0:
|
||
pulse.play(pulse.Constant(160, 0.1), pulse.drive_channel(0))
|
||
|
||
backend.defaults().instruction_schedule_map.add("x", (0,), x_q0)
|
||
|
||
circs = []
|
||
for _ in range(100):
|
||
circ = circuit.QuantumCircuit(1)
|
||
circ.sx(0)
|
||
circ.rz(1.57, 0)
|
||
circ.x(0)
|
||
circ.measure_active()
|
||
circs.append(circ)
|
||
|
||
circs = transpile(circs, backend)
|
||
circs[0].calibrations # This returns calibration only for x gate
|
||
```
|
||
|
||
Note that the instruction schedule map is a mutable object. If you override one of the entries and use that backend for other experiments, you may accidentally update the gate definition.
|
||
|
||
```python
|
||
backend = FakeGuadalupe()
|
||
|
||
instmap = backend.defaults().instruction_schedule_map
|
||
instmap.add("x", (0, ), my_x_gate_schedule)
|
||
|
||
qc = QuantumCircuit(1, 1)
|
||
qc.x(0)
|
||
qc.measure(0, 0)
|
||
|
||
qc = transpile(qc, backend) # This backend uses custom X gate
|
||
```
|
||
|
||
If you want to update the gate definitions of a specific experiment, you need to first deepcopy the instruction schedule map and directly pass it to the transpiler.
|
||
|
||
* Introduced a new option `qubit_subset` to the constructor of `BIPMapping`. The option enables us to specify physical qubits to be used (in `coupling_map` of the device) during the mapping in one line:
|
||
|
||
```python
|
||
mapped_circ = BIPMapping(
|
||
coupling_map=CouplingMap([[0, 1], [1, 2], [1, 3], [3, 4]]),
|
||
qubit_subset=[1, 3, 4]
|
||
)(circ)
|
||
```
|
||
|
||
Previously, to do the same thing, we had to supply a reduced `coupling_map` which contains only the qubits to be used, embed the resulting circuit onto the original `coupling_map` and update the `QuantumCircuit._layout` accordingly:
|
||
|
||
```python
|
||
reduced_coupling = coupling_map.reduce(qubit_to_use)
|
||
mapped = BIPMapping(reduced_coupling)(circ)
|
||
# skip the definition of fill_with_ancilla()
|
||
# recover circuit on original coupling map
|
||
layout = Layout({q: qubit_to_use[i] for i, q in enumerate(mapped.qubits)})
|
||
for reg in mapped.qregs:
|
||
layout.add_register(reg)
|
||
property_set = {"layout": fill_with_ancilla(layout)}
|
||
recovered = ApplyLayout()(mapped, property_set)
|
||
# recover layout
|
||
overall_layout = Layout({v: qubit_to_use[q] for v, q in mapped._layout.get_virtual_bits().items()})
|
||
for reg in mapped.qregs:
|
||
overall_layout.add_register(reg)
|
||
recovered._layout = fill_with_ancilla(overall_layout)
|
||
```
|
||
|
||
* Added the `ignore_pauli_phase` and `copy` arguments to the constructor of [`SparsePauliOp`](/api/qiskit/0.45/qiskit.quantum_info.SparsePauliOp "qiskit.quantum_info.SparsePauliOp"). `ignore_pauli_phase` prevents the `phase` attribute of an input [`PauliList`](/api/qiskit/0.45/qiskit.quantum_info.PauliList "qiskit.quantum_info.PauliList") from being read, which is more performant if the [`PauliList`](/api/qiskit/0.45/qiskit.quantum_info.PauliList "qiskit.quantum_info.PauliList") is already known to have all phases as zero in the internal ZX convention. `copy` allows users to avoid the copy of the input data when they explicitly set `copy=False`.
|
||
|
||
* Improved performance of the following [`SparsePauliOp`](/api/qiskit/0.45/qiskit.quantum_info.SparsePauliOp "qiskit.quantum_info.SparsePauliOp") operations:
|
||
|
||
* [`simplify()`](/api/qiskit/0.45/qiskit.quantum_info.SparsePauliOp#simplify "qiskit.quantum_info.SparsePauliOp.simplify") (see [#7122](https://github.com/Qiskit/qiskit/issues/7122))
|
||
* [`compose()`](/api/qiskit/0.45/qiskit.quantum_info.SparsePauliOp#compose "qiskit.quantum_info.SparsePauliOp.compose") (see [#7126](https://github.com/Qiskit/qiskit/issues/7126))
|
||
* `_add()` (see [#7138](https://github.com/Qiskit/qiskit/issues/7138))
|
||
* [`from_list()`](/api/qiskit/0.45/qiskit.quantum_info.SparsePauliOp#from_list "qiskit.quantum_info.SparsePauliOp.from_list") and `__init__()` (see other discussion in [#7138](https://github.com/Qiskit/qiskit/issues/7138)).
|
||
|
||
* Added the [`SparsePauliOp.sum()`](/api/qiskit/0.45/qiskit.quantum_info.SparsePauliOp#sum "qiskit.quantum_info.SparsePauliOp.sum") method to add together many [`SparsePauliOp`](/api/qiskit/0.45/qiskit.quantum_info.SparsePauliOp "qiskit.quantum_info.SparsePauliOp")s. This method has significantly better performance than adding the instances together in a loop. For example, the previous way to add several [`SparsePauliOp`](/api/qiskit/0.45/qiskit.quantum_info.SparsePauliOp "qiskit.quantum_info.SparsePauliOp")s together would be to do:
|
||
|
||
```python
|
||
from qiskit.quantum_info import SparsePauliOp, random_pauli_list
|
||
sparse_ops = [SparsePauliOp(random_pauli_list(10, 10)) for _ in [None]*1000]
|
||
|
||
total = sparse_ops[0]
|
||
for op in sparse_ops[1:]:
|
||
total += op
|
||
```
|
||
|
||
This can now be done far more efficiently (in both speed and typing!) as:
|
||
|
||
```python
|
||
SparsePauliOp.sum(sparse_ops)
|
||
```
|
||
|
||
* Added an argument `limit_amplitude` to the constructor of `ParametricPulse`, which is the base class of [`Gaussian`](/api/qiskit/0.45/qiskit.pulse.library.Gaussian_class.rst#qiskit.pulse.library.Gaussian "qiskit.pulse.library.Gaussian"), [`GaussianSquare`](/api/qiskit/0.45/qiskit.pulse.library.GaussianSquare "qiskit.pulse.library.GaussianSquare"), [`Drag`](/api/qiskit/0.45/qiskit.pulse.library.Drag_class.rst#qiskit.pulse.library.Drag "qiskit.pulse.library.Drag") and [`Constant`](/api/qiskit/0.45/qiskit.pulse.library.Constant_class.rst#qiskit.pulse.library.Constant "qiskit.pulse.library.Constant"), to allowing disabling the amplitude limit of 1 on a pulse-by-pulse basis. With `limit_amplitude=False`, individual pulses may have an amplitude exceeding unity without raising a [`PulseError`](/api/qiskit/0.45/pulse#qiskit.pulse.PulseError "qiskit.pulse.PulseError"). See [#6544](https://github.com/Qiskit/qiskit/issues/6544) for more detail.
|
||
|
||
* Using [`QuantumCircuit.draw()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#draw "qiskit.circuit.QuantumCircuit.draw") or [`circuit_drawer()`](/api/qiskit/0.45/qiskit.visualization.circuit_drawer "qiskit.visualization.circuit_drawer") with the `latex` drawer will now generate a file in an image format inferred from the filename extension, for example:
|
||
|
||
```python
|
||
import qiskit
|
||
|
||
circuit = qiskit.QuantumCircuit(2)
|
||
circuit.h(0)
|
||
circuit.cx(0, 1)
|
||
circuit.draw('latex', filename='./file.jpg')
|
||
```
|
||
|
||
This will save the circuit drawing in the JPEG format. Previously, the image always be in PNG format. Refer to [#6448](https://github.com/Qiskit/qiskit/issues/6448) for more details.
|
||
|
||
Now, if it encounters a filename extension which is not supported, for example:
|
||
|
||
```python
|
||
circuit.draw('latex', filename='./file.spooky')
|
||
```
|
||
|
||
it will raise a `ValueError` to change the filename extension to a supported image format.
|
||
|
||
* Added the parameter `filename` to [`plot_gate_map()`](/api/qiskit/0.45/qiskit.visualization.plot_gate_map "qiskit.visualization.plot_gate_map") and [`plot_coupling_map()`](/api/qiskit/0.45/qiskit.visualization.plot_coupling_map "qiskit.visualization.plot_coupling_map"), which allows saving the resulting images to a file.
|
||
|
||
* Introduced an approximate quantum compiler and a corresponding unitary synthesis plugin implementation. The main AQC class is [`AQC`](/api/qiskit/0.45/qiskit.transpiler.synthesis.aqc.AQC "qiskit.transpiler.synthesis.aqc.AQC") for a standalone version that compiles a unitary matrix into an approximate circuit. The plugin may be invoked by [`transpile()`](/api/qiskit/0.45/compiler#qiskit.compiler.transpile "qiskit.compiler.transpile") when the `unitary_synthesis_method` argument is set to `'aqc'`. See [`qiskit.transpiler.synthesis.aqc`](/api/qiskit/0.45/synthesis_aqc#module-qiskit.transpiler.synthesis.aqc "qiskit.transpiler.synthesis.aqc") for full details.
|
||
|
||
* Added a `filter_function` argument to [`QuantumCircuit.depth()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#depth "qiskit.circuit.QuantumCircuit.depth") and [`QuantumCircuit.size()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#size "qiskit.circuit.QuantumCircuit.size") in order to analyze circuit operations according to some criteria.
|
||
|
||
For example, to get the number of two-qubit gates, you can do:
|
||
|
||
```python
|
||
circuit.size(lambda x: x[0].num_qubits == 2)
|
||
```
|
||
|
||
Or to get the depth of T gates acting on the zeroth qubit:
|
||
|
||
```python
|
||
circuit.depth(lambda x: x[0].name == 't' and circuit.qubits[0] in x[1])
|
||
```
|
||
|
||
* Added a new transpiler pass, [`CollectMultiQBlocks`](/api/qiskit/0.45/qiskit.transpiler.passes.CollectMultiQBlocks "qiskit.transpiler.passes.CollectMultiQBlocks"), to the [`qiskit.transpiler.passes`](/api/qiskit/0.45/transpiler_passes#module-qiskit.transpiler.passes "qiskit.transpiler.passes") module. This pass is used to collect sequences of uninterrupted gates acting on groups of qubits. It provides a similar function to the existing [`Collect2qBlocks`](/api/qiskit/0.45/qiskit.transpiler.passes.Collect2qBlocks "qiskit.transpiler.passes.Collect2qBlocks") pass, but while that pass is designed and optimized to find 2 qubit blocks this new pass will work to find blocks of any size.
|
||
|
||
* There is a builder interface for the new control-flow operations on [`QuantumCircuit`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit"), such as the new [`ForLoopOp`](/api/qiskit/0.45/qiskit.circuit.ForLoopOp "qiskit.circuit.ForLoopOp"), [`IfElseOp`](/api/qiskit/0.45/qiskit.circuit.IfElseOp "qiskit.circuit.IfElseOp"), and [`WhileLoopOp`](/api/qiskit/0.45/qiskit.circuit.WhileLoopOp "qiskit.circuit.WhileLoopOp"). The interface uses the same circuit methods, *i.e.* [`QuantumCircuit.for_loop()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#for_loop "qiskit.circuit.QuantumCircuit.for_loop"), [`QuantumCircuit.if_test()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#if_test "qiskit.circuit.QuantumCircuit.if_test") and [`QuantumCircuit.while_loop()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#while_loop "qiskit.circuit.QuantumCircuit.while_loop"), which are overloaded so that if the `body` parameter is not given, they return a context manager. Entering one of these context managers pushes a scope into the circuit, and captures all gate calls (and other scopes) and the resources these use, and builds up the relevant operation at the end. For example, you can now do:
|
||
|
||
```python
|
||
qc = QuantumCircuit(2, 2)
|
||
with qc.for_loop(range(5)) as i:
|
||
qc.rx(i * math.pi / 4, 0)
|
||
```
|
||
|
||
This will produce a [`ForLoopOp`](/api/qiskit/0.45/qiskit.circuit.ForLoopOp "qiskit.circuit.ForLoopOp") on `qc`, which knows that qubit 0 is the only resource used within the loop body. These context managers can be nested, and will correctly determine their widths. You can use [`QuantumCircuit.break_loop()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#break_loop "qiskit.circuit.QuantumCircuit.break_loop") and [`QuantumCircuit.continue_loop()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#continue_loop "qiskit.circuit.QuantumCircuit.continue_loop") within a context, and it will expand to be the correct width for its containing loop, even if it is nested in further [`QuantumCircuit.if_test()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#if_test "qiskit.circuit.QuantumCircuit.if_test") blocks.
|
||
|
||
The [`if_test()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#if_test "qiskit.circuit.QuantumCircuit.if_test") context manager provides a chained manager which, if desired, can be used to create an `else` block, such as by:
|
||
|
||
```python
|
||
qreg = QuantumRegister(2)
|
||
creg = ClassicalRegister(2)
|
||
qc = QuantumCircuit(qreg, creg)
|
||
qc.h(0)
|
||
qc.cx(0, 1)
|
||
qc.measure(0, 0)
|
||
with qc.if_test((creg, 0)) as else_:
|
||
qc.x(1)
|
||
with else_:
|
||
qc.z(1)
|
||
```
|
||
|
||
The manager will ensure that the `if` and `else` bodies are defined over the same set of resources.
|
||
|
||
* Introduced a new transpiler pass [`InverseCancellation`](/api/qiskit/0.45/qiskit.transpiler.passes.InverseCancellation "qiskit.transpiler.passes.InverseCancellation") that generalizes the [`CXCancellation`](/api/qiskit/0.45/qiskit.transpiler.passes.CXCancellation "qiskit.transpiler.passes.CXCancellation") pass to cancel any self-inverse gates or gate-inverse pairs. It can be used by initializing [`InverseCancellation`](/api/qiskit/0.45/qiskit.transpiler.passes.InverseCancellation "qiskit.transpiler.passes.InverseCancellation") and passing a gate to cancel, for example:
|
||
|
||
```python
|
||
from qiskit.transpiler.passes import InverseCancellation
|
||
from qiskit import QuantumCircuit
|
||
from qiskit.circuit.library import HGate
|
||
from qiskit.transpiler import PassManager
|
||
|
||
qc = QuantumCircuit(2, 2)
|
||
qc.h(0)
|
||
qc.h(0)
|
||
pass_ = InverseCancellation([HGate()])
|
||
pm = PassManager(pass_)
|
||
new_circ = pm.run(qc)
|
||
```
|
||
|
||
* The constructor of [`RZXCalibrationBuilder`](/api/qiskit/0.45/qiskit.transpiler.passes.RZXCalibrationBuilder "qiskit.transpiler.passes.RZXCalibrationBuilder") has two new kwargs `instruction_schedule_map` and `qubit_channel_mapping` which take a [`InstructionScheduleMap`](/api/qiskit/0.45/qiskit.pulse.InstructionScheduleMap "qiskit.pulse.InstructionScheduleMap") and list of channel name lists for each qubit respectively. These new arguments are used to directly specify the information needed from a backend target. They should be used instead of passing a `BaseBackend` or [`BackendV1`](/api/qiskit/0.45/qiskit.providers.BackendV1 "qiskit.providers.BackendV1") object directly to the pass with the `backend` argument.
|
||
|
||
* The [`Statevector`](/api/qiskit/0.45/qiskit.quantum_info.Statevector "qiskit.quantum_info.Statevector")s of states comprised only of qubits can now be drawn in LaTeX in ket notation. In ket notation the entries of the statevector are processed such that exact factors like fractions or square roots of two are drawn as such. The particular convention can be chosen by passing the `convention` keyword argument as either `"ket"` or `"vector"` as appropriate:
|
||
|
||
```python
|
||
import math
|
||
from qiskit.quantum_info import Statevector
|
||
|
||
sv = Statevector([math.sqrt(0.5), 0, 0, -math.sqrt(0.5)])
|
||
sv.draw("latex", convention="ket")
|
||
sv.draw("latex", convention="vector")
|
||
```
|
||
|
||
* Added a new transpiler pass [`EchoRZXWeylDecomposition`](/api/qiskit/0.45/qiskit.transpiler.passes.EchoRZXWeylDecomposition "qiskit.transpiler.passes.EchoRZXWeylDecomposition") that allows users to decompose an arbitrary two-qubit gate in terms of echoed RZX-gates by leveraging Cartan’s decomposition. In combination with other transpiler passes, this can be used to transpile arbitrary circuits to RZX-gate-based and pulse-efficient circuits that implement the same unitary.
|
||
|
||
* The [`SPSA`](/api/qiskit/0.45/qiskit.algorithms.optimizers.SPSA "qiskit.algorithms.optimizers.SPSA") and [`QNSPSA`](/api/qiskit/0.45/qiskit.algorithms.optimizers.QNSPSA "qiskit.algorithms.optimizers.QNSPSA") optimizer classes are now capable of batching as many circuit evaluations as possible for both the iterations and the initial calibrations. This can be leveraged by setting the `max_evals_grouped` kwarg on the constructor for [`VQE`](/api/qiskit/0.45/qiskit.algorithms.VQE "qiskit.algorithms.VQE") when using either [`SPSA`](/api/qiskit/0.45/qiskit.algorithms.optimizers.SPSA "qiskit.algorithms.optimizers.SPSA") or [`QNSPSA`](/api/qiskit/0.45/qiskit.algorithms.optimizers.QNSPSA "qiskit.algorithms.optimizers.QNSPSA") as the `optimizer` parameter. For example:
|
||
|
||
```python
|
||
from qiskit.circuit.library import TwoLocal
|
||
from qiskit.algorithms import VQE
|
||
from qiskit.algorithms.optimizers import QNSPSA
|
||
from qiskit.test.mock import FakeMontreal
|
||
|
||
backend = FakeMontreal()
|
||
ansatz = TwoLocal(2, rotation_blocks=["ry", "rz"], entanglement_blocks="cz")
|
||
qnspsa = QNSPSA(fidelity, maxiter=5)
|
||
vqe = VQE(
|
||
ansatz=ansatz,
|
||
optimizer=qnspsa,
|
||
max_evals_grouped=100,
|
||
quantum_instance=backend,
|
||
)
|
||
```
|
||
|
||
* This release introduces a decomposition method for two-qubit gates which targets user-defined sets of RZX gates. Transpiler users can enable decomposition for \{`RZX(pi/2)`, `RZX(pi/4)`, and `RZX(pi/6)`} specifically by including `'rzx'` in their `basis_gates` list when calling [`transpile()`](/api/qiskit/0.45/compiler#qiskit.compiler.transpile "qiskit.compiler.transpile"). Quantum information package users can find the method itself under the [`XXDecomposer`](/api/qiskit/0.45/qiskit.quantum_info.XXDecomposer "qiskit.quantum_info.XXDecomposer") class.
|
||
|
||
* Added a transpiler pass [`Optimize1qGatesSimpleCommutation`](/api/qiskit/0.45/qiskit.transpiler.passes.Optimize1qGatesSimpleCommutation "qiskit.transpiler.passes.Optimize1qGatesSimpleCommutation"), which optimizes a circuit according to a strategy of commuting single-qubit gates around to discover resynthesis opportunities.
|
||
|
||
* Added a `max_job_tries` parameter to [`QuantumInstance`](/api/qiskit/0.45/qiskit.utils.QuantumInstance "qiskit.utils.QuantumInstance"), to limit the number of times a job will attempt to be executed on a backend. Previously the submission and fetching of results would be attempted infinitely, even if the job was cancelled or errored on the backend. The default is now 50, and the previous behaviour can be achieved by setting `max_job_tries=-1`. Fixes [#6872](https://github.com/Qiskit/qiskit/issues/6872) and [#6821](https://github.com/Qiskit/qiskit/issues/6821).
|
||
|
||
* The `latex` output method for the [`circuit_drawer()`](/api/qiskit/0.45/qiskit.visualization.circuit_drawer "qiskit.visualization.circuit_drawer") function and the [`QuantumCircuit.draw()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#draw "qiskit.circuit.QuantumCircuit.draw") method can now draw circuits that contain gates with single bit condition. This was added for compatibility of latex drawer with the new feature of supporting classical conditioning of gates on single classical bits.
|
||
|
||
* The `"mpl"` output method for the [`circuit_drawer()`](/api/qiskit/0.45/qiskit.visualization.circuit_drawer "qiskit.visualization.circuit_drawer") function and the [`QuantumCircuit.draw()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#draw "qiskit.circuit.QuantumCircuit.draw") method can now draw circuits that contain gates with single bit condition. This was added for compatibility of the `"mpl"` drawer with the new feature of supporting classical conditioning of gates on single classical bits.
|
||
|
||
* The `text` output method for the [`circuit_drawer()`](/api/qiskit/0.45/qiskit.visualization.circuit_drawer "qiskit.visualization.circuit_drawer") function and the [`QuantumCircuit.draw()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#draw "qiskit.circuit.QuantumCircuit.draw") method can now draw circuits that contain gates with single bit condition. This was added for compatibility of text drawer with the new feature of supporting classical conditioning of gates on single classical bits.
|
||
|
||
* A new analysis transpiler pass, [`GatesInBasis`](/api/qiskit/0.45/qiskit.transpiler.passes.GatesInBasis "qiskit.transpiler.passes.GatesInBasis"), was added to [`qiskit.transpiler.passes`](/api/qiskit/0.45/transpiler_passes#module-qiskit.transpiler.passes "qiskit.transpiler.passes"). This pass is used to check if the [`DAGCircuit`](/api/qiskit/0.45/qiskit.dagcircuit.DAGCircuit "qiskit.dagcircuit.DAGCircuit") being transpiled has all the gates in the configured basis set or not. It will set the attribute `"all_gates_in_basis"` in the property set to `True` if all the gates in the [`DAGCircuit`](/api/qiskit/0.45/qiskit.dagcircuit.DAGCircuit "qiskit.dagcircuit.DAGCircuit") are in the configured basis set or `False` if they are not. For example:
|
||
|
||
```python
|
||
from qiskit.circuit import QuantumCircuit
|
||
from qiskit.transpiler.passes import GatesInBasis
|
||
|
||
# Instatiate Pass
|
||
basis_gates = ["cx", "h"]
|
||
basis_check_pass = GatesInBasis(basis_gates)
|
||
# Build circuit
|
||
circuit = QuantumCircuit(2)
|
||
circuit.h(0)
|
||
circuit.cx(0, 1)
|
||
circuit.measure_all()
|
||
# Run pass on circuit
|
||
property_set = {}
|
||
basis_check_pass(circuit, property_set=property_set)
|
||
assert property_set["all_gates_in_basis"]
|
||
```
|
||
|
||
* Added two new constructor methods, [`from_heavy_hex()`](/api/qiskit/0.45/qiskit.transpiler.CouplingMap#from_heavy_hex "qiskit.transpiler.CouplingMap.from_heavy_hex") and [`from_heavy_square()`](/api/qiskit/0.45/qiskit.transpiler.CouplingMap#from_heavy_square "qiskit.transpiler.CouplingMap.from_heavy_square"), to the [`CouplingMap`](/api/qiskit/0.45/qiskit.transpiler.CouplingMap "qiskit.transpiler.CouplingMap") class. These constructor methods are used to create a [`CouplingMap`](/api/qiskit/0.45/qiskit.transpiler.CouplingMap "qiskit.transpiler.CouplingMap") that are a heavy hex or heavy square graph as described in [Chamberland *et al.*, 2020](https://journals.aps.org/prx/abstract/10.1103/PhysRevX.10.011022).
|
||
|
||
For example:
|
||
|
||
```python
|
||
from qiskit.transpiler import CouplingMap
|
||
|
||
cmap = CouplingMap.from_heavy_hex(5)
|
||
cmap.draw()
|
||
```
|
||
|
||
```python
|
||
from qiskit.transpiler import CouplingMap
|
||
|
||
cmap = CouplingMap.from_heavy_square(5)
|
||
cmap.draw()
|
||
```
|
||
|
||
* The `HHL` algorithm can now find solutions when its matrix has negative eigenvalues. To enable this, the algorithm now adds an extra qubit to represent the sign of the value, and the helper algorithm [`ExactReciprocal`](/api/qiskit/0.45/qiskit.circuit.library.ExactReciprocal "qiskit.circuit.library.ExactReciprocal") was updated to process this new information. See [#6971](https://github.com/Qiskit/qiskit-terra/pull/6971) for more details.
|
||
|
||
* Added two new classes, [`CompleteMeasFitter`](/api/qiskit/0.45/qiskit.utils.mitigation.CompleteMeasFitter "qiskit.utils.mitigation.CompleteMeasFitter") and [`TensoredMeasFitter`](/api/qiskit/0.45/qiskit.utils.mitigation.TensoredMeasFitter "qiskit.utils.mitigation.TensoredMeasFitter") to the [`qiskit.utils.mitigation`](/api/qiskit/0.45/utils_mitigation#module-qiskit.utils.mitigation "qiskit.utils.mitigation") module. These classes are for use only as values for the `measurement_error_mitigation_cls` kwarg of the [`QuantumInstance`](/api/qiskit/0.45/qiskit.utils.QuantumInstance "qiskit.utils.QuantumInstance") class. The instantiation and usage of these classes (or anything else in [`qiskit.utils.mitigation`](/api/qiskit/0.45/utils_mitigation#module-qiskit.utils.mitigation "qiskit.utils.mitigation")) outside of the `measurement_error_mitigation_cls` kwarg should be treated as an internal private API and not relied upon.
|
||
|
||
* The [`ListOp`](/api/qiskit/0.45/qiskit.opflow.list_ops.ListOp "qiskit.opflow.list_ops.ListOp") class in [`qiskit.opflow`](/api/qiskit/0.45/opflow#module-qiskit.opflow "qiskit.opflow") now has a [`coeffs`](/api/qiskit/0.45/qiskit.opflow.list_ops.ListOp#coeffs "qiskit.opflow.list_ops.ListOp.coeffs") attribute, which returns a list of the coefficients of the operator list, with the overall coefficient ([`ListOp.coeff`](/api/qiskit/0.45/qiskit.opflow.list_ops.ListOp#coeff "qiskit.opflow.list_ops.ListOp.coeff")) distributed multiplicatively into the list. Note that [`ListOp`](/api/qiskit/0.45/qiskit.opflow.list_ops.ListOp "qiskit.opflow.list_ops.ListOp") objects may be nested (contained in `oplist` of a [`ListOp`](/api/qiskit/0.45/qiskit.opflow.list_ops.ListOp "qiskit.opflow.list_ops.ListOp") object), and in these cases an exception is raised if the coeffs method is called. The [`ListOp.coeffs`](/api/qiskit/0.45/qiskit.opflow.list_ops.ListOp#coeffs "qiskit.opflow.list_ops.ListOp.coeffs") method conveniently duck-types against the `coeffs` property method of the non-nesting [`PauliSumOp`](/api/qiskit/0.45/qiskit.opflow.primitive_ops.PauliSumOp "qiskit.opflow.primitive_ops.PauliSumOp") class.
|
||
|
||
* The [`Statevector`](/api/qiskit/0.45/qiskit.quantum_info.Statevector "qiskit.quantum_info.Statevector") class is now subscriptable. User can now retrieve the nth coefficient in a [`Statevector`](/api/qiskit/0.45/qiskit.quantum_info.Statevector "qiskit.quantum_info.Statevector") by index as `statevec[n]`.
|
||
|
||
* Added the [`Statevector.inner`](/api/qiskit/0.45/qiskit.quantum_info.Statevector#inner "qiskit.quantum_info.Statevector.inner") method to calculate inner products of [`Statevector`](/api/qiskit/0.45/qiskit.quantum_info.Statevector "qiskit.quantum_info.Statevector") instances. For example:
|
||
|
||
```python
|
||
statevec_inner_other = statevec.inner(other)
|
||
```
|
||
|
||
will return the inner product of `statevec` with `other`. While `statevec` must be a [`Statevector`](/api/qiskit/0.45/qiskit.quantum_info.Statevector "qiskit.quantum_info.Statevector"), `other` can be anything that can be constructed into a [`Statevector`](/api/qiskit/0.45/qiskit.quantum_info.Statevector "qiskit.quantum_info.Statevector"), such as a Numpy array.
|
||
|
||
* Added a new parameter, `add_bits`, to [`QuantumCircuit.measure_all()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#measure_all "qiskit.circuit.QuantumCircuit.measure_all"). By default it is set to `True` to maintain the previous behaviour of adding a new [`ClassicalRegister`](/api/qiskit/0.45/qiskit.circuit.ClassicalRegister "qiskit.circuit.ClassicalRegister") of the same size as the number of qubits to store the measurements. If set to `False`, the measurements will be stored in the already existing classical bits. For example, if you created a circuit with existing classical bits like:
|
||
|
||
```python
|
||
from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
|
||
|
||
qr = QuantumRegister(2)
|
||
cr = ClassicalRegister(2, "meas")
|
||
circuit = QuantumCircuit(qr, cr)
|
||
```
|
||
|
||
calling `circuit.measure_all(add_bits=False)` will use the existing classical register `cr` as the output target of the `Measurement` objects added to the circuit.
|
||
|
||
* [`ParameterExpression`](/api/qiskit/0.45/qiskit.circuit.ParameterExpression "qiskit.circuit.ParameterExpression") now delegates its numeric conversions to the underlying symbolic library, even if there are potentially unbound parameters. This allows conversions of expressions such as:
|
||
|
||
```python
|
||
>>> from qiskit.circuit import Parameter
|
||
>>> x = Parameter('x')
|
||
>>> float(x - x + 2.3)
|
||
2.3
|
||
```
|
||
|
||
where the underlying expression has a fixed value, but the parameter `x` is not yet bound.
|
||
|
||
* Added an [`Optimizer.minimize()`](/api/qiskit/0.45/qiskit.algorithms.optimizers.Optimizer#minimize "qiskit.algorithms.optimizers.Optimizer.minimize") method to all optimizers: [`Optimizer`](/api/qiskit/0.45/qiskit.algorithms.optimizers.Optimizer "qiskit.algorithms.optimizers.Optimizer") and derived classes. This method mimics the signature of SciPy’s `minimize()` function and returns an [`OptimizerResult`](/api/qiskit/0.45/qiskit.algorithms.optimizers.OptimizerResult "qiskit.algorithms.optimizers.OptimizerResult").
|
||
|
||
For example
|
||
|
||
```python
|
||
import numpy as np
|
||
from qiskit.algorithms.optimizers import COBYLA
|
||
|
||
def loss(x):
|
||
return -(x[0] - 1) ** 2 - (x[1] + 1) ** 3
|
||
|
||
initial_point = np.array([0, 0])
|
||
optimizer = COBYLA()
|
||
result = optimizer.minimize(loss, initial_point)
|
||
|
||
optimal_parameters = result.x
|
||
minimum_value = result.fun
|
||
num_function_evals = result.nfev
|
||
```
|
||
|
||
* Added a [`PauliEvolutionGate`](/api/qiskit/0.45/qiskit.circuit.library.PauliEvolutionGate "qiskit.circuit.library.PauliEvolutionGate") to the circuit library ([`qiskit.circuit.library`](/api/qiskit/0.45/circuit_library#module-qiskit.circuit.library "qiskit.circuit.library")) which defines a gate performing time evolution of (sums or sums-of-sums of) [`Pauli`](/api/qiskit/0.45/qiskit.quantum_info.Pauli "qiskit.quantum_info.Pauli")s. The synthesis of this gate is performed by [`EvolutionSynthesis`](/api/qiskit/0.45/qiskit.synthesis.EvolutionSynthesis "qiskit.synthesis.EvolutionSynthesis") and is decoupled from the gate itself. Currently available synthesis methods are:
|
||
|
||
* [`LieTrotter`](/api/qiskit/0.45/qiskit.synthesis.LieTrotter "qiskit.synthesis.LieTrotter"): first order Trotterization
|
||
* [`SuzukiTrotter`](/api/qiskit/0.45/qiskit.synthesis.SuzukiTrotter "qiskit.synthesis.SuzukiTrotter"): higher order Trotterization
|
||
* [`MatrixExponential`](/api/qiskit/0.45/qiskit.synthesis.MatrixExponential "qiskit.synthesis.MatrixExponential"): exact, matrix-based evolution
|
||
|
||
For example:
|
||
|
||
```python
|
||
from qiskit.circuit import QuantumCircuit
|
||
from qiskit.circuit.library import PauliEvolutionGate
|
||
from qiskit.quantum_info import SparsePauliOp
|
||
from qiskit.synthesis import SuzukiTrotter
|
||
|
||
operator = SparsePauliOp.from_list([
|
||
("XIZ", 0.5), ("ZZX", 0.5), ("IYY", -1)
|
||
])
|
||
time = 0.12 # evolution time
|
||
synth = SuzukiTrotter(order=4, reps=2)
|
||
|
||
evo = PauliEvolutionGate(operator, time=time, synthesis=synth)
|
||
|
||
circuit = QuantumCircuit(3)
|
||
circuit.append(evo, range(3))
|
||
```
|
||
|
||
* A new function [`plot_coupling_map()`](/api/qiskit/0.45/qiskit.visualization.plot_coupling_map "qiskit.visualization.plot_coupling_map") has been introduced, which extends the functionality of the existing function [`plot_gate_map()`](/api/qiskit/0.45/qiskit.visualization.plot_gate_map "qiskit.visualization.plot_gate_map"), by accepting three parameters: `num_qubit`, `qubit_coordinates`, and `coupling_map` (instead of `backend`), to allow an arbitrary qubit coupling map to be plotted.
|
||
|
||
* Qiskit Terra now has initial support for serializing [`QuantumCircuit`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit")s to [OpenQASM 3](https://github.com/Qiskit/openqasm):
|
||
|
||
```python
|
||
from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
|
||
from qiskit import qasm3
|
||
|
||
qc = QuantumCircuit(2)
|
||
qc.h(0)
|
||
qc.cx(0, 1)
|
||
|
||
print(qasm3.dumps(qc))
|
||
```
|
||
|
||
This initial release has limited support for named registers, basic built-in instructions (such as measure, barrier and reset), user-defined gates, user-defined instructions (as subroutines), and the new control-flow constructs also introduced in this release:
|
||
|
||
```python
|
||
from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
|
||
from qiskit import qasm3
|
||
import math
|
||
|
||
composite_circ_qreg = QuantumRegister(2)
|
||
composite_circ = QuantumCircuit(composite_circ_qreg, name="composite_circ")
|
||
composite_circ.h(0)
|
||
composite_circ.x(1)
|
||
composite_circ.cx(0, 1)
|
||
composite_circ_gate = composite_circ.to_gate()
|
||
|
||
qr = QuantumRegister(2, "qr")
|
||
cr = ClassicalRegister(2, "cr")
|
||
qc = QuantumCircuit(qr, cr)
|
||
with qc.for_loop(range(4)) as i:
|
||
qc.rx(i * math.pi / 4, 0)
|
||
qc.cx(0, 1)
|
||
qc.barrier()
|
||
qc.append(composite_circ_gate, [0, 1])
|
||
qc.measure([0, 1], [0, 1])
|
||
|
||
print(qasm3.dumps(qc))
|
||
```
|
||
|
||
* The [`QDrift`](/api/qiskit/0.45/qiskit.opflow.evolutions.QDrift "qiskit.opflow.evolutions.QDrift") class was reformulated as a synthesis method for [`PauliEvolutionGate`](/api/qiskit/0.45/qiskit.circuit.library.PauliEvolutionGate "qiskit.circuit.library.PauliEvolutionGate"), deriving from [`TrotterizationBase`](/api/qiskit/0.45/qiskit.opflow.evolutions.TrotterizationBase "qiskit.opflow.evolutions.TrotterizationBase").
|
||
|
||
```python
|
||
from qiskit.circuit import QuantumCircuit
|
||
from qiskit.circuit.library import PauliEvolutionGate
|
||
from qiskit.synthesis import QDrift
|
||
from qiskit.opflow import X, Y, Z
|
||
|
||
qdrift = QDrift(reps=2)
|
||
operator = (X ^ 3) + (Y ^ 3) + (Z ^ 3)
|
||
time = 2.345 # evolution time
|
||
|
||
evolution_gate = PauliEvolutionGate(operator, time, synthesis=qdrift)
|
||
|
||
circuit = QuantumCircuit(3)
|
||
circuit.append(evolution_gate, range(3))
|
||
```
|
||
|
||
* QPY serialization is now capable of representing [`global_phase`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#global_phase "qiskit.circuit.QuantumCircuit.global_phase") attributes of a [`QuantumCircuit`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") object that are an `int`, [`Parameter`](/api/qiskit/0.45/qiskit.circuit.Parameter "qiskit.circuit.Parameter") object, or [`ParameterExpression`](/api/qiskit/0.45/qiskit.circuit.ParameterExpression "qiskit.circuit.ParameterExpression") object. Previous versions of QPY would only accept a [`global_phase`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#global_phase "qiskit.circuit.QuantumCircuit.global_phase") that was a `float`.
|
||
|
||
This requires the QPY format [Version 2](/api/qiskit/0.45/qpy#qpy-version-2) which was introduced in this release to represent the additional types.
|
||
|
||
* A new [`find_bit()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#find_bit "qiskit.circuit.QuantumCircuit.find_bit") method has been added to the [`QuantumCircuit`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") class, which allows lookups of the index and registers of a provided [`Bit`](/api/qiskit/0.45/qiskit.circuit.Bit "qiskit.circuit.Bit") on the given circuit. The method returns a two-element `namedtuple` containing 0) the index of the `Bit` in either [`qubits`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#qubits "qiskit.circuit.QuantumCircuit.qubits") (for a [`Qubit`](/api/qiskit/0.45/qiskit.circuit.Qubit "qiskit.circuit.Qubit")) or [`clbits`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#clbits "qiskit.circuit.QuantumCircuit.clbits") (for a [`Clbit`](/api/qiskit/0.45/qiskit.circuit.Clbit "qiskit.circuit.Clbit")) and 1) a list of length-2 tuples containing each circuit [`Register`](/api/qiskit/0.45/qiskit.circuit.Register "qiskit.circuit.Register") which contains the `Bit`, and the index in that `Register` at which the `Bit` can be found.
|
||
|
||
For example:
|
||
|
||
```python
|
||
from qiskit.circuit import QuantumCircuit, QuantumRegister, Qubit
|
||
|
||
reg1 = QuantumRegister(3, 'foo')
|
||
qubit = Qubit()
|
||
reg2 = QuantumRegister(2, 'bar')
|
||
|
||
qc = QuantumCircuit(reg1, [qubit], reg2)
|
||
|
||
print(qc.find_bit(reg1[2]))
|
||
print(qc.find_bit(qubit))
|
||
```
|
||
|
||
would generate:
|
||
|
||
```python
|
||
BitLocations(index=2, registers=[(QuantumRegister(3, 'foo'), 2)])
|
||
BitLocations(index=3, registers=[])
|
||
```
|
||
|
||
* Three new [`Instruction`](/api/qiskit/0.45/qiskit.circuit.Instruction "qiskit.circuit.Instruction") subclasses have been added to support control flow operations in dynamic circuits: [`WhileLoopOp`](/api/qiskit/0.45/qiskit.circuit.WhileLoopOp "qiskit.circuit.WhileLoopOp"), [`ForLoopOp`](/api/qiskit/0.45/qiskit.circuit.ForLoopOp "qiskit.circuit.ForLoopOp"), and [`IfElseOp`](/api/qiskit/0.45/qiskit.circuit.IfElseOp "qiskit.circuit.IfElseOp"). Additionally, two subclasses, [`BreakLoopOp`](/api/qiskit/0.45/qiskit.circuit.BreakLoopOp "qiskit.circuit.BreakLoopOp"), and [`ContinueLoopOp`](/api/qiskit/0.45/qiskit.circuit.ContinueLoopOp "qiskit.circuit.ContinueLoopOp"), have been added to support breaking from and continuing to the next iteration of a loop context, respectively.
|
||
|
||
These can be created as stand-alone [`Instruction`](/api/qiskit/0.45/qiskit.circuit.Instruction "qiskit.circuit.Instruction")s, or appended to an existing [`QuantumCircuit`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") instance via their respective methods, [`QuantumCircuit.while_loop()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#while_loop "qiskit.circuit.QuantumCircuit.while_loop"), [`for_loop()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#for_loop "qiskit.circuit.QuantumCircuit.for_loop"), [`if_test()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#if_test "qiskit.circuit.QuantumCircuit.if_test"), [`if_else()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#if_else "qiskit.circuit.QuantumCircuit.if_else"), [`break_loop()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#break_loop "qiskit.circuit.QuantumCircuit.break_loop"), and [`continue_loop()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#continue_loop "qiskit.circuit.QuantumCircuit.continue_loop").
|
||
|
||
* Added the [`BaseReadoutMitigator`](/api/qiskit/0.45/qiskit.result.BaseReadoutMitigator "qiskit.result.BaseReadoutMitigator") abstract base class for implementing classical measurement error mitigators. These objects are intended for mitigation measurement errors in [`Counts`](/api/qiskit/0.45/qiskit.result.Counts "qiskit.result.Counts") objects returned from execution of circuits on backends with measurement errors.
|
||
|
||
Readout mitigator classes have two main methods:
|
||
|
||
* [`expectation_value()`](/api/qiskit/0.45/qiskit.result.BaseReadoutMitigator#expectation_value "qiskit.result.BaseReadoutMitigator.expectation_value") which computes an mitigated expectation value and standard error of a diagonal operator from a noisy [`Counts`](/api/qiskit/0.45/qiskit.result.Counts "qiskit.result.Counts") object.
|
||
* [`quasi_probabilities()`](/api/qiskit/0.45/qiskit.result.BaseReadoutMitigator#quasi_probabilities "qiskit.result.BaseReadoutMitigator.quasi_probabilities") that computes an error mitigated [`QuasiDistribution`](/api/qiskit/0.45/qiskit.result.QuasiDistribution "qiskit.result.QuasiDistribution"), including standard error, from a noisy counts object.
|
||
|
||
Note that currently the [`qiskit.algorithms`](/api/qiskit/0.45/algorithms#module-qiskit.algorithms "qiskit.algorithms") module and the [`QuantumInstance`](/api/qiskit/0.45/qiskit.utils.QuantumInstance "qiskit.utils.QuantumInstance") class still use the legacy mitigators migrated from Qiskit Ignis in [`qiskit.utils.mitigation`](/api/qiskit/0.45/utils_mitigation#module-qiskit.utils.mitigation "qiskit.utils.mitigation"). It is planned to upgrade the module to use the new mitigator classes and deprecate the legacy mitgation code in a future release.
|
||
|
||
* Added the [`LocalReadoutMitigator`](/api/qiskit/0.45/qiskit.result.LocalReadoutMitigator "qiskit.result.LocalReadoutMitigator") class for performing measurement readout error mitigation of local measurement errors. Local measuerment errors are those that are described by a tensor-product of single-qubit measurement errors.
|
||
|
||
This class can be initialized with a list of $N$ single-qubit of measurement error assignment matrices or from a backend using the readout error information in the backend properties.
|
||
|
||
Mitigation is implemented using local assignment-matrix inversion which has complexity of $O(2^N)$ for $N$-qubit mitigation of [`QuasiDistribution`](/api/qiskit/0.45/qiskit.result.QuasiDistribution "qiskit.result.QuasiDistribution") and expectation values.
|
||
|
||
* Added the [`CorrelatedReadoutMitigator`](/api/qiskit/0.45/qiskit.result.CorrelatedReadoutMitigator "qiskit.result.CorrelatedReadoutMitigator") class for performing measurement readout error mitigation of correlated measurement errors. This class can be initialized with a single $2^N \times 2^N$ measurement error assignment matrix that descirbes the error probabilities. Mitigation is implemented via inversion of assigment matrix which has mitigation complexity of $O(4^N)$ of [`QuasiDistribution`](/api/qiskit/0.45/qiskit.result.QuasiDistribution "qiskit.result.QuasiDistribution") and expectation values.
|
||
|
||
* Added a [`QuasiDistribution.stddev_upper_bound`](/api/qiskit/0.45/qiskit.result.QuasiDistribution#stddev_upper_bound "qiskit.result.QuasiDistribution.stddev_upper_bound") attribute and a kwarg to the constructor of the [`QuasiDistribution`](/api/qiskit/0.45/qiskit.result.QuasiDistribution "qiskit.result.QuasiDistribution") class, which is used for storing standard errors in quasi-probability estimates. This is used by [`BaseReadoutMitigator`](/api/qiskit/0.45/qiskit.result.BaseReadoutMitigator "qiskit.result.BaseReadoutMitigator") classes to store the standard error in mitigated quasi probabilities.
|
||
|
||
* Added a [`shots()`](/api/qiskit/0.45/qiskit.result.Counts#shots "qiskit.result.Counts.shots") method to [`qiskit.result.Counts`](/api/qiskit/0.45/qiskit.result.Counts "qiskit.result.Counts") to return the sum of all outcomes in the counts.
|
||
|
||
* When running the [`Grover`](/api/qiskit/0.45/qiskit.algorithms.Grover "qiskit.algorithms.Grover") algorithm class if the optimal power is known and only a single circuit is run, the [`AmplificationProblem.is_good_state`](/api/qiskit/0.45/qiskit.algorithms.AmplificationProblem#is_good_state "qiskit.algorithms.AmplificationProblem.is_good_state") callback function is no longer required to be set and the Grover search will return the most likely bitstring. Generally, if the optimal power of the Grover operator is not known, the [`Grover`](/api/qiskit/0.45/qiskit.algorithms.Grover "qiskit.algorithms.Grover") algorithm checks different powers (i.e. iterations) and applies the [`is_good_state`](/api/qiskit/0.45/qiskit.algorithms.AmplificationProblem#is_good_state "qiskit.algorithms.AmplificationProblem.is_good_state") function to check whether a good bitstring has been measured. For example, you are now able to run something like:
|
||
|
||
```python
|
||
from qiskit.algorithms import Grover, AmplificationProblem
|
||
from qiskit.providers.aer import AerSimulator
|
||
from qiskit.quantum_info import Statevector
|
||
|
||
# Fixed Grover power: 2.
|
||
grover = Grover(iterations=2, quantum_instance=AerSimulator())
|
||
|
||
# The ``is_good_state`` argument not required here since Grover search
|
||
# will be run only once, with a power of 2.
|
||
problem = AmplificationProblem(Statevector.from_label("111"))
|
||
|
||
# Run Grover search and print the best measurement
|
||
result = grover.amplify(problem)
|
||
print(result.top_measurement) # should print 111
|
||
```
|
||
|
||
* Added method [`remove_cregs()`](/api/qiskit/0.45/qiskit.dagcircuit.DAGCircuit#remove_cregs "qiskit.dagcircuit.DAGCircuit.remove_cregs") to class [`DAGCircuit`](/api/qiskit/0.45/qiskit.dagcircuit.DAGCircuit "qiskit.dagcircuit.DAGCircuit") to support classical register removal.
|
||
|
||
* Added method [`remove_clbits()`](/api/qiskit/0.45/qiskit.dagcircuit.DAGCircuit#remove_clbits "qiskit.dagcircuit.DAGCircuit.remove_clbits") to class [`DAGCircuit`](/api/qiskit/0.45/qiskit.dagcircuit.DAGCircuit "qiskit.dagcircuit.DAGCircuit") to support the removal of idle classical bits. Any classical registers referencing a removed bit are also removed.
|
||
|
||
* Added a new method, [`replace_block_with_op()`](/api/qiskit/0.45/qiskit.dagcircuit.DAGCircuit#replace_block_with_op "qiskit.dagcircuit.DAGCircuit.replace_block_with_op"), to the [`DAGCircuit`](/api/qiskit/0.45/qiskit.dagcircuit.DAGCircuit "qiskit.dagcircuit.DAGCircuit") class. This method is used to replace a block of nodes in the DAG with a single operation. The canonical example is for the [`ConsolidateBlocks`](/api/qiskit/0.45/qiskit.transpiler.passes.ConsolidateBlocks "qiskit.transpiler.passes.ConsolidateBlocks") pass which replaces blocks of nodes with equivalent `UnitaryGate` nodes.
|
||
|
||
* Added a new analysis transpiler pass, [`Collect1qRuns`](/api/qiskit/0.45/qiskit.transpiler.passes.Collect1qRuns "qiskit.transpiler.passes.Collect1qRuns"), to the [`qiskit.transpiler.passes`](/api/qiskit/0.45/transpiler_passes#module-qiskit.transpiler.passes "qiskit.transpiler.passes") module. This pass is used to find sequences of uninterrupted gates acting on a single qubit. It is similar to the [`Collect2qBlocks`](/api/qiskit/0.45/qiskit.transpiler.passes.Collect2qBlocks "qiskit.transpiler.passes.Collect2qBlocks") and [`CollectMultiQBlocks`](/api/qiskit/0.45/qiskit.transpiler.passes.CollectMultiQBlocks "qiskit.transpiler.passes.CollectMultiQBlocks") but optimized for single qubit runs instead of multiple qubit blocks.
|
||
|
||
* Various transpilation internals now use new features in [retworkx](https://github.com/Qiskit/retworkx) 0.10 when operating on the internal circuit representation. This can often result in speedups in calls to [`transpile`](/api/qiskit/0.45/compiler#qiskit.compiler.transpile "qiskit.compiler.transpile") of around 10-40%, with greater effects at higher optimization levels. See [#6302](https://github.com/Qiskit/qiskit-terra/pull/6302) for more details.
|
||
|
||
* The [`UnitarySynthesis`](/api/qiskit/0.45/qiskit.transpiler.passes.UnitarySynthesis "qiskit.transpiler.passes.UnitarySynthesis") transpiler pass in [`qiskit.transpiler.passes`](/api/qiskit/0.45/transpiler_passes#module-qiskit.transpiler.passes "qiskit.transpiler.passes") has a new kwarg in the constructor, `min_qubits`. When specified this can be set to an `int` value which is the minimum size `UnitaryGate` object to run the unitary synthesis on. If a `UnitaryGate` in a [`QuantumCircuit`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") uses fewer qubits it will be skipped by that instance of the pass.
|
||
|
||
* The `Eigensolver` and `MinimumEigensolver` interfaces now support the type `Dict[str, Optional[OperatorBase]]` for the `aux_operators` parameter in their respective `compute_eigenvalues()` and `compute_minimum_eigenvalue()` methods. In this case, the auxiliary eigenvalues are also stored in a dictionary under the same keys provided by the `aux_operators` dictionary. Keys that correspond to an operator that does not commute with the main operator are dropped.
|
||
|
||
* The [`BasisTranslator`](/api/qiskit/0.45/qiskit.transpiler.passes.BasisTranslator "qiskit.transpiler.passes.BasisTranslator"), [`GateDirection`](/api/qiskit/0.45/qiskit.transpiler.passes.GateDirection "qiskit.transpiler.passes.GateDirection"), and [`CheckGateDirection`](/api/qiskit/0.45/qiskit.transpiler.passes.CheckGateDirection "qiskit.transpiler.passes.CheckGateDirection") transpiler passes have a new `target` kwarg in their constructors, which can be used to set a [`Target`](/api/qiskit/0.45/qiskit.transpiler.Target "qiskit.transpiler.Target") object as the target for the pass. If it is set it will be used instead of the `target_basis` (in the case of the [`BasisTranslator`](/api/qiskit/0.45/qiskit.transpiler.passes.BasisTranslator "qiskit.transpiler.passes.BasisTranslator") pass) or `coupling_map` (in the case of the [`GateDirection`](/api/qiskit/0.45/qiskit.transpiler.passes.GateDirection "qiskit.transpiler.passes.GateDirection") and [`CheckGateDirection`](/api/qiskit/0.45/qiskit.transpiler.passes.CheckGateDirection "qiskit.transpiler.passes.CheckGateDirection") passes) arguments.
|
||
|
||
* Allow two transpiler stages in the [`QuantumInstance`](/api/qiskit/0.45/qiskit.utils.QuantumInstance "qiskit.utils.QuantumInstance"), one for parameterized circuits and a second one for bound circuits (i.e. no free parameters) only. If a quantum instance with passes for unbound and bound circuits is passed into a [`CircuitSampler`](/api/qiskit/0.45/qiskit.opflow.converters.CircuitSampler "qiskit.opflow.converters.CircuitSampler"), the sampler will attempt to apply the unbound pass once on the parameterized circuit, cache it, and only apply the bound pass for all future evaluations.
|
||
|
||
This enables variational algorithms like the [`VQE`](/api/qiskit/0.45/qiskit.algorithms.VQE "qiskit.algorithms.VQE") to run a custom pass manager for parameterized circuits once and, additionally, another the transpiler again with a different custom pass manager on the bound circuits in each iteration. Being able to run different pass managers is important because not all passes support parameterized circuits (for example [`Optimize1qGatesDecomposition`](/api/qiskit/0.45/qiskit.transpiler.passes.Optimize1qGatesDecomposition "qiskit.transpiler.passes.Optimize1qGatesDecomposition") only works with bound circuit parameters).
|
||
|
||
For example, this feature allows using the pulse-efficient CX decomposition in the VQE, as
|
||
|
||
```python
|
||
from qiskit.algorithms import VQE
|
||
from qiskit.opflow import Z
|
||
from qiskit.circuit.library.standard_gates.equivalence_library import StandardEquivalenceLibrary as std_eqlib
|
||
from qiskit.transpiler import PassManager, PassManagerConfig, CouplingMap
|
||
from qiskit.transpiler.preset_passmanagers import level_1_pass_manager
|
||
from qiskit.transpiler.passes import (
|
||
Collect2qBlocks, ConsolidateBlocks, Optimize1qGatesDecomposition,
|
||
RZXCalibrationBuilderNoEcho, UnrollCustomDefinitions, BasisTranslator
|
||
)
|
||
from qiskit.transpiler.passes.optimization.echo_rzx_weyl_decomposition import EchoRZXWeylDecomposition
|
||
from qiskit.test.mock import FakeBelem
|
||
from qiskit.utils import QuantumInstance
|
||
|
||
# Replace by a real backend! If not ensure qiskit-aer is installed to simulate the backend
|
||
backend = FakeBelem()
|
||
|
||
# Build the pass manager for the parameterized circuit
|
||
rzx_basis = ['rzx', 'rz', 'x', 'sx']
|
||
coupling_map = CouplingMap(backend.configuration().coupling_map)
|
||
config = PassManagerConfig(basis_gates=rzx_basis, coupling_map=coupling_map)
|
||
pre = level_1_pass_manager(config)
|
||
|
||
# Build a pass manager for the CX decomposition (works only on bound circuits)
|
||
post = PassManager([
|
||
# Consolidate consecutive two-qubit operations.
|
||
Collect2qBlocks(),
|
||
ConsolidateBlocks(basis_gates=['rz', 'sx', 'x', 'rxx']),
|
||
|
||
# Rewrite circuit in terms of Weyl-decomposed echoed RZX gates.
|
||
EchoRZXWeylDecomposition(backend),
|
||
|
||
# Attach scaled CR pulse schedules to the RZX gates.
|
||
RZXCalibrationBuilderNoEcho(backend),
|
||
|
||
# Simplify single-qubit gates.
|
||
UnrollCustomDefinitions(std_eqlib, rzx_basis),
|
||
BasisTranslator(std_eqlib, rzx_basis),
|
||
Optimize1qGatesDecomposition(rzx_basis),
|
||
])
|
||
|
||
quantum_instance = QuantumInstance(backend, pass_manager=pre, bound_pass_manager=post)
|
||
|
||
vqe = VQE(quantum_instance=quantum_instance)
|
||
result = vqe.compute_minimum_eigenvalue(Z ^ Z)
|
||
```
|
||
|
||
* Introduced a new unitary synthesis plugin interface which is used to enable using alternative synthesis techniques included in external packages seamlessly with the [`UnitarySynthesis`](/api/qiskit/0.45/qiskit.transpiler.passes.UnitarySynthesis "qiskit.transpiler.passes.UnitarySynthesis") transpiler pass. Users can select a plugin to use when calling [`transpile()`](/api/qiskit/0.45/compiler#qiskit.compiler.transpile "qiskit.compiler.transpile") by setting the `unitary_synthesis_method` kwarg to the plugin’s name. A full list of installed plugins can be found using the [`qiskit.transpiler.passes.synthesis.plugin.unitary_synthesis_plugin_names()`](/api/qiskit/0.45/qiskit.transpiler.passes.synthesis.plugin.unitary_synthesis_plugin_names "qiskit.transpiler.passes.synthesis.plugin.unitary_synthesis_plugin_names") function. For example, if you installed a package that includes a synthesis plugin named `special_synth` you could use it with:
|
||
|
||
```python
|
||
from qiskit import transpile
|
||
|
||
transpile(qc, unitary_synthesis_method='special_synth', optimization_level=3)
|
||
```
|
||
|
||
This will replace all uses of the [`UnitarySynthesis`](/api/qiskit/0.45/qiskit.transpiler.passes.UnitarySynthesis "qiskit.transpiler.passes.UnitarySynthesis") with the method included in the external package that exports the `special_synth` plugin.
|
||
|
||
The plugin interface is built around setuptools [entry points](https://setuptools.readthedocs.io/en/latest/userguide/entry_point.html) which enable packages external to Qiskit to advertise they include a synthesis plugin. For details on writing a new plugin refer to the [`qiskit.transpiler.passes.synthesis.plugin`](/api/qiskit/0.45/transpiler_synthesis_plugins#module-qiskit.transpiler.passes.synthesis.plugin "qiskit.transpiler.passes.synthesis.plugin") module documentation.
|
||
|
||
* Added a new transpiler pass, [`VF2Layout`](/api/qiskit/0.45/qiskit.transpiler.passes.VF2Layout "qiskit.transpiler.passes.VF2Layout"). This pass models the layout allocation problem as a subgraph isomorphism problem and uses the [VF2 algorithm](https://ieeexplore.ieee.org/document/1323804) implementation in [rustworkx](https://qiskit.org/ecosystem/rustworkx/apiref/rustworkx.vf2_mapping.html) to find a perfect layout (a layout which would not require additional routing) if one exists. The functionality exposed by this new pass is very similar to exisiting [`CSPLayout`](/api/qiskit/0.45/qiskit.transpiler.passes.CSPLayout "qiskit.transpiler.passes.CSPLayout") but [`VF2Layout`](/api/qiskit/0.45/qiskit.transpiler.passes.VF2Layout "qiskit.transpiler.passes.VF2Layout") is significantly faster.
|
||
|
||
<span id="release-notes-0-19-0-known-issues" />
|
||
|
||
<span id="id181" />
|
||
|
||
#### Known Issues
|
||
|
||
* The `"ket"` convention in the `"latex"` drawer of [`Statevector.draw()`](/api/qiskit/0.45/qiskit.quantum_info.Statevector#draw "qiskit.quantum_info.Statevector.draw") is only valid for states comprising purely of qubits. If you are using states with some spaces of dimension greater than two, you should either pass `convention="vector"`, or use a different drawer.
|
||
|
||
* The OpenQASM 3 export capabilities are in a beta state, and some features of Qiskit Terra’s [`QuantumCircuit`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") are not yet supported. In particular, you may see errors if you try to export custom subroutines with classical parameters, and there is no provision yet for exporting pulse-calibrated operations into [OpenPulse](https://openqasm.com/language/openpulse.html).
|
||
|
||
* When running the [`BasisTranslator`](/api/qiskit/0.45/qiskit.transpiler.passes.BasisTranslator "qiskit.transpiler.passes.BasisTranslator") in isolation with the `target` argument set to a [`Target`](/api/qiskit/0.45/qiskit.transpiler.Target "qiskit.transpiler.Target") object, where some single-qubit gates can only apply to non-overlapping sets of qubits, the output circuit might incorrectly include operations on a qubit that are not allowed by the [`Target`](/api/qiskit/0.45/qiskit.transpiler.Target "qiskit.transpiler.Target"). For example, if you ran:
|
||
|
||
```python
|
||
from qiskit.circuit import QuantumCircuit, Parameter
|
||
from qiskit.circuit.library import UGate, RZGate, XGate, SXGate, CXGate
|
||
from qiskit.circuit.equivalence_library import SessionEquivalenceLibrary as sel
|
||
|
||
from qiskit.transpiler import PassManager, Target, InstructionProperties
|
||
from qiskit.transpiler.passes import BasisTranslator
|
||
|
||
gmap = Target()
|
||
|
||
# U gate in qubit 0.
|
||
theta = Parameter('theta')
|
||
phi = Parameter('phi')
|
||
lam = Parameter('lambda')
|
||
u_props = {
|
||
(0,): InstructionProperties(duration=5.23e-8, error=0.00038115),
|
||
}
|
||
gmap.add_instruction(UGate(theta, phi, lam), u_props)
|
||
|
||
# Rz gate in qubit 1.
|
||
phi = Parameter("phi")
|
||
rz_props = {
|
||
(1,): InstructionProperties(duration=0.0, error=0),
|
||
}
|
||
gmap.add_instruction(RZGate(phi), rz_props)
|
||
|
||
# X gate in qubit 1.
|
||
x_props = {
|
||
(1,): InstructionProperties(
|
||
duration=3.5555555555555554e-08, error=0.00020056469709026198
|
||
),
|
||
}
|
||
gmap.add_instruction(XGate(), x_props)
|
||
|
||
# SX gate in qubit 1.
|
||
sx_props = {
|
||
(1,): InstructionProperties(
|
||
duration=3.5555555555555554e-08, error=0.00020056469709026198
|
||
),
|
||
}
|
||
gmap.add_instruction(SXGate(), sx_props)
|
||
|
||
cx_props = {
|
||
(0, 1): InstructionProperties(duration=5.23e-7, error=0.00098115),
|
||
(1, 0): InstructionProperties(duration=4.52e-7, error=0.00132115),
|
||
}
|
||
gmap.add_instruction(CXGate(), cx_props)
|
||
|
||
bt_pass = BasisTranslator(sel, target_basis=None, target=gmap)
|
||
|
||
qc = QuantumCircuit(2)
|
||
qc.iswap(0, 1)
|
||
output = bt_pass(qc)
|
||
```
|
||
|
||
`output` will have [`RZGate`](/api/qiskit/0.45/qiskit.circuit.library.RZGate "qiskit.circuit.library.RZGate") and [`SXGate`](/api/qiskit/0.45/qiskit.circuit.library.SXGate "qiskit.circuit.library.SXGate") on qubit 0, even though this is forbidden. To correct this you can normally run the basis translator a second time (i.e. `output = bt_pass(output)` in the above example) to correct this. This should not affect the output of running the [`transpile()`](/api/qiskit/0.45/compiler#qiskit.compiler.transpile "qiskit.compiler.transpile") function and is only an issue if you run the pass by itself.
|
||
|
||
<span id="release-notes-0-19-0-upgrade-notes" />
|
||
|
||
<span id="id182" />
|
||
|
||
#### Upgrade Notes
|
||
|
||
* Starting with this version, `from qiskit import *` will not import submodules, but only a selected list of objects. This might break existing code using `from qiskit import *` and referring to objects that are not part of the current namespace. As a reminder, `import *` is considered bad practice and it should not be used in production code. Qiskit sets `__all__` in `qiskit/__init__.py` as a way to mitigate the effects of said bad practice. If your code raises `name '<something>' is not defined`, add `from qiskit import <something>` and try again.
|
||
|
||
* The preset pass managers for optimization levels 0, 1, 2, and 3 which are generated by [`level_0_pass_manager()`](/api/qiskit/0.45/transpiler_preset#qiskit.transpiler.preset_passmanagers.level_0_pass_manager "qiskit.transpiler.preset_passmanagers.level_0_pass_manager"), [`level_1_pass_manager()`](/api/qiskit/0.45/transpiler_preset#qiskit.transpiler.preset_passmanagers.level_1_pass_manager "qiskit.transpiler.preset_passmanagers.level_1_pass_manager"), [`level_2_pass_manager()`](/api/qiskit/0.45/transpiler_preset#qiskit.transpiler.preset_passmanagers.level_2_pass_manager "qiskit.transpiler.preset_passmanagers.level_2_pass_manager"), and [`level_3_pass_manager()`](/api/qiskit/0.45/transpiler_preset#qiskit.transpiler.preset_passmanagers.level_3_pass_manager "qiskit.transpiler.preset_passmanagers.level_3_pass_manager") respectively will no longer unconditionally run the [`TimeUnitConversion`](/api/qiskit/0.45/qiskit.transpiler.passes.TimeUnitConversion "qiskit.transpiler.passes.TimeUnitConversion"). Previously, the preset pass managers would always run this pass regardless of the inputs to the transpiler and the circuit. Now this pass will only be run if a `scheduling_method` parameter is set or the circuit contains a [`Delay`](/api/qiskit/0.45/qiskit.circuit.Delay "qiskit.circuit.Delay") instruction and the `instruction_durations` parameter is set. This change was made in the interest of runtime performance as in some cases running [`transpile()`](/api/qiskit/0.45/compiler#qiskit.compiler.transpile "qiskit.compiler.transpile") on circuits with a large number of gates and no delays, timing, or scheduling being used the [`TimeUnitConversion`](/api/qiskit/0.45/qiskit.transpiler.passes.TimeUnitConversion "qiskit.transpiler.passes.TimeUnitConversion") could be the largest bottleneck in the transpilation.
|
||
|
||
* The default method for `BIPMapping` is now `balanced` rather than `depth`. This new objective generally achieves a better result, as it factors in both the circuit depth and the gate error.
|
||
|
||
* The `sort_parameters_by_name` of the [`VQE`](/api/qiskit/0.45/qiskit.algorithms.VQE "qiskit.algorithms.VQE") class has been removed, following its deprecation in Qiskit Terra 0.18. There is no alternative provided, as the new ordering of parameters is the more natural sort order.
|
||
|
||
* The circuit drawers [`QuantumCircuit.draw()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#draw "qiskit.circuit.QuantumCircuit.draw") and [`circuit_drawer()`](/api/qiskit/0.45/qiskit.visualization.circuit_drawer "qiskit.visualization.circuit_drawer") with the `latex` option will now save their images in a format determined the file extension (if a file name is provided). Previously, they would always save in PNG format. They now raise `ValueError` if the image format is not known. This was done to make it easier to save the image in different formats.
|
||
|
||
* The core dependency `retworkx` had its version requirement bumped to 0.10.1, up from 0.9. This enables several performance improvements across different transpilation passes.
|
||
|
||
* The previously deprecated `condition` kwarg, which was deprecated as part of the 0.15.0 release, has been removed from [`DAGCircuit.apply_operation_back()`](/api/qiskit/0.45/qiskit.dagcircuit.DAGCircuit#apply_operation_back "qiskit.dagcircuit.DAGCircuit.apply_operation_back") and [`DAGCircuit.apply_operation_front()`](/api/qiskit/0.45/qiskit.dagcircuit.DAGCircuit#apply_operation_front "qiskit.dagcircuit.DAGCircuit.apply_operation_front"). Instead set the `condition` attribute on the [`Instruction`](/api/qiskit/0.45/qiskit.circuit.Instruction "qiskit.circuit.Instruction") instances being added to the [`DAGCircuit`](/api/qiskit/0.45/qiskit.dagcircuit.DAGCircuit "qiskit.dagcircuit.DAGCircuit") using [`Instruction.c_if()`](/api/qiskit/0.45/qiskit.circuit.Instruction#c_if "qiskit.circuit.Instruction.c_if").
|
||
|
||
* The `DAGCircuit.extend_back()` method has been removed. It was originally deprecated in the 0.13.0 release. Instead you can use the [`DAGCircuit.compose()`](/api/qiskit/0.45/qiskit.dagcircuit.DAGCircuit#compose "qiskit.dagcircuit.DAGCircuit.compose") method which is more general and provides the same functionality.
|
||
|
||
* The `DAGCircuit.compose_back()` method has been removed. It was originally deprecated in the 0.13.0 release. Instead you can use the [`DAGCircuit.compose()`](/api/qiskit/0.45/qiskit.dagcircuit.DAGCircuit#compose "qiskit.dagcircuit.DAGCircuit.compose") method which is more general and provides the same functionality.
|
||
|
||
* The `edge_map` kwarg of the [`DAGCircuit`](/api/qiskit/0.45/qiskit.dagcircuit.DAGCircuit "qiskit.dagcircuit.DAGCircuit") method [`compose()`](/api/qiskit/0.45/qiskit.dagcircuit.DAGCircuit#compose "qiskit.dagcircuit.DAGCircuit.compose") has been removed. It was originally deprecated in the 0.14.0 release. The method takes a `qubits` and `clbits` kwargs to specify the positional order of bits to compose onto instead of using a dictionary mapping that `edge_map` previously provided.
|
||
|
||
* The `DAGCircuit.twoQ_gates()` method has been removed. It was originally deprecated in the 0.13.0 release. Instead, [`DAGCircuit.two_qubit_ops()`](/api/qiskit/0.45/qiskit.dagcircuit.DAGCircuit#two_qubit_ops "qiskit.dagcircuit.DAGCircuit.two_qubit_ops") should be used.
|
||
|
||
* The `DAGCircuit.threeQ_or_more_gates()` method has been removed. It was originally deprecated in the 0.13.0 release. Instead, [`DAGCircuit.multi_qubit_ops()`](/api/qiskit/0.45/qiskit.dagcircuit.DAGCircuit#multi_qubit_ops "qiskit.dagcircuit.DAGCircuit.multi_qubit_ops") method should be used.
|
||
|
||
* Named access for the first positional argument for the constructor of the [`SingleQubitUnitary`](/api/qiskit/0.45/qiskit.extensions.SingleQubitUnitary "qiskit.extensions.SingleQubitUnitary") class with `u` has been removed. It was originally deprecated in the 0.14.0 release. Instead, the first positional argument can be set using the name `unitary_matrix` (or just set it positionally instead of by name).
|
||
|
||
* Named access for the first positional argument for the [`QuantumCircuit`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") method [`squ`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#squ "qiskit.circuit.QuantumCircuit.squ") with `u` has been removed. It was originally deprecated in the 0.14.0 release. Instead the first positional argument can be set using the name `unitary_matrix` (or just set it positionally instead of by name).
|
||
|
||
* The unused `proc` and `nested_scope` kwargs for the `qasm()` method of the QASM node classes in the `qiskit.qasm.node` module have been removed. They were originally deprecated in the 0.15.0 release.
|
||
|
||
* The unused `proc` and `nested_scope` kwargs for the `latex()` method of the QASM node classes in the `qiskit.qasm.node` module have been removed. They were originally deprecated in the 0.15.0 release.
|
||
|
||
* The unused `proc` and `nested_scope` kwargs for the `real()` method of the QASM node classes in the `qiskit.qasm.node` module have been removed. They were originally deprecated in the 0.15.0 release.
|
||
|
||
* The output of [`Statevector.draw()`](/api/qiskit/0.45/qiskit.quantum_info.Statevector#draw "qiskit.quantum_info.Statevector.draw") when using `"latex"` output is now the new `"ket"` convention if plotting a state comprised purely of qubits. This was changed to make reading the output clearer, especially in educational contexts, because it shows the ket labels, and only displays the nonzero elements.
|
||
|
||
* When running [`execute()`](/api/qiskit/0.45/execute#qiskit.execute_function.execute "qiskit.execute_function.execute") with a [`BackendV1`](/api/qiskit/0.45/qiskit.providers.BackendV1 "qiskit.providers.BackendV1") backend the default values for the kwargs `shots`, `max_credits`, `meas_level`, `meas_return` and `memory_slot_size` will now be whatever the set default is on the target backend’s [`options`](/api/qiskit/0.45/qiskit.providers.BackendV1#options "qiskit.providers.BackendV1.options") attribute. Previously these defaults were set to match the default values when calling [`execute()`](/api/qiskit/0.45/execute#qiskit.execute_function.execute "qiskit.execute_function.execute") with a legacy `BaseBackend` backend. For example:
|
||
|
||
```python
|
||
from qiskit.test.mock import FakeMumbai
|
||
from qiskit import QuantumCircuit, execute
|
||
|
||
circuit = QuantumCircuit(2)
|
||
qc.h(0)
|
||
qc.cx(0, 1)
|
||
qc.measure_all()
|
||
|
||
backend = FakeMumbai()
|
||
backend.set_options(shots=4096)
|
||
execute(qc, backend)
|
||
```
|
||
|
||
will now run with `4096` shots. While in previous releases it would run with `1024`.
|
||
|
||
* The minimum supported version of Matplotlib has been raised from 2.1.0 to 3.3.0. You will now need to have Matplotlib 3.3.0 installed if you’re using Matplotlib-based visualization functions such as the `'mpl'` backend for the [`circuit_drawer()`](/api/qiskit/0.45/qiskit.visualization.circuit_drawer "qiskit.visualization.circuit_drawer") function or the [`plot_bloch_vector()`](/api/qiskit/0.45/qiskit.visualization.plot_bloch_vector "qiskit.visualization.plot_bloch_vector") function. This was done for two reasons, the first is because recent versions of Matplotlib have deprecated the use of APIs around 3D visualizations that were compatible with older releases and second installing older versions of Matplotlib was becoming increasingly difficult as matplotlib’s upstream dependencies have caused incompatiblities that made testing moving forward more difficult.
|
||
|
||
* The internal use of the random number generator in [`random_circuit()`](/api/qiskit/0.45/circuit#qiskit.circuit.random.random_circuit "qiskit.circuit.random.random_circuit") was adjusted, which will change the output from previous versions, even with a fixed seed. This was done to greatly improve the runtime scaling with the number of qubits being used. If you were depending on an identical output from a previous version it is recommended that you use `qpy_serialization.dump()` to save the random circuit generated with a previous version and instead of re-generating it with the new release, and instead just use `qpy_serialization.load()` to load that saved circuit.
|
||
|
||
* The use of `*` (`__mul__`) for the [`dot()`](/api/qiskit/0.45/qiskit.quantum_info.Operator#dot "qiskit.quantum_info.Operator.dot") method and `@` (`__matmul__`) for the [`compose()`](/api/qiskit/0.45/qiskit.quantum_info.Operator#compose "qiskit.quantum_info.Operator.compose") method of `BaseOperator` (which is the parent of all the operator classes in [`qiskit.quantum_info`](/api/qiskit/0.45/quantum_info#module-qiskit.quantum_info "qiskit.quantum_info") including classes like [`Operator`](/api/qiskit/0.45/qiskit.quantum_info.Operator "qiskit.quantum_info.Operator") and [`Pauli`](/api/qiskit/0.45/qiskit.quantum_info.Pauli "qiskit.quantum_info.Pauli")) is no longer supported. The use of these operators were previously deprecated in 0.17.0 release. Instead you should use the [`dot()`](/api/qiskit/0.45/qiskit.quantum_info.Operator#dot "qiskit.quantum_info.Operator.dot") and [`compose()`](/api/qiskit/0.45/qiskit.quantum_info.Operator#compose "qiskit.quantum_info.Operator.compose") methods directly, or the `&` operator (`__and__`) can be used for [`compose()`](/api/qiskit/0.45/qiskit.quantum_info.Operator#compose "qiskit.quantum_info.Operator.compose"). For example, if you were previously using the operator like:
|
||
|
||
```python
|
||
from qiskit.quantum_info import random_hermitian
|
||
|
||
op_a = random_hermitian(4)
|
||
op_b = random_hermitian(4)
|
||
|
||
new_op = op_a @ op_b
|
||
```
|
||
|
||
this should be changed to be:
|
||
|
||
```python
|
||
from qiskit.quantum_info import random_hermitian
|
||
|
||
op_a = random_hermitian(4)
|
||
op_b = random_hermitian(4)
|
||
new_op = op_a.compose(op_b)
|
||
```
|
||
|
||
or:
|
||
|
||
```python
|
||
new_op = op_a & op_b
|
||
```
|
||
|
||
* Various methods of assigning parameters to operands of pulse program instructions have been removed, having been deprecated in Qiskit Terra 0.17. These include:
|
||
|
||
* the `assign()` method of `pulse.Instruction`.
|
||
* the `assign()` method of `Channel`, which is the base of [`AcquireChannel`](/api/qiskit/0.45/qiskit.pulse.channels.AcquireChannel "qiskit.pulse.channels.AcquireChannel"), [`SnapshotChannel`](/api/qiskit/0.45/qiskit.pulse.channels.SnapshotChannel "qiskit.pulse.channels.SnapshotChannel"), [`MemorySlot`](/api/qiskit/0.45/qiskit.pulse.channels.MemorySlot "qiskit.pulse.channels.MemorySlot") and [`RegisterSlot`](/api/qiskit/0.45/qiskit.pulse.channels.RegisterSlot "qiskit.pulse.channels.RegisterSlot").
|
||
* the `assign()` and `assign_parameters()` methods of `ParametricPulse`, which is the base of `pulse.Gaussian`, `pulse.GaussianSquare`, `pulse.Drag` and `pulse.Constant`.
|
||
|
||
These parameters should be assigned from the pulse program ([`pulse.Schedule`](/api/qiskit/0.45/qiskit.pulse.Schedule "qiskit.pulse.Schedule") and [`pulse.ScheduleBlock`](/api/qiskit/0.45/qiskit.pulse.ScheduleBlock "qiskit.pulse.ScheduleBlock")) rather than operands of the pulse program instruction.
|
||
|
||
* The `flatten()` method of `pulse.Instruction` and [`qiskit.pulse.Schedule`](/api/qiskit/0.45/qiskit.pulse.Schedule "qiskit.pulse.Schedule") has been removed and no longer exists as per the deprecation notice from Qiskit Terra 0.17. This transformation is defined as a standalone function in `qiskit.pulse.transforms.canonicalization.flatten()`.
|
||
|
||
* `qiskit.pulse.interfaces.ScheduleComponent` has been removed and no longer exists as per the deprecation notice from Qiskit Terra 0.15. No alternative class will be provided.
|
||
|
||
* Legacy pulse drawer arguments have been removed from `pulse.Waveform.draw()`, [`Schedule.draw()`](/api/qiskit/0.45/qiskit.pulse.Schedule#draw "qiskit.pulse.Schedule.draw") and [`ScheduleBlock.draw()`](/api/qiskit/0.45/qiskit.pulse.ScheduleBlock#draw "qiskit.pulse.ScheduleBlock.draw") and no longer exist as per the deprecation notice from Qiskit Terra 0.16. Now these draw methods support only V2 pulse drawer arguments. See method documentations for details.
|
||
|
||
* The `qiskit.pulse.reschedule` module has been removed and this import path no longer exist as per the deprecation notice from Qiskit Terra 0.14. Use [`qiskit.pulse.transforms`](/api/qiskit/0.45/pulse#module-qiskit.pulse.transforms "qiskit.pulse.transforms") instead.
|
||
|
||
* A protected method `Schedule._children()` has been removed and replaced by a protected instance variable as per the deprecation notice from Qiskit Terra 0.17. This is now provided as a public attribute [`Schedule.children`](/api/qiskit/0.45/qiskit.pulse.Schedule#children "qiskit.pulse.Schedule.children").
|
||
|
||
* Timeslot relevant methods and properties have been removed and no longer exist in [`ScheduleBlock`](/api/qiskit/0.45/qiskit.pulse.ScheduleBlock "qiskit.pulse.ScheduleBlock") as per the deprecation notice from Qiskit Terra 0.17. Since this representation doesn’t have notion of instruction time `t0`, the timeslot information will be available after it is transformed to a [`Schedule`](/api/qiskit/0.45/qiskit.pulse.Schedule "qiskit.pulse.Schedule"). Corresponding attributes have been provided after this conversion, but they are no longer supported. The following attributes are removed:
|
||
|
||
* `timeslots`
|
||
* `start_time`
|
||
* `stop_time`
|
||
* `ch_start_time`
|
||
* `ch_stop_time`
|
||
* `shift`
|
||
* `insert`
|
||
|
||
* Alignment pulse schedule transforms have been removed and no longer exist as per the deprecation notice from Qiskit Terra 0.17. These transforms are integrated and implemented in the `AlignmentKind` context of the schedule block. The following explicit transform functions are removed:
|
||
|
||
* `qiskit.pulse.transforms.align_equispaced`
|
||
* `qiskit.pulse.transforms.align_func`
|
||
* `qiskit.pulse.transforms.align_left`
|
||
* `qiskit.pulse.transforms.align_right`
|
||
* `qiskit.pulse.transforms.align_sequential`
|
||
|
||
* Redundant pulse builder commands have been removed and no longer exist as per the deprecation notice from Qiskit Terra 0.17. `pulse.builder.call_schedule` and `pulse.builder.call_circuit` have been integrated into [`pulse.builder.call()`](/api/qiskit/0.45/pulse#qiskit.pulse.builder.call "qiskit.pulse.builder.call").
|
||
|
||
* An internal filter override that caused all Qiskit deprecation warnings to be displayed has been removed. This means that the behaviour will now revert to the standard Python behaviour for deprecations; you should only see a `DeprecationWarning` if it was triggered by code in the main script file, interpreter session or Jupyter notebook. The user will no longer be blamed with a warning if internal Qiskit functions call deprecated behaviour. If you write libraries, you should occasionally run with the default warning filters disabled, or have tests which always run with them disabled. See the [Python documentation on warnings](https://docs.python.org/3/library/warnings.html), and in particular the [section on testing for deprecations](https://docs.python.org/3/library/warnings.html#updating-code-for-new-versions-of-dependencies) for more information on how to do this.
|
||
|
||
* Certain warnings used to be only issued once, even if triggered from multiple places. This behaviour has been removed, so it is possible that if you call deprecated functions, you may see more warnings than you did before. You should change any deprecated function calls to the suggested versions, because the deprecated forms will be removed in future Qiskit releases.
|
||
|
||
* The deprecated `qiskit.schemas` module and the `qiskit.validation` module which build jsonschema validator from the schemas have been removed. This was deprecated in the 0.17.0 release and has been replaced with a [dedicated repository for the IBM Quantum API payload schemas](https://github.com/Qiskit/ibm-quantum-schemas).
|
||
|
||
If you were relying on the schema files previously packaged in `qiskit.schemas` or the validators built on them you should use that repository and create validators from the schema files it contains.
|
||
|
||
* The functions `qiskit.qobj.validate_qobj_against_schema` and `qiskit.qobj.common.validator` along with the `validate` kwarg of the methods [`QasmQobj.to_dict()`](/api/qiskit/0.45/qiskit.qobj.QasmQobj#to_dict "qiskit.qobj.QasmQobj.to_dict"), [`PulseQobj.to_dict()`](/api/qiskit/0.45/qiskit.qobj.PulseQobj#to_dict "qiskit.qobj.PulseQobj.to_dict"), and `Qobj.to_dict()` have been removed. These were deprecated in the 0.17.0 release. If you were using these function you will have to manually build jsonschema validation functions for `Qobj` objects using the jsonschema files from [the dedicated repository for the IBM Quantum API payload schemas](https://github.com/Qiskit/ibm-quantum-schemas).
|
||
|
||
* The `fastjsonschema` and `jsonschema` packages are no longer in the requirements list for qiskit-terra. The internal use of jsonschema has been removed and they are no longer required to use qiskit-terra.
|
||
|
||
* The exception raised by the [`assemble()`](/api/qiskit/0.45/compiler#qiskit.compiler.assemble "qiskit.compiler.assemble") function when invalid parameters are passed in for constructing a [`PulseQobj`](/api/qiskit/0.45/qiskit.qobj.PulseQobj "qiskit.qobj.PulseQobj") have changed from a `SchemaValidationError` to a [`QiskitError`](/api/qiskit/0.45/exceptions#qiskit.exceptions.QiskitError "qiskit.exceptions.QiskitError"). This was necessary because the `SchemaValidationError` class was removed along with the rest of the deprecated `qiskit.schemas` and `qiskit.validation`. This also makes it more consistent with other error conditions from [`assemble()`](/api/qiskit/0.45/compiler#qiskit.compiler.assemble "qiskit.compiler.assemble") which were already raising a [`QiskitError`](/api/qiskit/0.45/exceptions#qiskit.exceptions.QiskitError "qiskit.exceptions.QiskitError").
|
||
|
||
* The default routing pass and layout pass for transpiler optimization level 3 has changed to use [`SabreSwap`](/api/qiskit/0.45/qiskit.transpiler.passes.SabreSwap "qiskit.transpiler.passes.SabreSwap") and [`SabreLayout`](/api/qiskit/0.45/qiskit.transpiler.passes.SabreLayout "qiskit.transpiler.passes.SabreLayout") respectively. This was done to improve the quality of the output result, as using the sabre passes produces better results than using [`StochasticSwap`](/api/qiskit/0.45/qiskit.transpiler.passes.StochasticSwap "qiskit.transpiler.passes.StochasticSwap") and [`DenseLayout`](/api/qiskit/0.45/qiskit.transpiler.passes.DenseLayout "qiskit.transpiler.passes.DenseLayout"), which were used as the defaults in prior releases. This change will improve the quality of the results when running [`transpile()`](/api/qiskit/0.45/compiler#qiskit.compiler.transpile "qiskit.compiler.transpile") or [`execute()`](/api/qiskit/0.45/execute#qiskit.execute_function.execute "qiskit.execute_function.execute") functions with the `optimization_level` kwarg set to `3`. While this is generally an improvement, if you need to retain the previous behavior for any reason you can do this by explicitly setting the `routing_method="stochastic"` and `layout_method="dense"` when calling [`transpile()`](/api/qiskit/0.45/compiler#qiskit.compiler.transpile "qiskit.compiler.transpile") with `optimization_level=3`.
|
||
|
||
* The return type of [`pauli_basis()`](/api/qiskit/0.45/qiskit.quantum_info.pauli_basis "qiskit.quantum_info.pauli_basis") will change from `PauliTable` to [`PauliList`](/api/qiskit/0.45/qiskit.quantum_info.PauliList "qiskit.quantum_info.PauliList") in a future release of Qiskit Terra. To immediately swap to the new behaviour, pass the keyword argument `pauli_list=True`.
|
||
|
||
* The [`name`](/api/qiskit/0.45/qiskit.extensions.SingleQubitUnitary#name "qiskit.extensions.SingleQubitUnitary.name") attribute of the [`SingleQubitUnitary`](/api/qiskit/0.45/qiskit.extensions.SingleQubitUnitary "qiskit.extensions.SingleQubitUnitary") gate class has been changed from `unitary` to `squ`. This was necessary to avoid a conflict with the `UnitaryGate` class’s name which was also `unitary` since the 2 gates are not the same and don’t have the same implementation (and can’t be used interchangeably).
|
||
|
||
* The minimum version of [Symengine](https://pypi.org/project/symengine) required for installing has been increased to 0.8.0. This was necessary to fix some issues with the handling of `numpy.float16` and `numpy.float32` values when running [`bind()`](/api/qiskit/0.45/qiskit.circuit.ParameterExpression#bind "qiskit.circuit.ParameterExpression.bind") to bind parameters in a [`ParameterExpression`](/api/qiskit/0.45/qiskit.circuit.ParameterExpression "qiskit.circuit.ParameterExpression").
|
||
|
||
* A new dependency [stevedore](https://pypi.org/project/stevedore/) has been added to the requirements list. This is required by qiskit-terra as it is used to build the unitary synthesis plugin interface.
|
||
|
||
<span id="release-notes-0-19-0-deprecation-notes" />
|
||
|
||
<span id="id184" />
|
||
|
||
#### Deprecation Notes
|
||
|
||
* The `gate` attribute and initialization parameter of [`qiskit.transpiler.passes.Decompose`](/api/qiskit/0.45/qiskit.transpiler.passes.Decompose "qiskit.transpiler.passes.Decompose") is deprecated, and will be removed in a future release. Instead of this single gate, you should pass a list of gate names to the new parameter `gates_to_decompose`. This was done as the new form allows you to select more than one gate as a decomposition target, which is more flexible, and does not need to re-run the pass several times to decompose a set of gates.
|
||
|
||
* There has been a significant transpiler pass reorganization regarding calibrations. The import paths:
|
||
|
||
```python
|
||
from qiskit.transpiler.passes.scheduling.calibration_creators import RZXCalibrationBuilder
|
||
from qiskit.transpiler.passes.scheduling.calibration_creators import RZXCalibrationBuilderNoEcho
|
||
```
|
||
|
||
are deprecated, and will be removed in a future release. The import path:
|
||
|
||
```python
|
||
from qiskit.transpiler.passes.scheduling.rzx_templates import rzx_templates
|
||
```
|
||
|
||
is also deprecated, and will be removed in a future release. You should use the new import paths:
|
||
|
||
```python
|
||
from qiskit.transpiler.passes import RZXCalibrationBuilder
|
||
from qiskit.transpiler.passes import RZXCalibrationBuilderNoEcho
|
||
from qiskit.transpiler.passes.calibration.rzx_templates import rzx_templates
|
||
```
|
||
|
||
* The [`DAGNode`](/api/qiskit/0.45/qiskit.dagcircuit.DAGNode "qiskit.dagcircuit.DAGNode") class is being deprecated as a standalone class and will be used in the future only as the parent class for [`DAGOpNode`](/api/qiskit/0.45/qiskit.dagcircuit.DAGOpNode "qiskit.dagcircuit.DAGOpNode"), [`DAGInNode`](/api/qiskit/0.45/qiskit.dagcircuit.DAGInNode "qiskit.dagcircuit.DAGInNode"), and [`DAGOutNode`](/api/qiskit/0.45/qiskit.dagcircuit.DAGOutNode "qiskit.dagcircuit.DAGOutNode"). As part of this deprecation, the following kwargs and associated attributes in [`DAGNode`](/api/qiskit/0.45/qiskit.dagcircuit.DAGNode "qiskit.dagcircuit.DAGNode") are also being deprecated: `type`, `op`, and `wire`.
|
||
|
||
* For the constructor of the [`RZXCalibrationBuilder`](/api/qiskit/0.45/qiskit.transpiler.passes.RZXCalibrationBuilder "qiskit.transpiler.passes.RZXCalibrationBuilder") passing a backend either as the first positional argument or with the named `backend` kwarg is deprecated and will no longer work in a future release. Instead a [`InstructionScheduleMap`](/api/qiskit/0.45/qiskit.pulse.InstructionScheduleMap "qiskit.pulse.InstructionScheduleMap") should be passed directly to the `instruction_schedule_map` kwarg and a list of channel name lists for each qubit should be passed directly to `qubit_channel_mapping`. For example, if you were calling the pass like:
|
||
|
||
```python
|
||
from qiskit.transpiler.passes import RZXCalibrationBuilder
|
||
from qiskit.test.mock import FakeMumbai
|
||
|
||
backend = FakeMumbai()
|
||
cal_pass = RZXCalibrationBuilder(backend)
|
||
```
|
||
|
||
instead you should call it like:
|
||
|
||
```python
|
||
from qiskit.transpiler.passes import RZXCalibrationBuilder
|
||
from qiskit.test.mock import FakeMumbai
|
||
|
||
backend = FakeMumbai()
|
||
inst_map = backend.defaults().instruction_schedule_map
|
||
channel_map = self.backend.configuration().qubit_channel_mapping
|
||
cal_pass = RZXCalibrationBuilder(
|
||
instruction_schedule_map=inst_map,
|
||
qubit_channel_mapping=channel_map,
|
||
)
|
||
```
|
||
|
||
This change is necessary because as a general rule backend objects are not pickle serializable and it would break when it was used with multiple processes inside of [`transpile()`](/api/qiskit/0.45/compiler#qiskit.compiler.transpile "qiskit.compiler.transpile") when compiling multiple circuits at once.
|
||
|
||
* The `label` property of class [`MCMT`](/api/qiskit/0.45/qiskit.circuit.library.MCMT "qiskit.circuit.library.MCMT") and subclass [`MCMTVChain`](/api/qiskit/0.45/qiskit.circuit.library.MCMTVChain "qiskit.circuit.library.MCMTVChain") has been deprecated and will be removed in a future release. Consequently, the `label` kwarg on the constructor for both classes is also deprecated, along with the `label` kwarg of method [`MCMT.control()`](/api/qiskit/0.45/qiskit.circuit.library.MCMT#control "qiskit.circuit.library.MCMT.control"). Currently, the `label` property is used to name the controlled target when it is comprised of more than one target qubit, however, this was never intended to be user-specifiable, and can result in an incorrect MCMT gate if the name of a well-known operation is used. After deprecation, the `label` property will no longer be user-specifiable. However, you can get the generated name of the controlled target via
|
||
|
||
```python
|
||
MCMT.data[0][0].base_gate.name
|
||
```
|
||
|
||
* The `subgraph()` method of the [`CouplingMap`](/api/qiskit/0.45/qiskit.transpiler.CouplingMap "qiskit.transpiler.CouplingMap") class is deprecated and will be removed in a future release. Instead the [`reduce()`](/api/qiskit/0.45/qiskit.transpiler.CouplingMap#reduce "qiskit.transpiler.CouplingMap.reduce") method should be used, which does the same thing except it preserves the node list order for the output [`CouplingMap`](/api/qiskit/0.45/qiskit.transpiler.CouplingMap "qiskit.transpiler.CouplingMap") (while `subgraph()` did not preserve list order).
|
||
|
||
* Creating an instance of [`InstructionSet`](/api/qiskit/0.45/qiskit.circuit.InstructionSet "qiskit.circuit.InstructionSet") with the `circuit_cregs` keyword argument is deprecated. In general, these classes never need to be constructed by users (but are used internally), but should you need to, you should pass a callable as the `resource_requester` keyword argument. For example:
|
||
|
||
```python
|
||
from qiskit.circuit import Clbit, ClassicalRegister, InstructionSet
|
||
from qiskit.circuit.exceptions import CircuitError
|
||
|
||
def my_requester(bits, registers):
|
||
bits_set = set(bits)
|
||
bits_flat = tuple(bits)
|
||
registers_set = set(registers)
|
||
|
||
def requester(specifier):
|
||
if isinstance(specifer, Clbit) and specifier in bits_set:
|
||
return specifier
|
||
if isinstance(specifer, ClassicalRegster) and specifier in register_set:
|
||
return specifier
|
||
if isinstance(specifier, int) and 0 <= specifier < len(bits_flat):
|
||
return bits_flat[specifier]
|
||
raise CircuitError(f"Unknown resource: {specifier}")
|
||
|
||
return requester
|
||
|
||
my_bits = [Clbit() for _ in [None]*5]
|
||
my_registers = [ClassicalRegister(n) for n in range(3)]
|
||
|
||
InstructionSet(resource_requester=my_requester(my_bits, my_registers))
|
||
```
|
||
|
||
* The use of the measurement mitigation classes `qiskit.ignis.mitigation.CompleteMeasFitter` and `qiskit.ignis.mitigation.TensoredMeasFitter` from `qiskit-ignis` as values for the `measurement_error_mitigation_cls` kwarg of the constructor for the [`QuantumInstance`](/api/qiskit/0.45/qiskit.utils.QuantumInstance "qiskit.utils.QuantumInstance") class is deprecated and will be removed in a future release. Instead the equivalent classes from [`qiskit.utils.mitigation`](/api/qiskit/0.45/utils_mitigation#module-qiskit.utils.mitigation "qiskit.utils.mitigation"), [`CompleteMeasFitter`](/api/qiskit/0.45/qiskit.utils.mitigation.CompleteMeasFitter "qiskit.utils.mitigation.CompleteMeasFitter") and [`TensoredMeasFitter`](/api/qiskit/0.45/qiskit.utils.mitigation.TensoredMeasFitter "qiskit.utils.mitigation.TensoredMeasFitter") should be used. This was necessary as the `qiskit-ignis` project is now deprecated and will no longer be supported in the near future. It’s worth noting that unlike the equivalent classes from `qiskit-ignis` the versions from [`qiskit.utils.mitigation`](/api/qiskit/0.45/utils_mitigation#module-qiskit.utils.mitigation "qiskit.utils.mitigation") are supported only in their use with [`QuantumInstance`](/api/qiskit/0.45/qiskit.utils.QuantumInstance "qiskit.utils.QuantumInstance") (i.e. as a class not an instance with the `measurement_error_mitigation_cls` kwarg) and not intended for standalone use.
|
||
|
||
* The `Optimizer.optimize()` method for all the optimizers ([`Optimizer`](/api/qiskit/0.45/qiskit.algorithms.optimizers.Optimizer "qiskit.algorithms.optimizers.Optimizer") and derived classes) is now deprecated and will be removed in a future release. Instead, the [`Optimizer.minimize()`](/api/qiskit/0.45/qiskit.algorithms.optimizers.Optimizer#minimize "qiskit.algorithms.optimizers.Optimizer.minimize") method should be used which mimics the signature of SciPy’s `minimize()` function.
|
||
|
||
To replace the current optimize call with minimize you can replace
|
||
|
||
```python
|
||
xopt, fopt, nfev = optimizer.optimize(
|
||
num_vars,
|
||
objective_function,
|
||
gradient_function,
|
||
variable_bounds,
|
||
initial_point,
|
||
)
|
||
```
|
||
|
||
with
|
||
|
||
```python
|
||
result = optimizer.minimize(
|
||
fun=objective_function,
|
||
x0=initial_point,
|
||
jac=gradient_function,
|
||
bounds=variable_bounds,
|
||
)
|
||
xopt, fopt, nfev = result.x, result.fun, result.nfev
|
||
```
|
||
|
||
* Importing the `qiskit.util` module will now issue a `DeprecationWarning`. Users should instead import all the same functionality from [`qiskit.utils`](/api/qiskit/0.45/utils#module-qiskit.utils "qiskit.utils"). The `util` module has been deprecated since Terra 0.17, but previously did not issue a warning. It will be removed in Terra 0.20.
|
||
|
||
* The property `table` is deprecated, and will be removed in a future release. This is because [`SparsePauliOp`](/api/qiskit/0.45/qiskit.quantum_info.SparsePauliOp "qiskit.quantum_info.SparsePauliOp") has been updated to internally use `PauliList` instead of `PauliTable`. This is in order to significantly improve performance. You should now access the [`PauliList`](/api/qiskit/0.45/qiskit.quantum_info.PauliList "qiskit.quantum_info.PauliList") data by using the [`SparsePauliOp.paulis`](/api/qiskit/0.45/qiskit.quantum_info.SparsePauliOp#paulis "qiskit.quantum_info.SparsePauliOp.paulis") attribute.
|
||
|
||
<span id="release-notes-0-19-0-bug-fixes" />
|
||
|
||
<span id="id185" />
|
||
|
||
#### Bug Fixes
|
||
|
||
* Fixed a bug where many layout methods would ignore 3-or-more qubit gates, resulting in unexpected layout-allocation decisions. The transpiler pass [`Unroll3qOrMore`](/api/qiskit/0.45/qiskit.transpiler.passes.Unroll3qOrMore "qiskit.transpiler.passes.Unroll3qOrMore") is now being executed before the layout pass in all the preset pass managers when [`transpile()`](/api/qiskit/0.45/compiler#qiskit.compiler.transpile "qiskit.compiler.transpile") is called. Fixed [#7156](https://github.com/Qiskit/qiskit/issues/7156).
|
||
|
||
* Disassembled circuits now inherit calibrations from assembled [`QasmQobj`](/api/qiskit/0.45/qiskit.qobj.QasmQobj "qiskit.qobj.QasmQobj") and experiments. Fixes [#5348](https://github.com/Qiskit/qiskit/issues/5348).
|
||
|
||
* Fixed setting the `ansatz` or `optimizer` attributes of a [`VQE`](/api/qiskit/0.45/qiskit.algorithms.VQE "qiskit.algorithms.VQE") instance to `None` resulting in a buggy behavior. See [#7093](https://github.com/Qiskit/qiskit/issues/7093) for details.
|
||
|
||
* Fixed addition of [`PauliList`](/api/qiskit/0.45/qiskit.quantum_info.PauliList "qiskit.quantum_info.PauliList")s with `qargs`. The method used to raise a runtime error if the operands had different numbers of qubits.
|
||
|
||
* Fixed an issue causing an error when trying to compute a gradient with the [`CircuitGradient`](/api/qiskit/0.45/qiskit.opflow.gradients.CircuitGradient "qiskit.opflow.gradients.CircuitGradient") class for a gate that was not a supported gate. This bugfix transpiles a given gate to the set of supported gates for a requested gradient method. Fixes [#6918](https://github.com/Qiskit/qiskit/issues/6918).
|
||
|
||
* Removed calibration results when using error mitigation with the [`execute()`](/api/qiskit/0.45/qiskit.utils.QuantumInstance#execute "qiskit.utils.QuantumInstance.execute") method of [`QuantumInstance`](/api/qiskit/0.45/qiskit.utils.QuantumInstance "qiskit.utils.QuantumInstance"). Fixes [#7129](https://github.com/Qiskit/qiskit/issues/7129).
|
||
|
||
* Fixed a deprecation warning emitted when running [`QuantumCircuit.draw()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#draw "qiskit.circuit.QuantumCircuit.draw") or [`circuit_drawer()`](/api/qiskit/0.45/qiskit.visualization.circuit_drawer "qiskit.visualization.circuit_drawer") with Sympy 1.9 installed, mentioning the Sympy function `expr_free_symbols()`. The circuit drawers previously made use of this method when finding instances of symbolic constants.
|
||
|
||
* Fixed an issue where the `ax` kwarg and the `figwidth` option in the `style` kwarg for the `mpl` circuit drawer did not scale properly. Users can now pass an `ax` from a Matplotlib subplot to the `mpl` circuit drawer and the circuit will be drawn within the boundaries of that subplot. Alternatively, users can set the `figwidth` in inches in the `style` dict kwarg and the drawing will scale to the width in inches that was set. Fixed [#6367](https://github.com/Qiskit/qiskit/issues/6367).
|
||
|
||
* Fixed an issue with the [`circuit_drawer()`](/api/qiskit/0.45/qiskit.visualization.circuit_drawer "qiskit.visualization.circuit_drawer") function and [`draw()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#draw "qiskit.circuit.QuantumCircuit.draw") method of [`QuantumCircuit`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit"). When displaying a `measure` instruction targeted on a classical bit instead of a register, using the `latex` drawer option, the drawer would fail.
|
||
|
||
* Fixed an issue with the [`circuit_drawer()`](/api/qiskit/0.45/qiskit.visualization.circuit_drawer "qiskit.visualization.circuit_drawer") function and [`draw()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#draw "qiskit.circuit.QuantumCircuit.draw") method of [`QuantumCircuit`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit"). With any of the 3 drawer options, `mpl`, `latex`, or `text`, if a gate with a classical condition was encountered that was conditioned on a classical bit without a register, the drawer would fail.
|
||
|
||
* Fixed an issue with the [`circuit_drawer()`](/api/qiskit/0.45/qiskit.visualization.circuit_drawer "qiskit.visualization.circuit_drawer") function and [`draw()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#draw "qiskit.circuit.QuantumCircuit.draw") method of [`QuantumCircuit`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit"). With any of the 3 drawer options, `mpl`, `latex`, or `text`, if a gate with a classical condition was conditioned on the same classical bit as a `measure` and the bit that the measure targeted did not have a register, the drawer would fail.
|
||
|
||
* [`C3SXGate`](/api/qiskit/0.45/qiskit.circuit.library.C3SXGate "qiskit.circuit.library.C3SXGate") now has a correct decomposition and matrix representation. Previously it was equivalent to `SdgXGate().control(3)`, rather than the intended `SXGate().control(3)`.
|
||
|
||
* The member `name` of `qiskit.test.mock.utils.ConfigurableFakeBackend` has been changed to `backend_name`. This was done to avoid a conflict with the [`name()`](/api/qiskit/0.45/qiskit.providers.BackendV1#name "qiskit.providers.BackendV1.name") method inherited from the parent abstract [`BackendV1`](/api/qiskit/0.45/qiskit.providers.BackendV1 "qiskit.providers.BackendV1") class. This makes `ConfigurableFakeBackend` compatible with anything expecting a [`BackendV1`](/api/qiskit/0.45/qiskit.providers.BackendV1 "qiskit.providers.BackendV1") object. However, if you were using the `name` attribute directly before you will now need to either call it as a method or access the `backend_name` attribute instead.
|
||
|
||
* Fixed an issue where calling [`QuantumCircuit.decompose()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#decompose "qiskit.circuit.QuantumCircuit.decompose") on a circuit containing an [`Instruction`](/api/qiskit/0.45/qiskit.circuit.Instruction "qiskit.circuit.Instruction") whose [`definition`](/api/qiskit/0.45/qiskit.circuit.Instruction#definition "qiskit.circuit.Instruction.definition") attribute was empty would leave the instruction in place, instead of decomposing it into zero operations. For example, with a circuit:
|
||
|
||
```python
|
||
from qiskit.circuit import QuantumCircuit
|
||
empty = QuantumCircuit(1, name="decompose me!")
|
||
circuit = QuantumCircuit(1)
|
||
circuit.append(empty.to_gate(), [0])
|
||
```
|
||
|
||
Previously, calling `circuit.decompose()` would not change the circuit. Now, the decomposition will correct decompose `empty` into zero instructions. See [#6997](https://github.com/Qiskit/qiskit-terra/pull/6997) for more.
|
||
|
||
* Fixed an issue with the [`circuit_drawer()`](/api/qiskit/0.45/qiskit.visualization.circuit_drawer "qiskit.visualization.circuit_drawer") function and [`draw()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#draw "qiskit.circuit.QuantumCircuit.draw") method of [`QuantumCircuit`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit"). When displaying a `measure` instruction containing a classical `condition` using the `mpl` or `latex` options, the `condition` information would sometimes overwrite the `measure` display.
|
||
|
||
* Fixed an issue with the [`circuit_drawer()`](/api/qiskit/0.45/qiskit.visualization.circuit_drawer "qiskit.visualization.circuit_drawer") function and [`draw()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#draw "qiskit.circuit.QuantumCircuit.draw") method of [`QuantumCircuit`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit"). The `mpl` drawer used hex notation to display the `condition` value, whereas the `text` and `latex` drawers used decimal notation. Now all three drawers use hex notation.
|
||
|
||
* Fixed a bug in the Hoare optimizer transpilation pass where it could attempt to remove a gate twice if it could be separately combined with both its predecessor and its successor to form the identity. Refer to [#7271](https://github.com/Qiskit/qiskit/issues/7271) for more details.
|
||
|
||
* Making an instruction conditional with the standard [`InstructionSet.c_if()`](/api/qiskit/0.45/qiskit.circuit.InstructionSet#c_if "qiskit.circuit.InstructionSet.c_if") method with integer indices is now consistent with the numbering scheme used by the [`QuantumCircuit`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") the instructions are part of. Previously, if there were two [`ClassicalRegister`](/api/qiskit/0.45/qiskit.circuit.ClassicalRegister "qiskit.circuit.ClassicalRegister")s with overlapping [`Clbit`](/api/qiskit/0.45/qiskit.circuit.Clbit "qiskit.circuit.Clbit")s, the numbering would be incorrect. See [#7246](https://github.com/Qiskit/qiskit/issues/7246) for more detail.
|
||
|
||
* Making an instruction conditional with the standard [`InstructionSet.c_if()`](/api/qiskit/0.45/qiskit.circuit.InstructionSet#c_if "qiskit.circuit.InstructionSet.c_if") method will now succeed, even if there are no [`ClassicalRegister`](/api/qiskit/0.45/qiskit.circuit.ClassicalRegister "qiskit.circuit.ClassicalRegister")s in the circuit. See [#7250](https://github.com/Qiskit/qiskit/issues/7250) for more detail.
|
||
|
||
* Making an instruction conditional with the standard [`InstructionSet.c_if()`](/api/qiskit/0.45/qiskit.circuit.InstructionSet#c_if "qiskit.circuit.InstructionSet.c_if") method when using a [`Clbit`](/api/qiskit/0.45/qiskit.circuit.Clbit "qiskit.circuit.Clbit") that is contained in a [`ClassicalRegister`](/api/qiskit/0.45/qiskit.circuit.ClassicalRegister "qiskit.circuit.ClassicalRegister") of size one will now correctly create a condition on the bit, not the register. See [#7255](https://github.com/Qiskit/qiskit-terra/pull/7255) for more detail.
|
||
|
||
* Trying to make an instruction conditional with the standard [`InstructionSet.c_if()`](/api/qiskit/0.45/qiskit.circuit.InstructionSet#c_if "qiskit.circuit.InstructionSet.c_if") method will now correctly raise an error if the classical resource is not present in the circuit. See [#7255](https://github.com/Qiskit/qiskit-terra/pull/7255) for more detail.
|
||
|
||
* Fixed a compatibility issue with Matplotlib 3.5, where the Bloch sphere would fail to render if it had any vectors attached, such as by using [`plot_bloch_vector`](/api/qiskit/0.45/qiskit.visualization.plot_bloch_vector "qiskit.visualization.plot_bloch_vector"). See [#7272](https://github.com/Qiskit/qiskit/issues/7272) for more detail.
|
||
|
||
* Fixed an issue with the [`NLocal.add_layer()`](/api/qiskit/0.45/qiskit.circuit.library.NLocal#add_layer "qiskit.circuit.library.NLocal.add_layer") method incorrectly appending layers if the [`NLocal`](/api/qiskit/0.45/qiskit.circuit.library.NLocal "qiskit.circuit.library.NLocal") object had already been built.
|
||
|
||
* Fixed an issue with pickling [`InstructionScheduleMap`](/api/qiskit/0.45/qiskit.pulse.InstructionScheduleMap "qiskit.pulse.InstructionScheduleMap") object when using Python 3.6. See [#6944](https://github.com/Qiskit/qiskit/issues/6944) for details.
|
||
|
||
* Complex valued pulse parameter assignment with symengine has been fixed. For example,
|
||
|
||
```python
|
||
from qiskit import circuit, pulse
|
||
import numpy as np
|
||
|
||
amp = circuit.Parameter("amp")
|
||
phase = circuit.Parameter("phase")
|
||
|
||
with pulse.build() as sched:
|
||
pulse.play(pulse.Gaussian(160, amp * np.exp(1j * phase), 40), pulse.DriveChannel(0))
|
||
sched.assign_parameters({amp: 0.1, phase: 1.57}, inplace=True)
|
||
```
|
||
|
||
The assigned amplitude has been shown as `ParameterExpression(0.1*exp(1.57*I))` after the use of `symengine` was introduced in the 0.18.0 release. This is now correctly evaluated and shown as `7.96327e-05 + 0.0999999683j`.
|
||
|
||
* Fixed an issue where [`QAOA.construct_circuit()`](/api/qiskit/0.45/qiskit.algorithms.QAOA#construct_circuit "qiskit.algorithms.QAOA.construct_circuit") with different operators with same number of qubits would generate the same circuit each time. See [#7223](https://github.com/Qiskit/qiskit/issues/7223) for more detail.
|
||
|
||
* Fixed an issue where [`QAOAAnsatz`](/api/qiskit/0.45/qiskit.circuit.library.QAOAAnsatz "qiskit.circuit.library.QAOAAnsatz") had an incorrect number of parameters if identities of `PauliSumOp` were given, e.g., `PauliSumOp.from_list([("III", 1)])`. See [#7225](https://github.com/Qiskit/qiskit-terra/pull/7225) for more detail.
|
||
|
||
* Fixed a bug where the [`QuantumCircuit.qasm()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#qasm "qiskit.circuit.QuantumCircuit.qasm") method could return OpenQASM 2 instructions with invalid identifiers. The same bug was fixed for `UnitaryGate`.
|
||
|
||
* Fixed an issue where trying to display registerless bits would cause a failure of the `mpl` and the `latex` circuit drawers. A leading `_` has been removed from the display of registerless bits’ numbers in the `text` drawer. Fixed [#6732](https://github.com/Qiskit/qiskit/issues/6732).
|
||
|
||
* For one-bit registers, all of the circuit drawers now display only the register name and no longer show the `0` subscript. Fixed [#5784](https://github.com/Qiskit/qiskit/issues/5784).
|
||
|
||
* Fixed naming collisions of implicit registers in [`QuantumCircuit.qasm`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#qasm "qiskit.circuit.QuantumCircuit.qasm") when dealing with registerless qubits and clbits. Previously, registerless qubits and clbits were put into corresponding `qreg` and `creg` both called `regless`, despite the collision. They will now have separate, deterministically generated names, which will not clash with any user-defined register names in the circuit.
|
||
|
||
* Fixed an issue in scheduling of circuits with clbits operations, e.g. measurements, conditional gates, updating [`ASAPSchedule`](/api/qiskit/0.45/qiskit.transpiler.passes.ASAPSchedule "qiskit.transpiler.passes.ASAPSchedule"), [`ALAPSchedule`](/api/qiskit/0.45/qiskit.transpiler.passes.ALAPSchedule "qiskit.transpiler.passes.ALAPSchedule"), and [`AlignMeasures`](/api/qiskit/0.45/qiskit.transpiler.passes.AlignMeasures "qiskit.transpiler.passes.AlignMeasures"). The updated schedulers assume all clbits I/O operations take no time, `measure` writes the measured value to a clbit at the end, and `c_if` reads the conditional value in clbit(s) at the beginning. Fixed [#7006](https://github.com/Qiskit/qiskit/issues/7006).
|
||
|
||
* Calling [`transpile`](/api/qiskit/0.45/compiler#qiskit.compiler.transpile "qiskit.compiler.transpile") on an empty list will now correctly return an empty list without issuing a warning. Fixed [#7287](https://github.com/Qiskit/qiskit/issues/7287).
|
||
|
||
* Fixed an issue in [`PiecewiseChebyshev`](/api/qiskit/0.45/qiskit.circuit.library.PiecewiseChebyshev "qiskit.circuit.library.PiecewiseChebyshev") when the function to be approximated was constant. In these cases, you should now pass the constant directly as the `f_x` argument, rather than using a function, such as:
|
||
|
||
```python
|
||
from qiskit.circuit.library.arithmetic import PiecewiseChebyshev
|
||
|
||
PiecewiseChebyshev(1.0, degree=3)
|
||
```
|
||
|
||
See [#6707](https://github.com/Qiskit/qiskit-terra/pull/6707) for more details.
|
||
|
||
* If an `HHL` algorithm instance was constructed without a [`QuantumInstance`](/api/qiskit/0.45/qiskit.utils.QuantumInstance "qiskit.utils.QuantumInstance") (the default), attempts to use the getter and setter properties to read or set an instance later would fail. The getters and setters now work as expected.
|
||
|
||
* The [`QuantumCircuit.qasm()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#qasm "qiskit.circuit.QuantumCircuit.qasm") method now edits the names of copies of the instructions present in the circuit, not the original instructions that live in `circuit.data`. Refer to [#6952](https://github.com/Qiskit/qiskit/issues/6952) for more details.
|
||
|
||
* Fixed a bug in [`PauliSumOp.permute()`](/api/qiskit/0.45/qiskit.opflow.primitive_ops.PauliSumOp#permute "qiskit.opflow.primitive_ops.PauliSumOp.permute") causing the error:
|
||
|
||
```python
|
||
QiskitError: 'Pauli string label "" is not valid.'
|
||
```
|
||
|
||
if the permutation had the same number of Pauli terms. Calling `permute([2, 1, 0])` on `X ^ Y ^ Z` no longer raises an error, and now returns `Z ^ Y ^ X`.
|
||
|
||
* Fixed a bug where the parameter bounds for the mixer parameters in the [`QAOAAnsatz`](/api/qiskit/0.45/qiskit.circuit.library.QAOAAnsatz "qiskit.circuit.library.QAOAAnsatz") were not been set.
|
||
|
||
* Fixed determination of final operations (barriers and measures) in pass [`RemoveFinalMeasurements`](/api/qiskit/0.45/qiskit.transpiler.passes.RemoveFinalMeasurements "qiskit.transpiler.passes.RemoveFinalMeasurements") and in method [`remove_final_measurements()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#remove_final_measurements "qiskit.circuit.QuantumCircuit.remove_final_measurements") of class [`QuantumCircuit`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") which previously considered only nodes immediately preceding an output node.
|
||
|
||
* Fixed determination of final operations in pass [`RemoveFinalMeasurements`](/api/qiskit/0.45/qiskit.transpiler.passes.RemoveFinalMeasurements "qiskit.transpiler.passes.RemoveFinalMeasurements") and in method [`remove_final_measurements()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#remove_final_measurements "qiskit.circuit.QuantumCircuit.remove_final_measurements") of class [`QuantumCircuit`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") which could wrongly consider a barrier to be final, even if other circuit operations followed it.
|
||
|
||
* Fixed multi-bit classical register removal in pass [`RemoveFinalMeasurements`](/api/qiskit/0.45/qiskit.transpiler.passes.RemoveFinalMeasurements "qiskit.transpiler.passes.RemoveFinalMeasurements") and in method [`remove_final_measurements()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#remove_final_measurements "qiskit.circuit.QuantumCircuit.remove_final_measurements") of class [`QuantumCircuit`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") where classical registers were not removed even if other bits were idle, unless a final measure was done into each and every bit. Now, classical registers that become idle as a result of removing final measurements and barriers are always removed. Classical bits are removed if they are referenced only by removed registers or are not referenced at all and became idle due to the removal. This fix also adds proper handling of registers with shared underlying bits.
|
||
|
||
* Fixed an issue with [`RemoveFinalMeasurements`](/api/qiskit/0.45/qiskit.transpiler.passes.RemoveFinalMeasurements "qiskit.transpiler.passes.RemoveFinalMeasurements") which could cause the resulting [`DAGCircuit`](/api/qiskit/0.45/qiskit.dagcircuit.DAGCircuit "qiskit.dagcircuit.DAGCircuit") to become invalid. See [#7196](https://github.com/Qiskit/qiskit-terra/pull/7196) for more details.
|
||
|
||
* Fixed an issue with method [`remove_final_measurements()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#remove_final_measurements "qiskit.circuit.QuantumCircuit.remove_final_measurements") of class [`QuantumCircuit`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") that caused [`QuantumCircuit.clbits`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#clbits "qiskit.circuit.QuantumCircuit.clbits") to be incorrect after invocation. Refer to [#7089](https://github.com/Qiskit/qiskit/issues/7089) for details.
|
||
|
||
* When tapering an empty zero operator in [`qiskit.opflow`](/api/qiskit/0.45/opflow#module-qiskit.opflow "qiskit.opflow"), the code, on detecting it was zero, logged a warning and returned the original operator. Such operators are commonly found in the auxiliary operators, when using Qiskit Nature, and the above behavior caused `VQE` to throw an exception as tapered non-zero operators were a different number of qubits from the tapered zero operators (since taper has returned the input operator unchanged). The code will now correctly taper a zero operator such that the number of qubits is reduced as expected and matches to tapered non-zero operators e.g `` `0*"IIII"` `` when we are tapering by 3 qubits will become `0*"I"`.
|
||
|
||
* Fixed an issue with the [`draw()`](/api/qiskit/0.45/qiskit.circuit.QuantumCircuit#draw "qiskit.circuit.QuantumCircuit.draw") method and [`circuit_drawer()`](/api/qiskit/0.45/qiskit.visualization.circuit_drawer "qiskit.visualization.circuit_drawer") function, where a custom style set via the user config file (i.e. `settings.conf`) would ignore the set value of the `circuit_mpl_style` field if the `style` kwarg on the function/method was not set.
|
||
|
||
<span id="release-notes-0-19-0-other-notes" />
|
||
|
||
<span id="id186" />
|
||
|
||
#### Other Notes
|
||
|
||
* The string cast for [`qiskit.circuit.ParameterExpression`](/api/qiskit/0.45/qiskit.circuit.ParameterExpression "qiskit.circuit.ParameterExpression") does not have full precision anymore. This removes the trailing 0s when printing parameters that are bound to floats. This has consequences for QASM serialization and the circuit text drawer:
|
||
|
||
```python
|
||
>>> from qiskit.circuit import Parameter
|
||
>>> x = Parameter('x')
|
||
>>> str(x.bind({x:0.5}))
|
||
'0.5' # instead of '0.500000000000000'
|
||
```
|
||
|
||
* The [`QAOAAnsatz`](/api/qiskit/0.45/qiskit.circuit.library.QAOAAnsatz "qiskit.circuit.library.QAOAAnsatz") has been updated to use the parameter symbol `γ` for the cost operator and `β` for the mixer operator, as is the standard notation in QAOA literature.
|
||
|
||
<span id="id187" />
|
||
|
||
### Aer 0.9.1
|
||
|
||
No change
|
||
|
||
<span id="release-notes-ignis-0-7-0" />
|
||
|
||
<span id="id188" />
|
||
|
||
### Ignis 0.7.0
|
||
|
||
<span id="release-notes-ignis-0-7-0-prelude" />
|
||
|
||
<span id="id189" />
|
||
|
||
#### Prelude
|
||
|
||
This release deprecates the Qiskit Ignis project, it has been supersceded by the [Qiskit Experiments](https://qiskit.org/documentation/experiments/) project and active development has ceased. While deprecated, critical bug fixes and compatibility fixes will continue to be made to provide users a sufficient opportunity to migrate off of Ignis. After the deprecation period (which will be no shorter than 3 months from this release) the project will be retired and archived.
|
||
|
||
<span id="release-notes-ignis-0-7-0-new-features" />
|
||
|
||
<span id="id190" />
|
||
|
||
#### New Features
|
||
|
||
* Updated the accreditation protocol to use fitting routine from [https://arxiv.org/abs/2103.06603](https://arxiv.org/abs/2103.06603). `AccreditationFitter` now has methods FullAccreditation (previous protocol) and MeanAccreditation (new protocol). In addtition data entry has been changed to either use the result object AppendResult or a list of strings AppendStrings. `qiskit.ignis.verification.QOTPCorrectString()` was also added.
|
||
|
||
* Added the option for the fast analytical generation of syndrome graphs. The `RepetitionCode` now has a new bool argument `brute`, which allows to still use the brute force method. Helper class `RepetitionCodeSyndromeGenerator` added to facilitate this.
|
||
|
||
* The `RepetitionCode` now has keyword arguments `resets` and `delay`. The former determines whether reset gates are inserted after measurement. The latter allows a time (in dt) to be specificed for a delay after each measurement (and reset, if applicable).
|
||
|
||
The `syndrome_measurement()` method of `RepetitionCode` now has keyword arguments `final` and `delay`. The former determines whether to add reset gates according to the global `resets`, or to overwrite it with appropriate behavior for the final round of syndrome measurements. The latter allows a time (in dt) to be specificed for a delay after each measurement (and reset, if applicable).
|
||
|
||
* The `RepetitionCode` class now supports encoding with x basis states. This can be used by setting the `xbasis` keyword argument when constructing a `RepetitionCode` object.
|
||
|
||
<span id="release-notes-ignis-0-7-0-upgrade-notes" />
|
||
|
||
<span id="id191" />
|
||
|
||
#### Upgrade Notes
|
||
|
||
* The keyword argument `reset` has been removed from the the `syndrome_measurement()` method of `RepetitionCode`. This is replaced by the global `resets` keyword argument for the class as well as the keyword argument `final` for `syndrome_measurement`. In cases where one would previously add the final measurement round using `reset=False` to avoid the final reset gates, one should now use `final=True`.
|
||
|
||
* Remove `ParametrizedSchedule` from `update_u_gates()`.
|
||
|
||
`ParametrizedSchedule` was deprecated as a part of Qiskit-terra 0.17.0 and will be removed in next release. The function now updates u gates with `Schedule` programs involving unassigned `Parameter` objects.
|
||
|
||
<span id="release-notes-ignis-0-7-0-deprecation-notes" />
|
||
|
||
<span id="id192" />
|
||
|
||
#### Deprecation Notes
|
||
|
||
* Deprecating methods in `AccreditationFitter` namely bound\_variation\_distance and single\_protocol\_run
|
||
|
||
* The Qiskit Ignis project as a whole has been deprecated and the project will be retired and archived in the future. While deprecated only compatibility fixes and fixes for critical bugs will be made to the proejct. Instead of using Qiskit Ignis you should migrate to use [Qiskit Experiments](https://qiskit.org/documentation/experiments/) instead. You can refer to the migration guide:
|
||
|
||
[https://github.com/qiskit-community/qiskit-ignis#migration-guide](https://github.com/qiskit-community/qiskit-ignis#migration-guide)
|
||
|
||
<span id="qiskit-0-32-1" /> |