diff --git a/doc/releases/changelog-0.27.0.md b/doc/releases/changelog-0.27.0.md
index 0094d58f45d..b1fa90337f1 100644
--- a/doc/releases/changelog-0.27.0.md
+++ b/doc/releases/changelog-0.27.0.md
@@ -4,145 +4,235 @@
New features since last release
-(TODO: title) JAX JIT
+An all-new data module πΎ
-(TODO: title) Qutrits
+* The `qml.data` module is now available, allowing users to download, load, and create quantum datasets.
+ [(#3156)](https://github.com/PennyLaneAI/pennylane/pull/3156)
-* The `qml.GellMann` qutrit observable, the ternary generalization of the Pauli observables, is now available.
- ([#3035](https://github.com/PennyLaneAI/pennylane/pull/3035))
+ Datasets are hosted on Xanadu Cloud and can be downloaded by using `qml.data.load()`:
- When using `qml.GellMann`, the `index` keyword argument determines which of the 8 Gell-Mann matrices is used.
+ ```pycon
+ >>> H2_datasets = qml.data.load(
+ ... data_name="qchem", molname="H2", basis="STO-3G", bondlength=1.1
+ ... )
+ >>> H2data = H2_datasets[0]
+ >>> H2data
+
+ ```
- ```python
- dev = qml.device("default.qutrit", wires=2)
+ - Datasets available to be downloaded can be listed with `qml.data.list_datasets()`.
- @qml.qnode(dev)
- def circuit():
- qml.TClock(wires=0)
- qml.TShift(wires=1)
- qml.TAdd(wires=[0, 1])
- return qml.expval(qml.GellMann(wires=0, index=8) + qml.GellMann(wires=1, index=3))
- ```
+ - To download or load only specific properties of a dataset, we can specify the desired properties in `qml.data.load` with the `attributes` keyword argument:
- ```pycon
- >>> circuit()
- -0.42264973081037416
- ```
+ ```pycon
+ >>> H2_hamiltonian = qml.data.load(
+ ... data_name="qchem", molname="H2", basis="STO-3G", bondlength=1.1,
+ ... attributes=["molecule", "hamiltonian"]
+ ... )[0]
+ >>> H2_hamiltonian.hamiltonian
+
+ ```
-* Controlled qutrit operations can now be performed with `qml.ControlledQutritUnitary`.
- ([#2844](https://github.com/PennyLaneAI/pennylane/pull/2844))
+ The available attributes can be found using `qml.data.list_attributes()`:
- The control wires and values that define the operation are defined analogously to the qubit operation.
+ - To select data interactively, we can use `qml.data.load_interactive()`:
- ```python
- dev = qml.device("default.qutrit", wires=3)
+ ```pycon
+ >>> qml.data.load_interactive()
+ Please select a data name:
+ 1) qspin
+ 2) qchem
+ Choice [1-2]: 1
+ Please select a sysname:
+ ...
+ Please select a periodicity:
+ ...
+ Please select a lattice:
+ ...
+ Please select a layout:
+ ...
+ Please select attributes:
+ ...
+ Force download files? (Default is no) [y/N]: N
+ Folder to download to? (Default is pwd, will download to /datasets subdirectory):
+
+ Please confirm your choices:
+ dataset: qspin/Ising/open/rectangular/4x4
+ attributes: ['parameters', 'ground_states']
+ force: False
+ dest folder: datasets
+ Would you like to continue? (Default is yes) [Y/n]:
+
+ ```
- @qml.qnode(dev)
- def circuit(U):
- qml.TShift(wires=0)
- qml.TAdd(wires=[0, 1])
- qml.ControlledQutritUnitary(U, control_wires=[0, 1], control_values='12', wires=2)
- return qml.state()
+ - Once a dataset is loaded, its properties can be accessed as follows:
+
+ ```pycon
+ >>> dev = qml.device("default.qubit",wires=4)
+ >>> @qml.qnode(dev)
+ ... def circuit():
+ ... qml.BasisState(H2data.hf_state, wires = [0, 1, 2, 3])
+ ... for op in H2data.vqe_gates:
+ ... qml.apply(op)
+ ... return qml.expval(H2data.hamiltonian)
+ >>> print(circuit())
+ -1.0791430411076344
+ ```
+
+ It's also possible to create custom datasets with `qml.data.Dataset`:
+
+ ```pycon
+ >>> example_hamiltonian = qml.Hamiltonian(coeffs=[1,0.5], observables=[qml.PauliZ(wires=0),qml.PauliX(wires=1)])
+ >>> example_energies, _ = np.linalg.eigh(qml.matrix(example_hamiltonian))
+ >>> example_dataset = qml.data.Dataset(
+ ... data_name = 'Example', hamiltonian=example_hamiltonian, energies=example_energies
+ ... )
+ >>> example_dataset.data_name
+ 'Example'
+ >>> example_dataset.hamiltonian
+ (0.5) [X1]
+ + (1) [Z0]
+ >>> example_dataset.energies
+ array([-1.5, -0.5, 0.5, 1.5])
```
+ Custom datasets can be saved and read with the `qml.data.Dataset.write()` and `qml.data.Dataset.read()` methods, respectively.
+
```pycon
- >>> U = np.array([[1, 1, 0], [1, -1, 0], [0, 0, np.sqrt(2)]]) / np.sqrt(2)
- >>> circuit(U)
- tensor([0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,
- 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,
- 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,
- 0.+0.j, 0.+0.j, 0.+0.j], requires_grad=True)
+ >>> example_dataset.write('./path/to/dataset.dat')
+ >>> read_dataset = qml.data.Dataset()
+ >>> read_dataset.read('./path/to/dataset.dat')
+ >>> read_dataset.data_name
+ 'Example'
+ >>> read_dataset.hamiltonian
+ (0.5) [X1]
+ + (1) [Z0]
+ >>> read_dataset.energies
+ array([-1.5, -0.5, 0.5, 1.5])
```
-(TODO: title) QChem
+ We will continue to work on adding more datasets and features for `qml.data` in future releases.
+
+Adaptive optimization πποΈπ
-* Grouped coefficients, observables, and basis rotation transformation matrices needed to construct a qubit Hamiltonian in the rotated basis of molecular orbitals are now calculable via `qml.qchem.basis_rotation()`.
- ([#3011](https://github.com/PennyLaneAI/pennylane/pull/3011))
+* Optimizing quantum circuits can now be done *adaptively* with
+ `qml.AdaptiveOptimizer`.
+ [(#3192)](https://github.com/PennyLaneAI/pennylane/pull/3192)
- ```pycon
- >>> symbols = ['H', 'H']
- >>> geometry = np.array([[0.0, 0.0, 0.0], [1.398397361, 0.0, 0.0]], requires_grad = False)
- >>> mol = qml.qchem.Molecule(symbols, geometry)
- >>> core, one, two = qml.qchem.electron_integrals(mol)()
- >>> coeffs, ops, unitaries = qml.qchem.basis_rotation(one, two, tol_factor=1.0e-5)
- >>> unitaries
- [tensor([[-1.00000000e+00, -5.46483514e-13],
- [ 5.46483514e-13, -1.00000000e+00]], requires_grad=True),
- tensor([[-1.00000000e+00, 3.17585063e-14],
- [-3.17585063e-14, -1.00000000e+00]], requires_grad=True),
- tensor([[-0.70710678, -0.70710678],
- [-0.70710678, 0.70710678]], requires_grad=True),
- tensor([[ 2.58789009e-11, 1.00000000e+00],
- [-1.00000000e+00, 2.58789009e-11]], requires_grad=True)]
+ The `qml.AdaptiveOptimizer` takes an initial circuit and a collection of operators as input and adds a selected gate to the circuit at each optimization step. The process of growing the circuit can be repeated until the circuit gradients converge to zero within a given threshold. The adaptive optimizer can be used to implement algorithms such as ADAPT-VQE as shown in the following example.
+
+ Firstly, we define some preliminary variables needed for VQE:
+
+ ```python
+ symbols = ["H", "H", "H"]
+ geometry = np.array([[0.01076341, 0.04449877, 0.0],
+ [0.98729513, 1.63059094, 0.0],
+ [1.87262415, -0.00815842, 0.0]], requires_grad=False)
+ H, qubits = qml.qchem.molecular_hamiltonian(symbols, geometry, charge = 1)
```
-* Any gate operation can now be tapered according to :math:`\mathbb{Z}_2` symmetries of the Hamiltonian via `qml.qchem.taper_operation`.
- [(#3002)](https://github.com/PennyLaneAI/pennylane/pull/3002)
+ The collection of gates to grow the circuit is built to contain all single and double excitations:
- ```pycon
- >>> symbols = ['He', 'H']
- >>> geometry = np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 1.4589]])
- >>> mol = qml.qchem.Molecule(symbols, geometry, charge=1)
- >>> H, n_qubits = qml.qchem.molecular_hamiltonian(symbols, geometry)
- >>> generators = qml.qchem.symmetry_generators(H)
- >>> paulixops = qml.qchem.paulix_ops(generators, n_qubits)
- >>> paulix_sector = qml.qchem.optimal_sector(H, generators, mol.n_electrons)
- >>> tap_op = qml.qchem.taper_operation(qml.SingleExcitation, generators, paulixops,
- ... paulix_sector, wire_order=H.wires, op_wires=[0, 2])
- >>> tap_op(3.14159)
- [Exp(1.570795j PauliY)]
+ ```python
+ n_electrons = 2
+ singles, doubles = qml.qchem.excitations(n_electrons, qubits)
+ singles_excitations = [qml.SingleExcitation(0.0, x) for x in singles]
+ doubles_excitations = [qml.DoubleExcitation(0.0, x) for x in doubles]
+ operator_pool = doubles_excitations + singles_excitations
```
- Moreover, the obtained tapered operation can be used directly within a QNode.
+ Next, an initial circuit that prepares a Hartree-Fock state and returns the expectation value of the Hamiltonian is defined:
- ```pycon
- >>> dev = qml.device('default.qubit', wires=[0, 1])
- >>> @qml.qnode(dev)
- ... def circuit(params):
- ... tap_op(params[0])
- ... return qml.expval(qml.PauliZ(0) @ qml.PauliZ(1))
- >>> drawer = qml.draw(circuit, show_all_wires=True)
- >>> print(drawer(params=[3.14159]))
- 0: ββExp(0.00+1.57j Y)ββ€ β
- 1: βββββββββββββββββββββ€ β°
+ ```python
+ hf_state = qml.qchem.hf_state(n_electrons, qubits)
+ dev = qml.device("default.qubit", wires=qubits)
+ @qml.qnode(dev)
+ def circuit():
+ qml.BasisState(hf_state, wires=range(qubits))
+ return qml.expval(H)
```
-(TODO: title) New operators and optimizers
+ Finally, the optimizer is instantiated and then the circuit is created and optimized adaptively:
-* Optimizing quantum circuits can now be done *adaptively* with `qml.AdaptiveOptimizer`.
- [(#3192)](https://github.com/PennyLaneAI/pennylane/pull/3192)
+ ```python
+ opt = qml.optimize.AdaptiveOptimizer()
+ for i in range(len(operator_pool)):
+ circuit, energy, gradient = opt.step_and_cost(circuit, operator_pool, drain_pool=True)
+ print('Energy:', energy)
+ print(qml.draw(circuit)())
+ print('Largest Gradient:', gradient)
+ print()
+ if gradient < 1e-3:
+ break
+ ```
- The `qml.AdaptiveOptimizer` optimizer takes an initial circuit and a collection of operators
- as input and adds a selected gate to the circuits at each optimization step. The process of
- growing the circuit can be repeated until the circuit gradients converge to zero within a given
- threshold. The adaptive optimizer can be used to implement algorithms such as `ADAPT-VQE`.
+ ```pycon
+ Energy: -1.246549938420637
+ 0: ββBasisState(M0)ββGΒ²(0.20)ββ€ β<π>
+ 1: ββBasisState(M0)ββGΒ²(0.20)ββ€ β<π>
+ 2: ββBasisState(M0)ββββββββββββ€ β<π>
+ 3: ββBasisState(M0)ββββββββββββ€ β<π>
+ 4: ββBasisState(M0)ββGΒ²(0.20)ββ€ β<π>
+ 5: ββ°BasisState(M0)ββ°GΒ²(0.20)ββ€ β°<π>
+ Largest Gradient: 0.14399872776755085
+
+ Energy: -1.2613740231529604
+ 0: ββBasisState(M0)ββGΒ²(0.20)ββGΒ²(0.19)ββ€ β<π>
+ 1: ββBasisState(M0)ββGΒ²(0.20)ββGΒ²(0.19)ββ€ β<π>
+ 2: ββBasisState(M0)ββββββββββββGΒ²(0.19)ββ€ β<π>
+ 3: ββBasisState(M0)ββββββββββββ°GΒ²(0.19)ββ€ β<π>
+ 4: ββBasisState(M0)ββGΒ²(0.20)ββββββββββββ€ β<π>
+ 5: ββ°BasisState(M0)ββ°GΒ²(0.20)ββββββββββββ€ β°<π>
+ Largest Gradient: 0.1349349562423238
+
+ Energy: -1.2743971719780331
+ 0: ββBasisState(M0)ββGΒ²(0.20)ββGΒ²(0.19)βββββββββββ€ β<π>
+ 1: ββBasisState(M0)ββGΒ²(0.20)ββGΒ²(0.19)ββG(0.00)ββ€ β<π>
+ 2: ββBasisState(M0)ββββββββββββGΒ²(0.19)βββββββββββ€ β<π>
+ 3: ββBasisState(M0)ββββββββββββ°GΒ²(0.19)ββ°G(0.00)ββ€ β<π>
+ 4: ββBasisState(M0)ββGΒ²(0.20)βββββββββββββββββββββ€ β<π>
+ 5: ββ°BasisState(M0)ββ°GΒ²(0.20)βββββββββββββββββββββ€ β°<π>
+ Largest Gradient: 0.00040841755397108586
+ ```
- For a detailed breakdown of its implementation, check out [our demo!](https://pennylane.ai/qml/demos/tutorial_adaptive_circuits.html)
+ For a detailed breakdown of its implementation, check out the [Adaptive circuits for quantum chemistry
+ demo](https://pennylane.ai/qml/demos/tutorial_adaptive_circuits.html).
-* The `IntegerComparator` arithmetic operation is now available.
-[(#3113)](https://github.com/PennyLaneAI/pennylane/pull/3113)
+Automatic interface detection π§©
- Given a basis state :math:`\vert n \rangle`, where :math:`n` is a positive integer, and a fixed positive integer :math:`L`, the `IntegerComparator` operator flips a target qubit if :math:`n \geq L`. Alternatively, the flipping condition can be :math:`n < L` as demonstrated below:
+* QNodes now accept an `auto` interface argument which automatically detects the machine learning library to use.
+ [(#3132)](https://github.com/PennyLaneAI/pennylane/pull/3132)
```python
+ from pennylane import numpy as np
+ import torch
+ import tensorflow as tf
+ from jax import numpy as jnp
+
dev = qml.device("default.qubit", wires=2)
+ @qml.qnode(dev, interface="auto")
+ def circuit(weight):
+ qml.RX(weight[0], wires=0)
+ qml.RY(weight[1], wires=1)
+ return qml.expval(qml.PauliZ(0))
- @qml.qnode(dev)
- def circuit():
- qml.BasisState(np.array([0, 1]), wires=range(2))
- qml.broadcast(qml.Hadamard, wires=range(2), pattern='single')
- qml.IntegerComparator(2, geq=False, wires=[0, 1])
- return qml.state()
+ interface_tensors = [[0, 1], np.array([0, 1]), torch.Tensor([0, 1]), tf.Variable([0, 1], dtype=float), jnp.array([0, 1])]
+ for tensor in interface_tensors:
+ res = circuit(weight=tensor)
+ print(f"Result value: {res:.2f}; Result type: {type(res)}")
```
```pycon
- >>> circuit()
- [-0.5+0.j 0.5+0.j -0.5+0.j 0.5+0.j]
+ Result value: 1.00; Result type:
+ Result value: 1.00; Result type:
+ Result value: 1.00; Result type:
+ Result value: 1.00; Result type:
+ Result value: 1.00; Result type:
```
-(TODO: title) QNode QoL boosts
+Upgraded JAX-JIT gradient support π
-* Added support to the JAX-JIT interface for computing the gradient of QNodes that return a single vector of probabilities or multiple expectation values.
+* JAX-JIT support for computing the gradient of QNodes that return a single vector of probabilities or multiple expectation values is now available.
[(#3244)](https://github.com/PennyLaneAI/pennylane/pull/3244)
[(#3261)](https://github.com/PennyLaneAI/pennylane/pull/3261)
@@ -174,32 +264,183 @@
Note that this change depends on `jax.pure_callback`, which requires `jax>=0.3.17`.
-* The `QNode` class now accepts an `auto` interface, which automatically detects the interface of the given input.
- [(#3132)](https://github.com/PennyLaneAI/pennylane/pull/3132)
+Construct Pauli words and sentences π€
+
+* We've reorganized and grouped everything in PennyLane responsible for manipulating Pauli operators into a `pauli` module. The `grouping` module has been deprecated as a result, and logic was moved from `pennylane/grouping` to `pennylane/pauli/grouping`.
+ [(#3179)](https://github.com/PennyLaneAI/pennylane/pull/3179)
+* `qml.pauli.PauliWord` and `qml.pauli.PauliSentence` can be used to represent tensor products and linear combinations of Pauli operators, respectively. These provide a more performant method to compute sums and products of Pauli operators.
+ [(#3195)](https://github.com/PennyLaneAI/pennylane/pull/3195)
+
+ - `qml.pauli.PauliWord` represents tensor products of Pauli operators. We can efficiently multiply and extract the matrix of these operators using this representation.
+
+ ```pycon
+ >>> pw1 = qml.pauli.PauliWord({0:"X", 1:"Z"})
+ >>> pw2 = qml.pauli.PauliWord({0:"Y", 1:"Z"})
+ >>> pw1, pw2
+ (X(0) @ Z(1), Y(0) @ Z(1))
+ >>> pw1 * pw2
+ (Z(0), 1j)
+ >>> pw1.to_mat(wire_order=[0,1])
+ array([[ 0, 0, 1, 0],
+ [ 0, 0, 0, -1],
+ [ 1, 0, 0, 0],
+ [ 0, -1, 0, 0]])
+ ```
+
+ - `qml.pauli.PauliSentence` represents linear combinations of Pauli words. We can efficiently add, multiply and extract the matrix of these operators in this representation.
+
+ ```pycon
+ >>> ps1 = qml.pauli.PauliSentence({pw1: 1.2, pw2: 0.5j})
+ >>> ps2 = qml.pauli.PauliSentence({pw1: -1.2})
+ >>> ps1
+ 1.2 * X(0) @ Z(1)
+ + 0.5j * Y(0) @ Z(1)
+ >>> ps1 + ps2
+ 0.0 * X(0) @ Z(1)
+ + 0.5j * Y(0) @ Z(1)
+ >>> ps1 * ps2
+ -1.44 * I
+ + (-0.6+0j) * Z(0)
+ >>> (ps1 + ps2).to_mat(wire_order=[0,1])
+ array([[ 0. +0.j, 0. +0.j, 0.5+0.j, 0. +0.j],
+ [ 0. +0.j, 0. +0.j, 0. +0.j, -0.5+0.j],
+ [-0.5+0.j, 0. +0.j, 0. +0.j, 0. +0.j],
+ [ 0. +0.j, 0.5+0.j, 0. +0.j, 0. +0.j]])
+ ```
+
+(Experimental) More support for multi-measurement and gradient output types π§ͺ
+
+* `qml.enable_return()` now supports QNodes returning multiple measurements,
+ including shots vectors, and gradient output types.
+ [(#2886)](https://github.com/PennyLaneAI/pennylane/pull/2886)
+ [(#3052)](https://github.com/PennyLaneAI/pennylane/pull/3052)
+ [(#3041)](https://github.com/PennyLaneAI/pennylane/pull/3041)
+ [(#3090)](https://github.com/PennyLaneAI/pennylane/pull/3090)
+ [(#3069)](https://github.com/PennyLaneAI/pennylane/pull/3069)
+ [(#3137)](https://github.com/PennyLaneAI/pennylane/pull/3137)
+ [(#3127)](https://github.com/PennyLaneAI/pennylane/pull/3127)
+ [(#3099)](https://github.com/PennyLaneAI/pennylane/pull/3099)
+ [(#3098)](https://github.com/PennyLaneAI/pennylane/pull/3098)
+ [(#3095)](https://github.com/PennyLaneAI/pennylane/pull/3095)
+ [(#3091)](https://github.com/PennyLaneAI/pennylane/pull/3091)
+ [(#3176)](https://github.com/PennyLaneAI/pennylane/pull/3176)
+ [(#3170)](https://github.com/PennyLaneAI/pennylane/pull/3170)
+ [(#3194)](https://github.com/PennyLaneAI/pennylane/pull/3194)
+ [(#3267)](https://github.com/PennyLaneAI/pennylane/pull/3267)
+ [(#3234)](https://github.com/PennyLaneAI/pennylane/pull/3234)
+ [(#3232)](https://github.com/PennyLaneAI/pennylane/pull/3232)
+ [(#3223)](https://github.com/PennyLaneAI/pennylane/pull/3223)
+ [(#3222)](https://github.com/PennyLaneAI/pennylane/pull/3222)
+ [(#3315)](https://github.com/PennyLaneAI/pennylane/pull/3315)
+
+ In v0.25, we introduced `qml.enable_return()`, which separates measurements into their own tensors. The motivation of this change is the deprecation of ragged `ndarray` creation in NumPy.
+
+ With this release, we're continuing to elevate this feature by adding support for:
+
+ - Execution (`qml.execute`)
+ - Jacobian vector product (JVP) computation
+ - Gradient transforms (`qml.gradients.param_shift`, `qml.gradients.finite_diff`, `qml.gradients.hessian_transform`, `qml.gradients.param_shift_hessian`).
+
+ - Interfaces (Autograd, TensorFlow, and JAX, although without JIT)
+
+ With this added support, the JAX interface can handle multiple shots (shots vectors), measurements, and gradient output types with `qml.enable_return()`:
+
```python
- dev = qml.device("default.qubit", wires=2)
- @qml.qnode(dev, interface="auto")
- def circuit(weight):
- qml.RX(weight[0], wires=0)
- qml.RY(weight[1], wires=1)
- return qml.expval(qml.PauliZ(0))
+ import jax
- interface_tensors = [[0, 1], np.array([0, 1]), torch.Tensor([0, 1]), tf.Variable([0, 1], dtype=float), jnp.array([0, 1])]
- for tensor in interface_tensors:
- res = circuit(weight=tensor)
- print(f"Result value: {res:.2f}; Result type: {type(res)}")
+ qml.enable_return()
+ dev = qml.device("default.qubit", wires=2, shots=(1, 10000))
+
+ params = jax.numpy.array([0.1, 0.2])
+
+ @qml.qnode(dev, interface="jax", diff_method="parameter-shift", max_diff=2)
+ def circuit(x):
+ qml.RX(x[0], wires=[0])
+ qml.RY(x[1], wires=[1])
+ qml.CNOT(wires=[0, 1])
+ return qml.var(qml.PauliZ(0) @ qml.PauliX(1)), qml.probs(wires=[0])
```
```pycon
- Result value: 1.00; Result type:
- Result value: 1.00; Result type:
- Result value: 1.00; Result type:
- Result value: 1.00; Result type:
- Result value: 1.00; Result type:
+ >>> jax.hessian(circuit)(params)
+ ((DeviceArray([[ 0., 0.],
+ [ 2., -3.]], dtype=float32),
+ DeviceArray([[[-0.5, 0. ],
+ [ 0. , 0. ]],
+ [[ 0.5, 0. ],
+ [ 0. , 0. ]]], dtype=float32)),
+ (DeviceArray([[ 0.07677898, 0.0563341 ],
+ [ 0.07238522, -1.830669 ]], dtype=float32),
+ DeviceArray([[[-4.9707499e-01, 2.9999996e-04],
+ [-6.2500127e-04, 1.2500001e-04]],
+ [[ 4.9707499e-01, -2.9999996e-04],
+ [ 6.2500127e-04, -1.2500001e-04]]], dtype=float32)))
+ ```
+
+ For more details, please [refer to the documentation](https://docs.pennylane.ai/en/stable/code/api/pennylane.enable_return.html?highlight=enable_return#pennylane.enable_return).
+
+New basis rotation and tapering features in qml.qchem π€
+
+* Grouped coefficients, observables, and basis rotation transformation matrices needed to construct a qubit Hamiltonian in the rotated basis of molecular orbitals are now calculable via `qml.qchem.basis_rotation()`.
+ ([#3011](https://github.com/PennyLaneAI/pennylane/pull/3011))
+
+ ```pycon
+ >>> symbols = ['H', 'H']
+ >>> geometry = np.array([[0.0, 0.0, 0.0], [1.398397361, 0.0, 0.0]], requires_grad = False)
+ >>> mol = qml.qchem.Molecule(symbols, geometry)
+ >>> core, one, two = qml.qchem.electron_integrals(mol)()
+ >>> coeffs, ops, unitaries = qml.qchem.basis_rotation(one, two, tol_factor=1.0e-5)
+ >>> unitaries
+ [tensor([[-1.00000000e+00, -5.46483514e-13],
+ [ 5.46483514e-13, -1.00000000e+00]], requires_grad=True),
+ tensor([[-1.00000000e+00, 3.17585063e-14],
+ [-3.17585063e-14, -1.00000000e+00]], requires_grad=True),
+ tensor([[-0.70710678, -0.70710678],
+ [-0.70710678, 0.70710678]], requires_grad=True),
+ tensor([[ 2.58789009e-11, 1.00000000e+00],
+ [-1.00000000e+00, 2.58789009e-11]], requires_grad=True)]
```
+* Any gate operation can now be tapered according to :math:`\mathbb{Z}_2` symmetries of the Hamiltonian via `qml.qchem.taper_operation`.
+ [(#3002)](https://github.com/PennyLaneAI/pennylane/pull/3002)
+ [(#3121)](https://github.com/PennyLaneAI/pennylane/pull/3121)
+
+ ```pycon
+ >>> symbols = ['He', 'H']
+ >>> geometry = np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 1.4589]])
+ >>> mol = qml.qchem.Molecule(symbols, geometry, charge=1)
+ >>> H, n_qubits = qml.qchem.molecular_hamiltonian(symbols, geometry)
+ >>> generators = qml.qchem.symmetry_generators(H)
+ >>> paulixops = qml.qchem.paulix_ops(generators, n_qubits)
+ >>> paulix_sector = qml.qchem.optimal_sector(H, generators, mol.n_electrons)
+ >>> tap_op = qml.qchem.taper_operation(qml.SingleExcitation, generators, paulixops,
+ ... paulix_sector, wire_order=H.wires, op_wires=[0, 2])
+ >>> tap_op(3.14159)
+ [Exp(1.5707949999999993j PauliY)]
+ ```
+
+ Moreover, the obtained tapered operation can be used directly within a QNode.
+
+ ```pycon
+ >>> dev = qml.device('default.qubit', wires=[0, 1])
+ >>> @qml.qnode(dev)
+ ... def circuit(params):
+ ... tap_op(params[0])
+ ... return qml.expval(qml.PauliZ(0) @ qml.PauliZ(1))
+ >>> drawer = qml.draw(circuit, show_all_wires=True)
+ >>> print(drawer(params=[3.14159]))
+ 0: ββExp(0.00+1.57j Y)ββ€ β
+ 1: βββββββββββββββββββββ€ β°
+ ```
+
+* Functionality has been added to estimate the number of measurements required to compute an expectation value with a target error and estimate the error in computing an expectation value with a given number of measurements.
+ [(#3000)](https://github.com/PennyLaneAI/pennylane/pull/3000)
+
+New functions, operations, and observables π€©
+
* Wires of operators or entire QNodes can now be mapped to other wires via `qml.map_wires()`.
+ [(#3143)](https://github.com/PennyLaneAI/pennylane/pull/3143)
[(#3145)](https://github.com/PennyLaneAI/pennylane/pull/3145)
The `qml.map_wires()` function requires a dictionary representing a wire map. Use it with
@@ -215,6 +456,9 @@
(RX(0.54, wires=[10]) + PauliX(wires=[11])) + (PauliZ(wires=[12]) @ RY(1.23, wires=[13]))
```
+ A `map_wires` method has also been added to operators, which returns a copy
+ of the operator with its wires changed according to the given wire map.
+
- entire QNodes:
```python
@@ -236,143 +480,84 @@
tensor([0.92885434, 0.07114566], requires_grad=True)
>>> print(qml.draw(mapped_circuit)())
A: ββRX(0.54)ββ€ Probs
- B: ββXβββββββββ€
- C: ββZβββββββββ€
- D: ββRY(1.23)ββ€
+ B: ββXβββββββββ€
+ C: ββZβββββββββ€
+ D: ββRY(1.23)ββ€
```
-(TODO: title) Data Module
+* The `qml.IntegerComparator` arithmetic operation is now available.
+[(#3113)](https://github.com/PennyLaneAI/pennylane/pull/3113)
-* Added the `data` module to allow downloading, loading, and creating quantum datasets.
+ Given a basis state :math:`\vert n \rangle`, where :math:`n` is a positive integer, and a fixed positive integer :math:`L`, `qml.IntegerComparator` flips a target qubit if :math:`n \geq L`. Alternatively, the flipping condition can be :math:`n < L` as demonstrated below:
-* Datasets hosted on the cloud can be downloaded with the `qml.data.load` function as follows:
+ ```python
+ dev = qml.device("default.qubit", wires=2)
- ```pycon
- >>> H2datasets = qml.data.load("qchem", molname="H2", basis="STO-3G", bondlength=1.1)
- >>> print(H2datasets)
- []
- >>> H2data = H2datasets[0]
+ @qml.qnode(dev)
+ def circuit():
+ qml.BasisState(np.array([0, 1]), wires=range(2))
+ qml.broadcast(qml.Hadamard, wires=range(2), pattern='single')
+ qml.IntegerComparator(2, geq=False, wires=[0, 1])
+ return qml.state()
```
-* To see what datasets are available for download, we can call `qml.data.list_datasets`:
-
```pycon
- >>> available_data = qml.data.list_datasets()
- >>> available_data.keys()
- dict_keys(["qspin", "qchem"])
- >>> available_data["qchem"].keys()
- dict_keys(["H2", "LiH", ...])
- >>> available_data['qchem']['H2'].keys()
- dict_keys(["6-31G", "STO-3G"])
- >>> print(available_data['qchem']['H2']['STO-3G'])
- ["0.5", "0.54", "0.62", "0.66", ...]
+ >>> circuit()
+ [-0.5+0.j 0.5+0.j -0.5+0.j 0.5+0.j]
```
-* To download or load only specific properties of a dataset, we can specify the desired attributes in `qml.data.load`:
+* The `qml.GellMann` qutrit observable, the ternary generalization of the Pauli observables, is now available.
+ [(#3035)](https://github.com/PennyLaneAI/pennylane/pull/3035)
- ```pycon
- >>> part = qml.data.load("qchem", molname="H2", basis="STO-3G", bondlength=1.1,
- ... attributes=["molecule", "fci_energy"])[0]
- >>> part.molecule
-
- >>> part.fci_energy
- -1.0791924385860894
- ```
+ When using `qml.GellMann`, the `index` keyword argument determines which of the 8 Gell-Mann matrices is used.
-* The available `attributes` can be found using `qml.data.list_attributes`:
+ ```python
+ dev = qml.device("default.qutrit", wires=2)
- ```pycon
- >>> qml.data.list_attributes(data_name='qchem')
- ['molecule',
- 'hamiltonian',
- 'sparse_hamiltonian',
- ...
- 'tapered_hamiltonian',
- 'full']
+ @qml.qnode(dev)
+ def circuit():
+ qml.TClock(wires=0)
+ qml.TShift(wires=1)
+ qml.TAdd(wires=[0, 1])
+ return qml.expval(qml.GellMann(wires=0, index=8) + qml.GellMann(wires=1, index=3))
```
-* To select data interactively by following a series of prompts, we can use `qml.data.load_interactive` as follows:
-
```pycon
- >>> qml.data.load_interactive()
- Please select a data name:
- 1) qspin
- 2) qchem
- Choice [1-2]: 1
- Please select a sysname:
- ...
- Please select a periodicity:
- ...
- Please select a lattice:
- ...
- Please select a layout:
- ...
- Please select attributes:
- ...
- Force download files? (Default is no) [y/N]: N
- Folder to download to? (Default is pwd, will download to /datasets subdirectory):
-
- Please confirm your choices:
- dataset: qspin/Ising/open/rectangular/4x4
- attributes: ['parameters', 'ground_states']
- force: False
- dest folder: /Users/jovyan/Downloads/datasets
- Would you like to continue? (Default is yes) [Y/n]:
-
- ```
+ >>> circuit()
+ -0.42264973081037416
+ ```
-* Once loaded, properties of a dataset can be accessed easily as follows:
+* Controlled qutrit operations can now be performed with `qml.ControlledQutritUnitary`.
+ ([#2844](https://github.com/PennyLaneAI/pennylane/pull/2844))
- ```pycon
- >>> dev = qml.device("default.qubit",wires=4)
- >>> @qml.qnode(dev)
- ... def circuit():
- ... qml.BasisState(H2_dataset.hf_state, wires = [0, 1, 2, 3])
- ... for op in H2_dataset.vqe_gates:
- ... qml.apply(op)
- ... return qml.expval(H2_dataset.hamiltonian)
- >>> print(circuit())
- -1.0791430411076344
- ```
+ The control wires and values that define the operation are defined analogously to the qubit operation.
-* It is also possible to create custom datasets with `qml.data.Dataset`
+ ```python
+ dev = qml.device("default.qutrit", wires=3)
- ```pycon
- >>> coeffs = [1, 0.5]
- >>> observables = [qml.PauliZ(wires=0), qml.PauliX(wires=1)]
- >>> H = qml.Hamiltonian(coeffs, observables)
- >>> energies, _ = np.linalg.eigh(qml.matrix(H)) #Calculate the energies
- >>> dataset = qml.data.Dataset(data_name = "Example", hamiltonian=H, energies=energies)
- >>> dataset.data_name
- "Example"
- >>> dataset.hamiltonian
- (0.5) [X1]
- + (1) [Z0]
- >>> dataset.energies
- array([-1.5, -0.5, 0.5, 1.5])
+ @qml.qnode(dev)
+ def circuit(U):
+ qml.TShift(wires=0)
+ qml.TAdd(wires=[0, 1])
+ qml.ControlledQutritUnitary(U, control_wires=[0, 1], control_values='12', wires=2)
+ return qml.state()
```
-* These custom datasets can be saved and read with the `Dataset.write` and `Dataset.read` functions as follows:
-
```pycon
- >>> dataset.write("./path/to/dataset.dat")
- >>> read_dataset = qml.data.Dataset()
- >>> read_dataset.read("./path/to/dataset.dat")
- >>> read_dataset.data_name
- 'Example'
- >>> read_dataset.hamiltonian
- (0.5) [X1]
- + (1) [Z0]
- >>> read_dataset.energies
- array([-1.5, -0.5, 0.5, 1.5])
+ >>> U = np.array([[1, 1, 0], [1, -1, 0], [0, 0, np.sqrt(2)]]) / np.sqrt(2)
+ >>> circuit(U)
+ tensor([0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,
+ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,
+ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,
+ 0.+0.j, 0.+0.j, 0.+0.j], requires_grad=True)
```
Improvements
-* Adds a Python 3.11 classification to the PennyLane package.
+* PennyLane now supports Python 3.11!
[(#3297)](https://github.com/PennyLaneAI/pennylane/pull/3297)
-* Added a `samples_computational_basis` attribute to the `MeasurementProcess` and `QuantumScript` classes to track if computational basis samples are being generated when `qml.sample` or `qml.counts` are called without specifying an observable.
+* `qml.sample` and `qml.counts` work more efficiently and track if computational basis samples are being generated when they are called without specifying an observable.
[(#3207)](https://github.com/PennyLaneAI/pennylane/pull/3207)
* The parameters of a basis set containing a different number of Gaussian functions are now easier to differentiate.
@@ -381,9 +566,6 @@
* Printing a `qml.MultiControlledX` operator now shows the `control_values` keyword argument.
[(#3113)](https://github.com/PennyLaneAI/pennylane/pull/3113)
-* The matrix passed to `qml.Hermitian` is now validated when creating the observable if the input is not abstract.
- [(#3181)](https://github.com/PennyLaneAI/pennylane/pull/3181)
-
* `qml.simplify` and transforms like `qml.matrix`, `batch_transform`, `hamiltonian_expand`, and `split_non_commuting` now work with
`QuantumScript` as well as `QuantumTape`.
[(#3209)](https://github.com/PennyLaneAI/pennylane/pull/3209)
@@ -391,37 +573,34 @@
* A redundant flipping of the initial state in the UCCSD and kUpCCGSD templates has been removed.
[(#3148)](https://github.com/PennyLaneAI/pennylane/pull/3148)
-* `Adjoint` now supports batching if the base operation supports batching.
+* `qml.adjoint` now supports batching if the base operation supports batching.
[(#3168)](https://github.com/PennyLaneAI/pennylane/pull/3168)
-* `OrbitalRotation` is now decomposed into two `SingleExcitation` operations for faster execution and more efficient parameter-shift gradient calculations on devices that natively support `SingleExcitation`.
+* `qml.OrbitalRotation` is now decomposed into two `qml.SingleExcitation` operations for faster execution and more efficient parameter-shift gradient calculations on devices that natively support `qml.SingleExcitation`.
[(#3171)](https://github.com/PennyLaneAI/pennylane/pull/3171)
-* Reorganized and grouped all functions in PennyLane responsible for manipulation of Pauli operators into a `pauli`
- module. Deprecated the `grouping` module and moved logic from `pennylane/grouping` to `pennylane/pauli/grouping`.
- [(#3179)](https://github.com/PennyLaneAI/pennylane/pull/3179)
+* The `Exp` class decomposes into a `PauliRot` class if the coefficient is imaginary and the base operator is a Pauli Word.
+ [(#3249)](https://github.com/PennyLaneAI/pennylane/pull/3249)
-* Added the `Operator` attributes `has_decomposition` and `has_adjoint` that indicate
+* Added the operator attributes `has_decomposition` and `has_adjoint` that indicate
whether a corresponding `decomposition` or `adjoint` method is available.
[(#2986)](https://github.com/PennyLaneAI/pennylane/pull/2986)
* Structural improvements are made to `QueuingManager`, formerly `QueuingContext`, and `AnnotatedQueue`.
[(#2794)](https://github.com/PennyLaneAI/pennylane/pull/2794)
[(#3061)](https://github.com/PennyLaneAI/pennylane/pull/3061)
-
- * `QueuingContext` is renamed to `QueuingManager`.
- * `QueuingManager` should now be the global communication point for putting queuable objects into the active queue.
- * `QueuingManager` is no longer an abstract base class.
- * `AnnotatedQueue` and its children no longer inherit from `QueuingManager`.
- * `QueuingManager` is no longer a context manager.
- * Recording queues should start and stop recording via the `QueuingManager.add_active_queue` and
- `QueueingContext.remove_active_queue` class methods instead of directly manipulating the `_active_contexts` property.
- * `AnnotatedQueue` and its children no longer provide global information about actively recording queues. This information
- is now only available through `QueuingManager`.
- * `AnnotatedQueue` and its children no longer have the private `_append`, `_remove`, `_update_info`, `_safe_update_info`,
- and `_get_info` methods. The public analogues should be used instead.
- * `QueuingManager.safe_update_info` and `AnnotatedQueue.safe_update_info` are deprecated. Their functionality is moved to
- `update_info`.
+ [(#3085)](https://github.com/PennyLaneAI/pennylane/pull/3085)
+
+ - `QueuingContext` is renamed to `QueuingManager`.
+ - `QueuingManager` should now be the global communication point for putting queuable objects into the active queue.
+ - `QueuingManager` is no longer an abstract base class.
+ - `AnnotatedQueue` and its children no longer inherit from `QueuingManager`.
+ - `QueuingManager` is no longer a context manager.
+ - Recording queues should start and stop recording via the `QueuingManager.add_active_queue` and
+ `QueuingContext.remove_active_queue` class methods instead of directly manipulating the `_active_contexts` property.
+ - `AnnotatedQueue` and its children no longer provide global information about actively recording queues. This information is now only available through `QueuingManager`.
+ - `AnnotatedQueue` and its children no longer have the private `_append`, `_remove`, `_update_info`, `_safe_update_info`, and `_get_info` methods. The public analogues should be used instead.
+ - `QueuingManager.safe_update_info` and `AnnotatedQueue.safe_update_info` are deprecated. Their functionality is moved to `update_info`.
* `qml.Identity` now accepts multiple wires.
[(#3049)](https://github.com/PennyLaneAI/pennylane/pull/3049)
@@ -448,14 +627,13 @@
* Modified the representation of `WireCut` by using `qml.draw_mpl`.
[(#3067)](https://github.com/PennyLaneAI/pennylane/pull/3067)
-* Improved the performance of the `qml.math.expand_matrix` function for dense matrices.
- [(#3064)](https://github.com/PennyLaneAI/pennylane/pull/3064)
-
-* Improved the `qml.math.expand_matrix` method for sparse matrices.
+* Improved the performance of `qml.math.expand_matrix` function for dense
+ and sparse matrices.
[(#3060)](https://github.com/PennyLaneAI/pennylane/pull/3060)
+ [(#3064)](https://github.com/PennyLaneAI/pennylane/pull/3064)
-* Support sums and products of `Operator` classes with scalar tensors of any interface
- (numpy, jax, tensorflow, torch...).
+* Added support for sums and products of operator classes with scalar tensors of any interface
+ (NumPy, JAX, Tensorflow, PyTorch...).
[(#3149)](https://github.com/PennyLaneAI/pennylane/pull/3149)
```pycon
@@ -470,7 +648,7 @@
performance of the `eigvals`, `diagonalizing_gates` and `Prod.matrix` methods.
[(#3084)](https://github.com/PennyLaneAI/pennylane/pull/3084)
-* Added the `map_wires` method to the `Operator` class, which returns a copy of the operator with
+* Added the `map_wires` method to the operators, which returns a copy of the operator with
its wires changed according to the given wire map.
[(#3143)](https://github.com/PennyLaneAI/pennylane/pull/3143)
@@ -496,34 +674,32 @@
* `default.qubit` favours decomposition and avoids matrix construction for `QFT` and `GroverOperator` at larger qubit numbers.
[(#3193)](https://github.com/PennyLaneAI/pennylane/pull/3193)
-* `ControlledQubitUnitary` now has a `control_values` property.
+* `qml.ControlledQubitUnitary` now has a `control_values` property.
[(#3206)](https://github.com/PennyLaneAI/pennylane/pull/3206)
-* Remove `_wires` properties and setters from the `ControlledClass` and the `SymbolicClass`.
- Stop using `op._wires = new_wires`, use `qml.map_wires(op, wire_map=dict(zip(op.wires, new_wires)))`
- instead.
- [(#3186)](https://github.com/PennyLaneAI/pennylane/pull/3186)
-
* Added a new `qml.tape.QuantumScript` class that contains all the non-queuing behavior of `QuantumTape`. Now, `QuantumTape` inherits from `QuantumScript` as well as `AnnotatedQueue`.
[(#3097)](https://github.com/PennyLaneAI/pennylane/pull/3097)
+* Extended the `qml.equal` function to MeasurementProcesses
+ [(#3189)](https://github.com/PennyLaneAI/pennylane/pull/3189)
+
+* `qml.drawer.draw.draw_mpl` now accepts a `style` kwarg to select a style for plotting, rather than calling
+ `qml.drawer.use_style(style)` before plotting. Setting a style for `draw_mpl` does not change the global
+ configuration for matplotlib plotting. If no `style` is passed, the function defaults
+ to plotting with the `black_white` style.
+ [(#3247)](https://github.com/PennyLaneAI/pennylane/pull/3247)
+
Breaking changes
* `QuantumTape._par_info` is now a list of dictionaries, instead of a dictionary whose keys are integers starting from zero.
[(#3185)](https://github.com/PennyLaneAI/pennylane/pull/3185)
-* `QueuingContext` is renamed `QueuingManager`.
+* `QueuingContext` has been renamed to `QueuingManager`.
[(#3061)](https://github.com/PennyLaneAI/pennylane/pull/3061)
-* `QueuingManager.safe_update_info` and `AnnotatedQueue.safe_update_info` are deprecated. Instead, `update_info` no longer raises errors
- if the object isn't in the queue.
-
* Deprecation patches for the return types enum's location and `qml.utils.expand` are removed.
[(#3092)](https://github.com/PennyLaneAI/pennylane/pull/3092)
-* Extended `qml.equal` function to MeasurementProcesses
- [(#3189)](https://github.com/PennyLaneAI/pennylane/pull/3189)
-
* `_multi_dispatch` functionality has been moved inside the `get_interface` function. This function
can now be called with one or multiple tensors as arguments.
[(#3136)](https://github.com/PennyLaneAI/pennylane/pull/3136)
@@ -555,29 +731,17 @@
>>> qml.math.get_interface(torch_scalar, torch_tensor, numpy_tensor)
'torch'
```
-
- Note that when passing lists or tuples without unpacking them, ``get_interface`` will always default to ``"numpy"``.
-
- ```pycon
- >>> qml.math.get_interface([torch_scalar, torch_tensor, numpy_tensor])
- 'numpy'
- ```
-
-
-
-* `qml.drawer.draw.draw_mpl` now accepts a `style` kwarg to select a style for plotting, rather than calling
- `qml.drawer.use_style(style)` before plotting. Setting a style for `draw_mpl` does not change the global
- configuration for matplotlib plotting. If no `style` is passed, the function defaults
-
- to plotting with the `black_white` style.
- [(#3247)](https://github.com/PennyLaneAI/pennylane/pull/3247)
-
+
* `Operator.compute_terms` is removed. On a specific instance of an operator, `op.terms()` can be used
instead. There is no longer a static method for this.
[(#3215)](https://github.com/PennyLaneAI/pennylane/pull/3215)
Deprecations
+* `QueuingManager.safe_update_info` and `AnnotatedQueue.safe_update_info` are deprecated. Instead, `update_info` no longer raises errors
+ if the object isn't in the queue.
+ [(#3085)](https://github.com/PennyLaneAI/pennylane/pull/3085)
+
* `qml.tape.stop_recording` and `QuantumTape.stop_recording` have been moved to `qml.QueuingManager.stop_recording`. The old functions will still be available until v0.29.
[(#3068)](https://github.com/PennyLaneAI/pennylane/pull/3068)
@@ -604,7 +768,7 @@
* Added a "Deprecations" page to the developer documentation.
[(#3093)](https://github.com/PennyLaneAI/pennylane/pull/3093)
-* The example of the `FlipSign` template has been updated.
+* The example of the `qml.FlipSign` template has been updated.
[(#3219)](https://github.com/PennyLaneAI/pennylane/pull/3219)
Bug fixes
@@ -612,16 +776,9 @@
* `qml.SparseHamiltonian` now validates the size of the input matrix.
[(#3278)](https://github.com/PennyLaneAI/pennylane/pull/3278)
-* Fixed a bug where `qml.sample()` and `qml.counts()` would output incorrect results when mixed with measurements whose
- operators do not qubit-wise commute with computational basis projectors.
- [(#3207)](https://github.com/PennyLaneAI/pennylane/pull/3207)
-
* Users no longer see unintuitive errors when inputing sequences to `qml.Hermitian`.
[(#3181)](https://github.com/PennyLaneAI/pennylane/pull/3181)
-* `ControlledQubitUnitary.pow` now copies over the `control_values`.
- [(#3206)](https://github.com/PennyLaneAI/pennylane/pull/3206)
-
* The evaluation of QNodes that return either `vn_entropy` or `mutual_info` raises an
informative error message when using devices that define a vector of shots.
[(#3180)](https://github.com/PennyLaneAI/pennylane/pull/3180)
@@ -650,10 +807,7 @@
composite operator.
[(#3204)](https://github.com/PennyLaneAI/pennylane/pull/3204)
-* Fixed a bug where `qml.BasisStatePreparation` was not jit-compilable with JAX.
- [(#3239)](https://github.com/PennyLaneAI/pennylane/pull/3239)
-
-* Fixed a bug where `qml.BasisEmbedding` was not jit-compilable with JAX.
+* Fixed a bug where `qml.BasisStatePreparation` and `qml.BasisEmbedding` were not jit-compilable with JAX.
[(#3239)](https://github.com/PennyLaneAI/pennylane/pull/3239)
* Fixed a bug where `qml.MottonenStatePreparation` was not jit-compilable with JAX.
@@ -673,16 +827,20 @@ This release contains contributions from (in alphabetical order):
Kamal Mohamed Ali,
Guillermo Alonso-Linaje,
Juan Miguel Arrazola,
-Albert Mitjans Coma,
Utkarsh Azad,
+Thomas Bromley,
+Albert Mitjans Coma,
Isaac De Vlugt,
+Olivia Di Matteo,
Amintor Dusko,
Lillian M. A. Frederiksen,
Diego Guala,
+Josh Izaac,
Soran Jahangiri,
Edward Jiang,
Korbinian Kottmann,
Christina Lee,
+Romain Moyard,
Lee J. O'Riordan,
Mudit Pandey,
Matthew Silverman,