New features since last release
Qiskit 1.0 integration 🔌
-
This version of PennyLane makes it easier to import circuits from Qiskit. (#5218) (#5168)
The
qml.from_qiskit
function converts a Qiskit QuantumCircuit into a PennyLane quantum function. Althoughqml.from_qiskit
already exists in PennyLane, we have made a number of improvements to make importing from Qiskit easier. And yes —qml.from_qiskit
functionality is compatible with both Qiskit 1.0 and earlier versions! Here's a comprehensive list of the improvements:-
You can now append PennyLane measurements onto the quantum function returned by
qml.from_qiskit
. Consider this simple Qiskit circuit:import pennylane as qml from qiskit import QuantumCircuit qc = QuantumCircuit(2) qc.rx(0.785, 0) qc.ry(1.57, 1)
We can convert it into a PennyLane QNode in just a few lines, with PennyLane
measurements
easily included:>>> dev = qml.device("default.qubit") >>> measurements = qml.expval(qml.Z(0) @ qml.Z(1)) >>> qfunc = qml.from_qiskit(qc, measurements=measurements) >>> qnode = qml.QNode(qfunc, dev) >>> qnode() tensor(0.00056331, requires_grad=True)
-
Quantum circuits that already contain Qiskit-side measurements can be faithfully converted with
qml.from_qiskit
. Consider this example Qiskit circuit:qc = QuantumCircuit(3, 2) # Teleportation qc.rx(0.9, 0) # Prepare input state on qubit 0 qc.h(1) # Prepare Bell state on qubits 1 and 2 qc.cx(1, 2) qc.cx(0, 1) # Perform teleportation qc.h(0) qc.measure(0, 0) qc.measure(1, 1) with qc.if_test((1, 1)): # Perform first conditional qc.x(2)
This circuit can be converted into PennyLane with the Qiskit measurements still accessible. For example, we can use those results as inputs to a mid-circuit measurement in PennyLane:
@qml.qnode(dev) def teleport(): m0, m1 = qml.from_qiskit(qc)() qml.cond(m0, qml.Z)(2) return qml.density_matrix(2)
>>> teleport() tensor([[0.81080498+0.j , 0. +0.39166345j], [0. -0.39166345j, 0.18919502+0.j ]], requires_grad=True)
-
It is now more intuitive to handle and differentiate parametrized Qiskit circuits. Consider the following circuit:
from qiskit.circuit import Parameter from pennylane import numpy as np angle0 = Parameter("x") angle1 = Parameter("y") qc = QuantumCircuit(2, 2) qc.rx(angle0, 0) qc.ry(angle1, 1) qc.cx(1, 0)
We can convert this circuit into a QNode with two arguments, corresponding to
x
andy
:measurements = qml.expval(qml.PauliZ(0)) qfunc = qml.from_qiskit(qc, measurements) qnode = qml.QNode(qfunc, dev)
The QNode can be evaluated and differentiated:
>>> x, y = np.array([0.4, 0.5], requires_grad=True) >>> qnode(x, y) tensor(0.80830707, requires_grad=True) >>> qml.grad(qnode)(x, y) (tensor(-0.34174675, requires_grad=True), tensor(-0.44158016, requires_grad=True))
This shows how easy it is to make a Qiskit circuit differentiable with PennyLane.
-
In addition to circuits, it is also possible to convert operators from Qiskit to PennyLane with a new function called
qml.from_qiskit_op
. (#5251)A Qiskit SparsePauliOp can be converted to a PennyLane operator using
qml.from_qiskit_op
:>>> from qiskit.quantum_info import SparsePauliOp >>> qiskit_op = SparsePauliOp(["II", "XY"]) >>> qiskit_op SparsePauliOp(['II', 'XY'], coeffs=[1.+0.j, 1.+0.j]) >>> pl_op = qml.from_qiskit_op(qiskit_op) >>> pl_op I(0) + X(1) @ Y(0)
Combined with
qml.from_qiskit
, it becomes easy to quickly calculate quantities like expectation values by converting the whole workflow to PennyLane:qc = QuantumCircuit(2) # Create circuit qc.rx(0.785, 0) qc.ry(1.57, 1) measurements = qml.expval(pl_op) # Create QNode qfunc = qml.from_qiskit(qc, measurements) qnode = qml.QNode(qfunc, dev)
>>> qnode() # Evaluate! tensor(0.29317504, requires_grad=True)
-
Native mid-circuit measurements on Default Qubit 💡
-
Mid-circuit measurements can now be more scalable and efficient in finite-shots mode with
default.qubit
by simulating them in a similar way to what happens on quantum hardware. (#5088) (#5120)Previously, mid-circuit measurements (MCMs) would be automatically replaced with an additional qubit using the
@qml.defer_measurements
transform. The circuit below would have required thousands of qubits to simulate.Now, MCMs are performed in a similar way to quantum hardware with finite shots on
default.qubit
. For each shot and each time an MCM is encountered, the device evaluates the probability of projecting onto|0>
or|1>
and makes a random choice to collapse the circuit state. This approach works well when there are a lot of MCMs and the number of shots is not too high.import pennylane as qml dev = qml.device("default.qubit", shots=10) @qml.qnode(dev) def f(): for i in range(1967): qml.Hadamard(0) qml.measure(0) return qml.sample(qml.PauliX(0))
>>> f() tensor([-1, -1, -1, 1, 1, -1, 1, -1, 1, -1], requires_grad=True)
Work easily and efficiently with operators 🔧
-
Over the past few releases, PennyLane's approach to operator arithmetic has been in the process of being overhauled. We have a few objectives:
- To make it as easy to work with PennyLane operators as it would be with pen and paper.
- To improve the efficiency of operator arithmetic.
The updated operator arithmetic functionality is still being finalized, but can be activated using
qml.operation.enable_new_opmath()
. In the next release, the new behaviour will become the default, so we recommend enabling now to become familiar with the new system!The following updates have been made in this version of PennyLane:
-
You can now easily access Pauli operators via
I
,X
,Y
, andZ
: (#5116)>>> from pennylane import I, X, Y, Z >>> X(0) X(0) ``` The original long-form names `Identity`, `PauliX`, `PauliY`, and `PauliZ` remain available, but use of the short-form names is now recommended.
-
A new
qml.commutator
function is now available that allows you to compute commutators between PennyLane operators. (#5051) (#5052) (#5098)>>> qml.commutator(X(0), Y(0)) 2j * Z(0)
-
Operators in PennyLane can have a backend Pauli representation, which can be used to perform faster operator arithmetic. Now, the Pauli representation will be automatically used for calculations when available. (#4989) (#5001) (#5003) (#5017) (#5027)
The Pauli representation can be optionally accessed via
op.pauli_rep
:>>> qml.operation.enable_new_opmath() >>> op = X(0) + Y(0) >>> op.pauli_rep 1.0 * X(0) + 1.0 * Y(0)
-
Extensive improvements have been made to the string representations of PennyLane operators, making them shorter and possible to copy-paste as valid PennyLane code. (#5116) (#5138)
>>> 0.5 * X(0) 0.5 * X(0) >>> 0.5 * (X(0) + Y(1)) 0.5 * (X(0) + Y(1))
Sums with many terms are broken up into multiple lines, but can still be copied back as valid code:
>>> 0.5 * (X(0) @ X(1)) + 0.7 * (X(1) @ X(2)) + 0.8 * (X(2) @ X(3)) ( 0.5 * (X(0) @ X(1)) + 0.7 * (X(1) @ X(2)) + 0.8 * (X(2) @ X(3)) )
-
Linear combinations of operators and operator multiplication via
Sum
andProd
, respectively, have been updated to reach feature parity withHamiltonian
andTensor
, respectively. This should minimize the effort to port over any existing code. (#5070) (#5132) (#5133)Updates include support for grouping via the
pauli
module:>>> obs = [X(0) @ Y(1), Z(0), Y(0) @ Z(1), Y(1)] >>> qml.pauli.group_observables(obs) [[Y(0) @ Z(1)], [X(0) @ Y(1), Y(1)], [Z(0)]]
New Clifford device 🦾
-
A new
default.clifford
device enables efficient simulation of large-scale Clifford circuits defined in PennyLane through the use of stim as a backend. (#4936) (#4954) (#5144)Given a circuit with only Clifford gates, one can use this device to obtain the usual range of PennyLane measurements as well as the state represented in the Tableau form of Aaronson & Gottesman (2004):
import pennylane as qml dev = qml.device("default.clifford", tableau=True) @qml.qnode(dev) def circuit(): qml.CNOT(wires=[0, 1]) qml.PauliX(wires=[1]) qml.ISWAP(wires=[0, 1]) qml.Hadamard(wires=[0]) return qml.state()
>>> circuit() array([[0, 1, 1, 0, 0], [1, 0, 1, 1, 1], [0, 0, 0, 1, 0], [1, 0, 0, 1, 1]])
The
default.clifford
device also supports thePauliError
,DepolarizingChannel
,BitFlip
andPhaseFlip
noise channels when operating in finite-shot mode.
Improvements 🛠
Faster gradients with VJPs and other performance improvements
-
Vector-Jacobian products (VJPs) can result in faster computations when the output of your quantum Node has a low dimension. They can be enabled by setting
device_vjp=True
when loading a QNode. In the next release of PennyLane, VJPs are planned to be used by default, when available.In this release, we have unlocked:
-
Adjoint device VJPs can be used with
jax.jacobian
, meaning thatdevice_vjp=True
is always faster when using JAX withdefault.qubit
. (#4963) -
PennyLane can now use lightning-provided VJPs. (#4914)
-
VJPs can be used with TensorFlow, though support has not yet been added for
tf.Function
and Tensorflow Autograph. (#4676)
-
-
Measuring
qml.probs
is now faster due to an optimization in converting samples to counts. (#5145) -
The performance of circuit-cutting workloads with large numbers of generated tapes has been improved. (#5005)
-
Queueing (
AnnotatedQueue
) has been removed fromqml.cut_circuit
andqml.cut_circuit_mc
to improve performance for large workflows. (#5108)
Community contributions 🥳
-
A new function called
qml.fermi.parity_transform
has been added for parity mapping of a fermionic Hamiltonian. (#4928)It is now possible to transform a fermionic Hamiltonian to a qubit Hamiltonian with parity mapping.
import pennylane as qml fermi_ham = qml.fermi.FermiWord({(0, 0) : '+', (1, 1) : '-'}) qubit_ham = qml.fermi.parity_transform(fermi_ham, n=6)
>>> print(qubit_ham)
-0.25j * Y(0) + (-0.25+0j) * (X(0) @ Z(1)) + (0.25+0j) * X(0) + 0.25j * (Y(0) @ Z(1))
-
The transform
split_non_commuting
now accepts measurements of typeprobs
,sample
, andcounts
, which accept both wires and observables. (#4972) -
The efficiency of matrix calculations when an operator is symmetric over a given set of wires has been improved. (#3601)
-
The
pennylane/math/quantum.py
module now has support for computing the minimum entropy of a density matrix. (#3959)>>> x = [1, 0, 0, 1] / np.sqrt(2) >>> x = qml.math.dm_from_state_vector(x) >>> qml.math.min_entropy(x, indices=[0]) 0.6931471805599455
-
A function called
apply_operation
that applies operations to device-compatible states has been added to the newqutrit_mixed
module found inqml.devices
. (#5032) -
A function called
measure
has been added to the newqutrit_mixed
module found inqml.devices
that measures device-compatible states for a collection of measurement processes. (#5049) -
A
partial_trace
function has been added toqml.math
for taking the partial trace of matrices. (#5152)
Other operator arithmetic improvements
-
The following capabilities have been added for Pauli arithmetic: (#4989) (#5001) (#5003) (#5017) (#5027) (#5018)
-
You can now multiply
PauliWord
andPauliSentence
instances by scalars (e.g.,0.5 * PauliWord({0: "X"})
or0.5 * PauliSentence({PauliWord({0: "X"}): 1.})
). -
You can now intuitively add and subtract
PauliWord
andPauliSentence
instances and scalars together (scalars are treated implicitly as multiples of the identity,I
). For example,ps1 + pw1 + 1.
for some Pauli wordpw1 = PauliWord({0: "X", 1: "Y"})
and Pauli sentenceps1 = PauliSentence({pw1: 3.})
. -
You can now element-wise multiply
PauliWord
,PauliSentence
, and operators together withqml.dot
(e.g.,qml.dot([0.5, -1.5, 2], [pw1, ps1, id_word])
withid_word = PauliWord({})
). -
qml.matrix
now acceptsPauliWord
andPauliSentence
instances (e.g.,qml.matrix(PauliWord({0: "X"}))
). -
It is now possible to compute commutators with Pauli operators natively with the new
commutator
method.>>> op1 = PauliWord({0: "X", 1: "X"}) >>> op2 = PauliWord({0: "Y"}) + PauliWord({1: "Y"}) >>> op1.commutator(op2) 2j * Z(0) @ X(1) + 2j * X(0) @ Z(1)
-
-
Composite operations (e.g., those made with
qml.prod
andqml.sum
) and scalar-product operations convertHamiltonian
andTensor
operands toSum
andProd
types, respectively. This helps avoid the mixing of incompatible operator types. (#5031) (#5063) -
qml.Identity()
can be initialized without wires. Measuring it is currently not possible, though. (#5106) -
qml.dot
now returns aSum
class even when all the coefficients match. (#5143) -
qml.pauli.group_observables
now supports groupingProd
andSProd
operators. (#5070) -
The performance of converting a
PauliSentence
to aSum
has been improved. (#5141) (#5150) -
Akin to
qml.Hamiltonian
features, the coefficients and operators that make up composite operators formed viaSum
orProd
can now be accessed with theterms()
method. (#5132) (#5133) (#5164)>>> qml.operation.enable_new_opmath() >>> op = X(0) @ (0.5 * X(1) + X(2)) >>> op.terms() ([0.5, 1.0], [X(1) @ X(0), X(2) @ X(0)])
-
String representations of
ParametrizedHamiltonian
have been updated to match the style of other PL operators. (#5215)
Other improvements
-
The
pl-device-test
suite is now compatible with theqml.devices.Device
interface. (#5229) -
The
QSVT
operation now determines itsdata
from the block encoding and projector operator data. (#5226) (#5248) -
The
BlockEncode
operator is now JIT-compatible with JAX. (#5110) -
The
qml.qsvt
function usesqml.GlobalPhase
instead ofqml.exp
to define a global phase. (#5105) -
The
tests/ops/functions/conftest.py
test has been updated to ensure that all operator types are tested for validity. (#4978) -
A new
pennylane.workflow
module has been added. This module now containsqnode.py
,execution.py
,set_shots.py
,jacobian_products.py
, and the submoduleinterfaces
. (#5023) -
A more informative error is now raised when calling
adjoint_jacobian
with trainable state-prep operations. (#5026) -
qml.workflow.get_transform_program
andqml.workflow.construct_batch
have been added to inspect the transform program and batch of tapes at different stages. (#5084) -
All custom controlled operations such as
CRX
,CZ
,CNOT
,ControlledPhaseShift
now inherit fromControlledOp
, giving them additional properties such ascontrol_wire
andcontrol_values
. Callingqml.ctrl
onRX
,RY
,RZ
,Rot
, andPhaseShift
with a single control wire will return gates of typesCRX
,CRY
, etc. as opposed to a generalControlled
operator. (#5069) (#5199) -
The CI will now fail if coverage data fails to upload to codecov. Previously, it would silently pass and the codecov check itself would never execute. (#5101)
-
qml.ctrl
called on operators with custom controlled versions will now return instances of the custom class, and it will flatten nested controlled operators to a single multi-controlled operation. ForPauliX
,CNOT
,Toffoli
, andMultiControlledX
, callingqml.ctrl
will always resolve to the best option inCNOT
,Toffoli
, orMultiControlledX
depending on the number of control wires and control values. (#5125) -
Unwanted warning filters have been removed from tests and no
PennyLaneDeprecationWarning
s are being raised unexpectedly. (#5122) -
New error tracking and propagation functionality has been added (#5115) (#5121)
-
The method
map_batch_transform
has been replaced with the method_batch_transform
implemented inTransformDispatcher
. (#5212) -
TransformDispatcher
can now dispatch onto a batch of tapes, making it easier to compose transforms when working in the tape paradigm. (#5163) -
qml.ctrl
is now a simple wrapper that either calls PennyLane's built increate_controlled_op
or uses the Catalyst implementation. (#5247) -
Controlled composite operations can now be decomposed using ZYZ rotations. (#5242)
-
New functions called
qml.devices.modifiers.simulator_tracking
andqml.devices.modifiers.single_tape_support
have been added to add basic default behavior onto a device class. (#5200)
Breaking changes 💔
-
Passing additional arguments to a transform that decorates a QNode must now be done through the use of
functools.partial
. (#5046) -
qml.ExpvalCost
has been removed. Users should useqml.expval()
moving forward. (#5097) -
Caching of executions is now turned off by default when
max_diff == 1
, as the classical overhead cost outweighs the probability that duplicate circuits exists. (#5243) -
The entry point convention registering compilers with PennyLane has changed. (#5140)
To allow for packages to register multiple compilers with PennyLane, the
entry_points
convention under the designated group namepennylane.compilers
has been modified.Previously, compilers would register
qjit
(JIT decorator),ops
(compiler-specific operations), andcontext
(for tracing and program capture).Now, compilers must register
compiler_name.qjit
,compiler_name.ops
, andcompiler_name.context
, wherecompiler_name
is replaced by the name of the provided compiler.For more information, please see the documentation on adding compilers.
-
PennyLane source code is now compatible with the latest version of
black
. (#5112) (#5119) -
gradient_analysis_and_validation
has been renamed tofind_and_validate_gradient_methods
. Instead of returning a list, it now returns a dictionary of gradient methods for each parameter index, and no longer mutates the tape. (#5035) -
Multiplying two
PauliWord
instances no longer returns a tuple(new_word, coeff)
but insteadPauliSentence({new_word: coeff})
. The old behavior is still available with the private methodPauliWord._matmul(other)
for faster processing. (#5045) -
Observable.return_type
has been removed. Instead, you should inspect the type of the surrounding measurement process. (#5044) -
ClassicalShadow.entropy()
no longer needs anatol
keyword as a better method to estimate entropies from approximate density matrix reconstructions (with potentially negative eigenvalues). (#5048) -
Controlled operators with a custom controlled version decompose like how their controlled counterpart decomposes as opposed to decomposing into their controlled version. (#5069) (#5125)
For example:
>>> qml.ctrl(qml.RX(0.123, wires=1), control=0).decomposition() [ RZ(1.5707963267948966, wires=[1]), RY(0.0615, wires=[1]), CNOT(wires=[0, 1]), RY(-0.0615, wires=[1]), CNOT(wires=[0, 1]), RZ(-1.5707963267948966, wires=[1]) ]
-
QuantumScript.is_sampled
andQuantumScript.all_sampled
have been removed. Users should now validate these properties manually. (#5072) -
qml.transforms.one_qubit_decomposition
andqml.transforms.two_qubit_decomposition
have been removed. Instead, you should useqml.ops.one_qubit_decomposition
andqml.ops.two_qubit_decomposition
. (#5091)
Deprecations 👋
-
Calling
qml.matrix
without providing awire_order
on objects where the wire order could be ambiguous now raises a warning. In the future, thewire_order
argument will be required in these cases. (#5039) -
Operator.validate_subspace(subspace)
has been relocated to theqml.ops.qutrit.parametric_ops
module and will be removed from the Operator class in an upcoming release. (#5067) -
Matrix and tensor products between
PauliWord
andPauliSentence
instances are done using the@
operator,*
will be used only for scalar multiplication. Note also the breaking change that the product of twoPauliWord
instances now returns aPauliSentence
instead of a tuple(new_word, coeff)
. (#4989) (#5054) -
MeasurementProcess.name
andMeasurementProcess.data
are now deprecated, as they contain dummy values that are no longer needed. (#5047) (#5071) (#5076) (#5122) -
qml.pauli.pauli_mult
andqml.pauli.pauli_mult_with_phase
are now deprecated. Instead, you should useqml.simplify(qml.prod(pauli_1, pauli_2))
to get the reduced operator. (#5057) -
The private functions
_pauli_mult
,_binary_matrix
and_get_pauli_map
from thepauli
module have been deprecated, as they are no longer used anywhere and the same functionality can be achieved using newer features in thepauli
module. (#5057) -
Sum.ops
,Sum.coeffs
,Prod.ops
andProd.coeffs
will be deprecated in the future. (#5164)
Documentation 📝
-
The module documentation for
pennylane.tape
now explains the difference betweenQuantumTape
andQuantumScript
. (#5065) -
A typo in a code example in the
qml.transforms
API has been fixed. (#5014) -
Documentation for
qml.data
has been updated and now mentions a way to access the same dataset simultaneously from multiple environments. (#5029) -
A clarification for the definition of
argnum
added to gradient methods has been made. (#5035) -
A typo in the code example for
qml.qchem.dipole_of
has been fixed. (#5036) -
A development guide on deprecations and removals has been added. (#5083)
-
A note about the eigenspectrum of second-quantized Hamiltonians has been added to
qml.eigvals
. (#5095) -
A warning about two mathematically equivalent Hamiltonians undergoing different time evolutions has been added to
qml.TrotterProduct
andqml.ApproxTimeEvolution
. (#5137) -
A reference to the paper that provides the image of the
qml.QAOAEmbedding
template has been added. (#5130) -
The docstring of
qml.sample
has been updated to advise the use of single-shot expectations instead when differentiating a circuit. (#5237) -
A quick start page has been added called "Importing Circuits". This explains how to import quantum circuits and operations defined outside of PennyLane. (#5281)
Bug fixes 🐛
-
QubitChannel
can now be used with jitting. (#5288) -
Fixed a bug in the matplotlib drawer where the colour of
Barrier
did not match the requested style. (#5276) -
qml.draw
andqml.draw_mpl
now apply all applied transforms before drawing. (#5277) -
ctrl_decomp_zyz
is now differentiable. (#5198) -
qml.ops.Pow.matrix()
is now differentiable with TensorFlow with integer exponents. (#5178) -
The
qml.MottonenStatePreparation
template has been updated to include a global phase operation. (#5166) -
Fixed a queuing bug when using
qml.prod
with a quantum function that queues a single operator. (#5170) -
The
qml.TrotterProduct
template has been updated to accept scalar products of operators as an input Hamiltonian. (#5073) -
Fixed a bug where caching together with JIT compilation and broadcasted tapes yielded wrong results
Operator.hash
now depends on the memory location,id
, of a JAX tracer instead of its string representation. (#3917) -
qml.transforms.undo_swaps
can now work with operators with hyperparameters or nesting. (#5081) -
qml.transforms.split_non_commuting
will now pass the original shots along. (#5081) -
If
argnum
is provided to a gradient transform, only the parameters specified inargnum
will have their gradient methods validated. (#5035) -
StatePrep
operations expanded onto more wires are now compatible with backprop. (#5028) -
qml.equal
works well withqml.Sum
operators when wire labels are a mix of integers and strings. (#5037) -
The return value of
Controlled.generator
now contains a projector that projects onto the correct subspace based on the control value specified. (#5068) -
CosineWindow
no longer raises an unexpected error when used on a subset of wires at the beginning of a circuit. (#5080) -
tf.function
now works withTensorSpec(shape=None)
by skipping batch size computation. (#5089) -
PauliSentence.wires
no longer imposes a false order. (#5041) -
qml.qchem.import_state
now applies the chemist-to-physicist sign convention when initializing a PennyLane state vector from classically pre-computed wavefunctions. That is, it interleaves spin-up/spin-down operators for the same spatial orbital index, as standard in PennyLane (instead of commuting all spin-up operators to the left, as is standard in quantum chemistry). (#5114) -
Multi-wire controlled
CNOT
andPhaseShift
are now be decomposed correctly. (#5125) (#5148) -
draw_mpl
no longer raises an error when drawing a circuit containing an adjoint of a controlled operation. (#5149) -
default.mixed
no longer throwsValueError
when applying a state vector that is not of typecomplex128
when used with tensorflow. (#5155) -
ctrl_decomp_zyz
no longer raises aTypeError
if the rotation parameters are of typetorch.Tensor
(#5183) -
Comparing
Prod
andSum
objects now works regardless of nested structure withqml.equal
if the operators have a validpauli_rep
property. (#5177) -
Controlled
GlobalPhase
with non-zero control wires no longer throws an error. (#5194) -
A
QNode
transformed withmitigate_with_zne
now accepts batch parameters. (#5195) -
The matrix of an empty
PauliSentence
instance is now correct (all-zeros). Further, matrices of emptyPauliWord
andPauliSentence
instances can now be turned into matrices. (#5188) -
PauliSentence
instances can handle matrix multiplication withPauliWord
instances. (#5208) -
CompositeOp.eigendecomposition
is now JIT-compatible. (#5207) -
QubitDensityMatrix
now works with JAX-JIT on thedefault.mixed
device. (#5203) (#5236) -
When a QNode specifies
diff_method="adjoint"
,default.qubit
no longer tries to decompose non-trainable operations with non-scalar parameters such asQubitUnitary
. (#5233) -
The overwriting of the class names of
I
,X
,Y
, andZ
no longer happens in the initialization after causing problems with datasets. This now happens globally. (#5252) -
The
adjoint_metric_tensor
transform now works withjax
. (#5271)
Contributors ✍️
This release contains contributions from (in alphabetical order):
Abhishek Abhishek, Mikhail Andrenkov, Utkarsh Azad, Trenten Babcock, Gabriel Bottrill, Thomas Bromley, Astral Cai, Skylar Chan, Isaac De Vlugt, Diksha Dhawan, Lillian Frederiksen, Pietropaolo Frisoni, Eugenio Gigante, Diego Guala, David Ittah, Soran Jahangiri, Jacky Jiang, Korbinian Kottmann, Christina Lee, Xiaoran Li, Vincent Michaud-Rioux, Romain Moyard, Pablo Antonio Moreno Casares, Erick Ochoa Lopez, Lee J. O'Riordan, Mudit Pandey, Alex Preciado, Matthew Silverman, Jay Soni.