Qulacs-Osaka / scikit-qulacs

scikit-qulacs is a library for quantum neural network. This library is based on qulacs and named after scikit-learn.
https://qulacs-osaka.github.io/scikit-qulacs/index.html
MIT License
21 stars 6 forks source link

Update dependency PennyLane to ^0.38.0 #276

Open renovate[bot] opened 1 year ago

renovate[bot] commented 1 year ago

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
PennyLane ^0.24.0 -> ^0.38.0 age adoption passing confidence

Release Notes

PennyLaneAI/pennylane (PennyLane) ### [`v0.38.1`](https://redirect.github.com/PennyLaneAI/pennylane/releases/tag/v0.38.1): Release 0.38.1 [Compare Source](https://redirect.github.com/PennyLaneAI/pennylane/compare/v0.38.0...v0.38.1)

Bug fixes ๐Ÿ›

- Fix float-to-complex casting in various places across PennyLane. [(#​6260)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6260)

Contributors โœ๏ธ

This release contains contributions from (in alphabetical order): Mudit Pandey ### [`v0.38.0`](https://redirect.github.com/PennyLaneAI/pennylane/releases/tag/v0.38.0): Release 0.38.0 [Compare Source](https://redirect.github.com/PennyLaneAI/pennylane/compare/v0.37.0...v0.38.0)

New features since last release

Registers of wires ๐Ÿงธ

- A new function called `qml.registers` has been added that lets you seamlessly create registers of wires. [(#​5957)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5957) [(#​6102)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6102) Using registers, it is easier to build large algorithms and circuits by applying gates and operations to predefined collections of wires. With `qml.registers`, you can create registers of wires by providing a dictionary whose keys are register names and whose values are the number of wires in each register. ```python >>> wire_reg = qml.registers({"alice": 4, "bob": 3}) >>> wire_reg {'alice': Wires([0, 1, 2, 3]), 'bob': Wires([4, 5, 6])} ``` The resulting data structure of `qml.registers` is a dictionary with the same register names as keys, but the values are `qml.wires.Wires` instances. Nesting registers within other registers can be done by providing a nested dictionary, where the ordering of wire labels is based on the order of appearance and nestedness. ```python >>> wire_reg = qml.registers({"alice": {"alice1": 1, "alice2": 2}, "bob": {"bob1": 2, "bob2": 1}}) >>> wire_reg {'alice1': Wires([0]), 'alice2': Wires([1, 2]), 'alice': Wires([0, 1, 2]), 'bob1': Wires([3, 4]), 'bob2': Wires([5]), 'bob': Wires([3, 4, 5])} ``` Since the values of the dictionary are `Wires` instances, their use within quantum circuits is very similar to that of a `list` of integers. ```python dev = qml.device("default.qubit") @​qml.qnode(dev) def circuit(): for w in wire_reg["alice"]: qml.Hadamard(w) for w in wire_reg["bob1"]: qml.RX(0.1967, wires=w) qml.CNOT(wires=[wire_reg["alice1"][0], wire_reg["bob2"][0]]) return [qml.expval(qml.Y(w)) for w in wire_reg["bob1"]] print(qml.draw(circuit)()) ``` ```pycon 0: โ”€โ”€Hโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ญโ—โ”€โ”ค 1: โ”€โ”€Hโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚โ”€โ”€โ”ค 2: โ”€โ”€Hโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚โ”€โ”€โ”ค 3: โ”€โ”€RX(0.20)โ”€โ”‚โ”€โ”€โ”ค 4: โ”€โ”€RX(0.20)โ”€โ”‚โ”€โ”€โ”ค 5: โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฐXโ”€โ”ค ``` In tandem with `qml.registers`, we've also made the following improvements to `qml.wires.Wires`: - `Wires` instances now have a more copy-paste friendly representation when printed. [(#​5958)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5958) ```python >>> from pennylane.wires import Wires >>> w = Wires([1, 2, 3]) >>> w Wires([1, 2, 3]) ``` - Python set-based combinations are now supported by `Wires`. [(#​5983)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5983) This new feature unlocks the ability to combine `Wires` instances in the following ways: - intersection with `&` or `intersection()`: ```python >>> wires1 = Wires([1, 2, 3]) >>> wires2 = Wires([2, 3, 4]) >>> wires1.intersection(wires2) # or wires1 & wires2 Wires([2, 3]) ``` - symmetric difference with `^` or `symmetric_difference()`: ```python >>> wires1.symmetric_difference(wires2) # or wires1 ^ wires2 Wires([1, 4]) ``` - union with `|` or `union()`: ```python >>> wires1.union(wires2) # or wires1 | wires2 Wires([1, 2, 3, 4]) ``` - difference with `-` or `difference()`: ```python >>> wires1.difference(wires2) # or wires1 - wires2 Wires([1]) ```

Quantum arithmetic operations ๐Ÿงฎ

- Several new operator templates have been added to PennyLane that let you perform quantum arithmetic operations. [(#​6109)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6109) [(#​6112)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6112) [(#​6121)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6121) - `qml.Adder` performs in-place modular addition: $\text{Adder}(k, m)\vert x \rangle = \vert x + k ; \text{mod} ; m\rangle$. - `qml.PhaseAdder` is similar to `qml.Adder`, but it performs in-place modular addition in the Fourier basis. - `qml.Multiplier` performs in-place multiplication: $\text{Multiplier}(k, m)\vert x \rangle = \vert x \times k ; \text{mod} ; m \rangle$. - `qml.OutAdder` performs out-place modular addition: $\text{OutAdder}(m)\vert x \rangle \vert y \rangle \vert b \rangle = \vert x \rangle \vert y \rangle \vert b + x + y ; \text{mod} ; m \rangle$. - `qml.OutMultiplier` performs out-place modular multiplication: $\text{OutMultiplier}(m)\vert x \rangle \vert y \rangle \vert b \rangle = \vert x \rangle \vert y \rangle \vert b + x \times y ; \text{mod} ; m \rangle$. - `qml.ModExp` performs modular exponentiation: $\text{ModExp}(base, m) \vert x \rangle \vert k \rangle = \vert x \rangle \vert k \times base^x ; \text{mod} ; m \rangle$. Here is a comprehensive example that performs the following calculation: `(2 + 1) * 3 mod 7 = 2` (or `010` in binary). ```python dev = qml.device("default.qubit", shots=1) wire_reg = qml.registers({ "x_wires": 2, # |x>: stores the result of 2 + 1 = 3 "y_wires": 2, # |y>: multiples x by 3 "output_wires": 3, # stores the result of (2 + 1) * 3 m 7 = 2 "work_wires": 2 # for qml.OutMultiplier }) @​qml.qnode(dev) def circuit(): ``` ### In-place addition qml.BasisEmbedding(2, wires=wire_reg["x_wires"]) qml.Adder(1, x_wires=wire_reg["x_wires"]) # add 1 to wires [0, 1] ### Out-place multiplication qml.BasisEmbedding(3, wires=wire_reg["y_wires"]) qml.OutMultiplier( wire_reg["x_wires"], wire_reg["y_wires"], wire_reg["output_wires"], work_wires=wire_reg["work_wires"], mod=7 ) return qml.sample(wires=wire_reg["output_wires"]) ``` ``` > > > circuit() > > > array(\[0, 1, 0]) ````

Converting noise models from Qiskit โ™ป๏ธ

* Convert Qiskit noise models into a PennyLane `NoiseModel` with `qml.from_qiskit_noise`. [(#​5996)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5996) In the last few releases, we've added substantial improvements and new features to the [Pennylane-Qiskit plugin](https://docs.pennylane.ai/projects/qiskit/en/latest/installation.html). With this release, a new `qml.from_qiskit_noise` function allows you to convert a Qiskit noise model into a PennyLane `NoiseModel`. Here is a simple example with two quantum errors that add two different depolarizing errors based on the presence of different gates in the circuit: ```python import pennylane as qml import qiskit_aer.noise as noise error_1 = noise.depolarizing_error(0.001, 1) # 1-qubit noise error_2 = noise.depolarizing_error(0.01, 2) # 2-qubit noise noise_model = noise.NoiseModel() noise_model.add_all_qubit_quantum_error(error_1, ['rz', 'ry']) noise_model.add_all_qubit_quantum_error(error_2, ['cx']) ```` ```pycon >>> qml.from_qiskit_noise(noise_model) NoiseModel({ OpIn(['RZ', 'RY']): QubitChannel(num_kraus=4, num_wires=1) OpIn(['CNOT']): QubitChannel(num_kraus=16, num_wires=2) }) ``` Under the hood, PennyLane converts each quantum error in the Qiskit noise model into an equivalent `qml.QubitChannel` operator with the same canonical [Kraus representation](https://en.wikipedia.org/wiki/Quantum_operation#Kraus_operators). Currently, noise models in PennyLane do not support readout errors. As such, those will be skipped during conversion if they are present in the Qiskit noise model. Make sure to `pip install pennylane-qiskit` to access this new feature!

Substantial upgrades to mid-circuit measurements using tree-traversal ๐ŸŒณ

- The `"tree-traversal"` algorithm for mid-circuit measurements (MCMs) on `default.qubit` has been internally redesigned for better performance. [(#​5868)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5868) In the last release (v0.37), we introduced the tree-traversal MCM method, which was implemented in a recursive way for simplicity. However, this had the unintended consequence of very deep [stack calls](https://en.wikipedia.org/wiki/Call_stack) for circuits with many MCMs, resulting in [stack overflows](https://en.wikipedia.org/wiki/Stack_overflow) in some cases. With this release, we've refactored the implementation of the tree-traversal method into an iterative approach, which solves those inefficiencies when many MCMs are present in a circuit. - The `tree-traversal` algorithm is now compatible with analytic-mode execution (`shots=None`). [(#​5868)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5868) ```python dev = qml.device("default.qubit") n_qubits = 5 @​qml.qnode(dev, mcm_method="tree-traversal") def circuit(): for w in range(n_qubits): qml.Hadamard(w) for w in range(n_qubits - 1): qml.CNOT(wires=[w, w+1]) for w in range(n_qubits): m = qml.measure(w) qml.cond(m == 1, qml.RX)(0.1967 * (w + 1), w) return [qml.expval(qml.Z(w)) for w in range(n_qubits)] ``` ```pycon >>> circuit() [tensor(0.00964158, requires_grad=True), tensor(0.03819446, requires_grad=True), tensor(0.08455748, requires_grad=True), tensor(0.14694258, requires_grad=True), tensor(0.2229438, requires_grad=True)] ```

Improvements ๐Ÿ› 

Creating spin Hamiltonians

- Three new functions are now available for creating commonly-used spin Hamiltonians in PennyLane: [(#​6106)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6106) [(#​6128)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6128) - `qml.spin.transverse_ising` creates the [transverse-field Ising model](https://en.wikipedia.org/wiki/Transverse-field_Ising_model) Hamiltonian. - `qml.spin.heisenberg` creates the [Heisenberg model](https://en.wikipedia.org/wiki/Quantum_Heisenberg_model) Hamiltonian. - `qml.spin.fermi_hubbard` creates the [Fermi-Hubbard model](https://en.wikipedia.org/wiki/Hubbard_model) Hamiltonian. Each Hamiltonian can be instantiated by specifying a `lattice`, the number of [unit cells](https://en.wikipedia.org/wiki/Unit_cell), `n_cells`, and the Hamiltonian parameters as keyword arguments. Here is an example with the transverse-field Ising model: ```pycon >>> tfim_ham = qml.spin.transverse_ising(lattice="square", n_cells=[2, 2], coupling=0.5, h=0.2) >>> tfim_ham ( -0.5 * (Z(0) @​ Z(1)) + -0.5 * (Z(0) @​ Z(2)) + -0.5 * (Z(1) @​ Z(3)) + -0.5 * (Z(2) @​ Z(3)) + -0.2 * X(0) + -0.2 * X(1) + -0.2 * X(2) + -0.2 * X(3) ) ``` The resulting object is a `qml.Hamiltonian` instance, making it easy to use in circuits like the following. ```python dev = qml.device("default.qubit", shots=1) @​qml.qnode(dev) def circuit(): return qml.expval(tfim_ham) ``` >>> circuit() -2.0 More features will be added to the `qml.spin` module in the coming releases, so stay tuned!

A Prep-Select-Prep template

- A new template called `qml.PrepSelPrep` has been added that implements a block-encoding of a linear combination of unitaries. [(#​5756)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5756) [(#​5987)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5987) This operator acts as a nice wrapper for having to perform `qml.StatePrep`, `qml.Select`, and `qml.adjoint(qml.StatePrep)` in succession, which is quite common in many quantum algorithms (e.g., [LCU and block encoding](https://pennylane.ai/qml/demos/tutorial_lcu_blockencoding/)). Here is an example showing the equivalence between using `qml.PrepSelPrep` and `qml.StatePrep`, `qml.Select`, and `qml.adjoint(qml.StatePrep)`. ```python coeffs = [0.3, 0.1] alphas = (np.sqrt(coeffs) / np.linalg.norm(np.sqrt(coeffs))) unitaries = [qml.X(2), qml.Z(2)] lcu = qml.dot(coeffs, unitaries) control = [0, 1] def prep_sel_prep(alphas, unitaries): qml.StatePrep(alphas, wires=control, pad_with=0) qml.Select(unitaries, control=control) qml.adjoint(qml.StatePrep)(alphas, wires=control, pad_with=0) @​qml.qnode(qml.device("default.qubit")) def circuit(lcu, control, alphas, unitaries): qml.PrepSelPrep(lcu, control) qml.adjoint(prep_sel_prep)(alphas, unitaries) return qml.state() ``` ```pycon >>> import numpy as np >>> np.round(circuit(lcu, control, alphas, unitaries), decimals=2) tensor([1.+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) ```

QChem improvements

- Molecules and Hamiltonians can now be constructed for all the elements present in the periodic table. [(#​5821)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5821) This new feature is made possible by integrating with the [basis-set-exchange package](https://pypi.org/project/basis-set-exchange/). If loading basis sets from `basis-set-exchange` is needed for your molecule, make sure that you `pip install basis-set-exchange` and set `load_data=True`. ```python symbols = ['Ti', 'Ti'] geometry = np.array([[0.0, 0.0, -1.1967], [0.0, 0.0, 1.1967]], requires_grad=True) mol = qml.qchem.Molecule(symbols, geometry, load_data=True) ``` ```pycon >>> mol.n_electrons 44 ``` - `qml.UCCSD` now accepts an additional optional argument, `n_repeats`, which defines the number of times the UCCSD template is repeated. This can improve the accuracy of the template by reducing the Trotter error, but would result in deeper circuits. [(#​5801)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5801) - The `qml.qchem.qubit_observable` function has been modified to return an ascending wire order for molecular Hamiltonians. [(#​5950)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5950) - A new method called `to_mat` has been added to the `qml.FermiWord` and `qml.FermiSentence` classes, which allows for computing the matrix representation of these Fermi operators. [(#​5920)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5920)

Improvements to operators

- `qml.GlobalPhase` now supports parameter broadcasting. [(#​5923)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5923) - `qml.Hermitian` now has a `compute_decomposition` method. [(#​6062)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6062) - The implementation of `qml.PhaseShift`, `qml.S`, and `qml.T` has been improved, resulting in faster circuit execution times. [(#​5876)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5876) - The `qml.CNOT` operator no longer decomposes into itself. Instead, it raises a `qml.DecompositionUndefinedError`. [(#​6039)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6039)

Mid-circuit measurements

- The `qml.dynamic_one_shot` transform now supports circuits using the `"tensorflow"` interface. [(#​5973)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5973) - If the conditional does not include a mid-circuit measurement, then `qml.cond` will automatically evaluate conditionals using standard Python control flow. [(#​6016)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6016) This allows `qml.cond` to be used to represent a wider range of conditionals: ```python dev = qml.device("default.qubit", wires=1) @​qml.qnode(dev) def circuit(x): c = qml.cond(x > 2.7, qml.RX, qml.RZ) c(x, wires=0) return qml.probs(wires=0) ``` ```pycon >>> print(qml.draw(circuit)(3.8)) 0: โ”€โ”€RX(3.80)โ”€โ”ค Probs >>> print(qml.draw(circuit)(0.54)) 0: โ”€โ”€RZ(0.54)โ”€โ”ค Probs ```

Transforms

- `qml.transforms.single_qubit_fusion` and `qml.transforms.merge_rotations` now respect global phases. [(#​6031)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6031) - A new transform called `qml.transforms.diagonalize_measurements` has been added. This transform converts measurements to the computational basis by applying the relevant diagonalizing gates. It can be set to diagonalize only a subset of the base observables `{qml.X, qml.Y, qml.Z, qml.Hadamard}`. [(#​5829)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5829) - A new transform called `split_to_single_terms` has been added. This transform splits expectation values of sums into multiple single-term measurements on a single tape, providing better support for simulators that can handle non-commuting observables but don't natively support multi-term observables. [(#​5884)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5884) - New functionality has been added to natively support exponential extrapolation when using `qml.transforms.mitigate_with_zne`. This allows users to have more control over the error mitigation protocol without needing to add further dependencies. [(#​5972)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5972)

Capturing and representing hybrid programs

- `qml.for_loop` now supports `range`-like syntax with default `step=1`. [(#​6068)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6068) - Applying `adjoint` and `ctrl` to a quantum function can now be captured into plxpr. Furthermore, the `qml.cond` function can be captured into plxpr. [(#​5966)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5966) [(#​5967)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5967) [(#​5999)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5999) [(#​6058)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6058) - During experimental program capture, functions that accept and/or return `pytree` structures can now be handled in the `qml.QNode` call, `qml.cond`, `qml.for_loop` and `qml.while_loop`. [(#​6081)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6081) - During experimental program capture, QNodes can now use closure variables. [(#​6052)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6052) - Mid-circuit measurements can now be captured with `qml.capture` enabled. [(#​6015)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6015) - `qml.for_loop` can now be captured into plxpr. [(#​6041)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6041) [(#​6064)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6064) - `qml.for_loop` and `qml.while_loop` now fall back to standard Python control flow if `@qjit` is not present, allowing the same code to work with and without `@qjit` without any rewrites. [(#​6014)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6014) ```python dev = qml.device("lightning.qubit", wires=3) @​qml.qnode(dev) def circuit(x, n): @​qml.for_loop(0, n, 1) def init_state(i): qml.Hadamard(wires=i) init_state() @​qml.for_loop(0, n, 1) def apply_operations(i, x): qml.RX(x, wires=i) @​qml.for_loop(i + 1, n, 1) def inner(j): qml.CRY(x**2, [i, j]) inner() return jnp.sin(x) apply_operations(x) return qml.probs() ``` ```pycon >>> print(qml.draw(circuit)(0.5, 3)) 0: โ”€โ”€Hโ”€โ”€RX(0.50)โ”€โ•ญโ—โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ญโ—โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค Probs 1: โ”€โ”€Hโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฐRY(0.25)โ”€โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€RX(0.48)โ”€โ•ญโ—โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค Probs 2: โ”€โ”€Hโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฐRY(0.25)โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฐRY(0.23)โ”€โ”€RX(0.46)โ”€โ”ค Probs >>> circuit(0.5, 3) array([0.125 , 0.125 , 0.09949758, 0.15050242, 0.07594666, 0.11917543, 0.08942104, 0.21545687]) >>> qml.qjit(circuit)(0.5, 3) Array([0.125 , 0.125 , 0.09949758, 0.15050242, 0.07594666, 0.11917543, 0.08942104, 0.21545687], dtype=float64) ```

Community contributions ๐Ÿฅณ

- Fixed a bug in `qml.ThermalRelaxationError` where there was a typo from `tq` to `tg`. [(#​5988)](https://redirect.github.com/PennyLaneAI/pennylane/issues/5988) - Readout error has been added using parameters `readout_relaxation_probs` and `readout_misclassification_probs` on the `default.qutrit.mixed` device. These parameters add a `qml.QutritAmplitudeDamping` and a `qml.TritFlip` channel, respectively, after measurement diagonalization. The amplitude damping error represents the potential for relaxation to occur during longer measurements. The trit flip error represents misclassification during readout. [(#​5842)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5842) - `qml.ops.qubit.BasisStateProjector` now has a `compute_sparse_matrix` method that computes the sparse CSR matrix representation of the projector onto the given basis state. [(#​5790)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5790)

Other improvements

- `qml.pauli.group_observables` now uses `rustworkx` colouring algorithms to solve the [Minimum Clique Cover problem](https://en.wikipedia.org/wiki/Clique_cover), resulting in orders of magnitude performance improvements. [(#​6043)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6043) This adds two new options for the `method` argument: `dsatur` (degree of saturation) and `gis` (independent set). In addition, the creation of the adjacency matrix now takes advantage of the symplectic representation of the Pauli observables. Additionally, a new function called `qml.pauli.compute_partition_indices` has been added to calculate the indices from the partitioned observables more efficiently. These changes improve the wall time of `qml.LinearCombination.compute_grouping` and the `grouping_type='qwc'` by orders of magnitude. - `qml.counts` measurements with `all_outcomes=True` can now be used with JAX jitting. Additionally, measurements broadcasted across all available wires (e.g., `qml.probs()`) can now be used with JAX jit and devices that allow dynamic numbers of wires (only `'default.qubit'` currently). [(#​6108)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6108/) - `qml.ops.op_math.ctrl_decomp_zyz` can now decompose special unitaries with multiple control wires. [(#​6042)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6042) - A new method called `process_density_matrix` has been added to the `ProbabilityMP` and `DensityMatrixMP` measurement processes, allowing for more efficient handling of quantum density matrices, particularly with batch processing support. This method simplifies the calculation of probabilities from quantum states represented as density matrices. [(#​5830)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5830) - `SProd.terms` now flattens out the terms if the base is a multi-term observable. [(#​5885)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5885) - `qml.QNGOptimizer` now supports cost functions with multiple arguments, updating each argument independently. [(#​5926)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5926) - `semantic_version` has been removed from the list of required packages in PennyLane. [(#​5836)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5836) - `qml.devices.LegacyDeviceFacade` has been added to map the legacy devices to the new device interface, making it easier for developers to develop legacy devices. [(#​5927)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5927) - `StateMP.process_state` now defines rules in `cast_to_complex` for complex casting, avoiding a superfluous statevector copy in PennyLane-Lightning simulations. [(#​5995)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5995) - `QuantumScript.hash` is now cached, leading to performance improvements. [(#​5919)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5919) - Observable validation for `default.qubit` is now based on execution mode (analytic vs. finite shots) and measurement type (sample measurement vs. state measurement). This improves our error handling when, for example, non-hermitian operators are given to `qml.expval`. [(#​5890)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5890) - A new `is_leaf` parameter has been added to the function `flatten` in the `qml.pytrees` module. This is to allow for node flattening to be stopped for any node where the `is_leaf` optional argument evaluates to being `True`. [(#​6107)](https://redirect.github.com/PennyLaneAI/pennylane/issues/6107) - A progress bar has been added to `qml.data.load()` when downloading a dataset. [(#​5560)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5560) - Upgraded and simplified `StatePrep` and `AmplitudeEmbedding` templates. [(#​6034)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6034) [(#​6170)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6170) - Upgraded and simplified `BasisState` and `BasisEmbedding` templates. [(#​6021)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6021)

Breaking changes ๐Ÿ’”

- `MeasurementProcess.shape(shots: Shots, device:Device)` is now `MeasurementProcess.shape(shots: Optional[int], num_device_wires:int = 0)`. This has been done to allow for jitting when a measurement is broadcasted across all available wires, but the device does not specify wires. [(#​6108)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6108/) - If the shape of a probability measurement is affected by a `Device.cutoff` property, it will no longer work with jitting. [(#​6108)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6108/) - `qml.GlobalPhase` is considered non-differentiable with tape transforms. As a consequence, `qml.gradients.finite_diff` and `qml.gradients.spsa_grad` no longer support differentiating `qml.GlobalPhase` with state-based outputs. [(#​5620)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5620) - The `CircuitGraph.graph` `rustworkx` graph now stores indices into the circuit as the node labels, instead of the operator/ measurement itself. This allows the same operator to occur multiple times in the circuit. [(#​5907)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5907) - The `queue_idx` attribute has been removed from the `Operator`, `CompositeOp`, and `SymbolicOp` classes. [(#​6005)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6005) - `qml.from_qasm` no longer removes measurements from the QASM code. Use `measurements=[]` to remove measurements from the original circuit. [(#​5982)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5982) - `qml.transforms.map_batch_transform` has been removed, since transforms can be applied directly to a batch of tapes. See `qml.transform` for more information. [(#​5981)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5981) - `QuantumScript.interface` has been removed. [(#​5980)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5980)

Deprecations ๐Ÿ‘‹

- The `decomp_depth` argument in `qml.device` has been deprecated. [(#​6026)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6026) - The `max_expansion` argument in `qml.QNode` has been deprecated. [(#​6026)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6026) - The `expansion_strategy` attribute `qml.QNode` has been deprecated. [(#​5989)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5989) - The `expansion_strategy` argument has been deprecated in all of `qml.draw`, `qml.draw_mpl`, and `qml.specs`. The `level` argument should be used instead. [(#​5989)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5989) - `Operator.expand` has been deprecated. Users should simply use `qml.tape.QuantumScript(op.decomposition())` for equivalent behaviour. [(#​5994)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5994) - `qml.transforms.sum_expand` and `qml.transforms.hamiltonian_expand` have been deprecated. Users should instead use `qml.transforms.split_non_commuting` for equivalent behaviour. [(#​6003)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6003) - The `expand_fn` argument in `qml.execute` has been deprecated. Instead, please create a `qml.transforms.core.TransformProgram` with the desired preprocessing and pass it to the `transform_program` argument of `qml.execute`. [(#​5984)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5984) - The `max_expansion` argument in `qml.execute` has been deprecated. Instead, please use `qml.devices.preprocess.decompose` with the desired expansion level, add it to a `qml.transforms.core.TransformProgram` and pass it to the `transform_program` argument of `qml.execute`. [(#​5984)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5984) - The `override_shots` argument in `qml.execute` has been deprecated. Instead, please add the shots to the `QuantumTape`s to be executed. [(#​5984)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5984) - The `device_batch_transform` argument in `qml.execute` has been deprecated. Instead, please create a `qml.transforms.core.TransformProgram` with the desired preprocessing and pass it to the `transform_program` argument of `qml.execute`. [(#​5984)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5984) - `qml.qinfo.classical_fisher` and `qml.qinfo.quantum_fisher` have been deprecated. Instead, use `qml.gradients.classical_fisher` and `qml.gradients.quantum_fisher`. [(#​5985)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5985) - The legacy devices `default.qubit.{autograd,torch,tf,jax,legacy}` have been deprecated. Instead, use `default.qubit`, as it now supports backpropagation through the several backends. [(#​5997)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5997) - The logic for internally switching a device for a different backpropagation compatible device is now deprecated, as it was in place for the deprecated `default.qubit.legacy`. [(#​6032)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6032)

Documentation ๐Ÿ“

- The docstring for `qml.qinfo.quantum_fisher`, regarding the internally used functions and potentially required auxiliary wires, has been improved. [(#​6074)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6074) - The docstring for `QuantumScript.expand` and `qml.tape.tape.expand_tape` has been improved. [(#​5974)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5974)

Bug fixes ๐Ÿ›

- The sparse matrix can now be computed for a product operator when one operand is a `GlobalPhase` on no wires. [(#​6197)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6197) - For `default.qubit`, JAX is now used for sampling whenever the state is a JAX array. This fixes normalization issues that can occur when the state uses 32-bit precision. [(#​6190)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6190) - Fix Pytree serialization of operators with empty shot vectors [(#​6155)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6155) - Fixes an error in the `dynamic_one_shot` transform when used with sampling a single shot. [(#​6149)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6149) - `qml.transforms.pattern_matching_optimization` now preserves the tape measurements. [(#​6153)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6153) - `qml.transforms.broadcast_expand` no longer squeezes out batch sizes of size 1, as a batch size of 1 is still a batch size. [(#​6147)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6147) - Catalyst replaced `argnum` with `argnums` in gradient related functions, therefore we updated the Catalyst calls to those functions in PennyLane. [(#​6117)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6117) - `fuse_rot_angles` now returns NaN instead of incorrect derivatives at singular points. [(#​6031)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6031) - `qml.GlobalPhase` and `qml.Identity` can now be captured with plxpr when acting on no wires. [(#​6060)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6060) - Fixed `jax.grad` and `jax.jit` to work for `qml.AmplitudeEmbedding`, `qml.StatePrep` and `qml.MottonenStatePreparation`. [(#​5620)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5620) - Fixed a bug in `qml.center` that omitted elements from the center if they were linear combinations of input elements. [(#​6049)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6049) - Fix a bug where the global phase returned by `one_qubit_decomposition` gained a broadcasting dimension. [(#​5923)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5923) - Fixed a bug in `qml.SPSAOptimizer` that ignored keyword arguments in the objective function. [(#​6027)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6027) - Fixed `dynamic_one_shot` for use with devices using the old device API, since `override_shots` was deprecated. [(#​6024)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6024) - `CircuitGraph` can now handle circuits with the same operation instance occuring multiple times. [(#​5907)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5907) - `qml.QSVT` has been updated to store wire order correctly. [(#​5959)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5959) - `qml.devices.qubit.measure_with_samples` now returns the correct result if the provided measurements contain a sum of operators acting on the same wire. [(#​5978)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5978) - `qml.AmplitudeEmbedding` has better support for features using low precision integer data types. [(#​5969)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5969) - `qml.BasisState` and `qml.BasisEmbedding` now works with jax.jit, `lightning.qubit`, and give the correct decomposition. [(#​6021)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6021) - Jacobian shape has been fixed for measurements with dimension in `qml.gradients.vjp.compute_vjp_single`. [(5986)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5986) - `qml.lie_closure` now works with sums of Paulis. [(#​6023)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6023) - Workflows that parameterize the coefficients of `qml.exp` are now jit-compatible. [(#​6082)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6082) - Fixed a bug where `CompositeOp.overlapping_ops` changes the original ordering of operators, causing an incorrect matrix to be generated for `Prod` with `Sum` as operands. [(#​6091)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6091) - `qml.qsvt` now works with "Wx" convention and any number of angles. [(#​6105)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6105) - Basis set data from the Basis Set Exchange library can now be loaded for elements with `SPD`-type orbitals. [(#​6159)](https://redirect.github.com/PennyLaneAI/pennylane/pull/6159)

Contributors โœ๏ธ

This release contains contributions from (in alphabetical order): Tarun Kumar Allamsetty, Guillermo Alonso, Ali Asadi, Utkarsh Azad, Tonmoy T. Bhattacharya, Gabriel Bottrill, Jack Brown, Ahmed Darwish, Astral Cai, Yushao Chen, Ahmed Darwish, Diksha Dhawan Maja Franz, Lillian M. A. Frederiksen, Pietropaolo Frisoni, Emiliano Godinez, Austin Huang, Renke Huang, Josh Izaac, Soran Jahangiri, Korbinian Kottmann, Christina Lee, Jorge Martinez de Lejarza, William Maxwell, Vincent Michaud-Rioux, Anurav Modak, Mudit Pandey, Andrija Paurevic, Erik Schultheis, nate stemen, David Wierichs, ### [`v0.37.0`](https://redirect.github.com/PennyLaneAI/pennylane/releases/tag/v0.37.0): Release 0.37.0 [Compare Source](https://redirect.github.com/PennyLaneAI/pennylane/compare/v0.36.0...v0.37.0) ### Release 0.37.0

New features since last release

Execute wide circuits with Default Tensor ๐Ÿ”—

- A new `default.tensor` device is now available for performing [tensor network](https://en.wikipedia.org/wiki/Tensor_network) and [matrix product state](https://en.wikipedia.org/wiki/Matrix_product_state) simulations of quantum circuits using the [quimb backend](https://quimb.readthedocs.io/en/latest/). [(#​5699)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5699) [(#​5744)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5744) [(#​5786)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5786) [(#​5795)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5795) Either method can be selected when instantiating the `default.tensor` device by setting the `method` keyword argument to `"tn"` (tensor network) or `"mps"` (matrix product state). There are [several templates in PennyLane](https://docs.pennylane.ai/en/stable/introduction/templates.html#tensor-networks) that are tensor-network focused, which are excellent candidates for the `"tn"` method for `default.tensor`. The following example shows how a circuit comprising gates in a tree tensor network architecture can be efficiently simulated using `method="tn"`. ```python import pennylane as qml n_wires = 16 dev = qml.device("default.tensor", method="tn") def block(weights, wires): qml.CNOT(wires=[wires[0], wires[1]]) qml.RY(weights[0], wires=wires[0]) qml.RY(weights[1], wires=wires[1]) n_block_wires = 2 n_params_block = 2 n_blocks = qml.TTN.get_n_blocks(range(n_wires), n_block_wires) template_weights = [[0.1, -0.3]] * n_blocks @​qml.qnode(dev) def circuit(template_weights): for i in range(n_wires): qml.Hadamard(i) qml.TTN(range(n_wires), n_block_wires, block, n_params_block, template_weights) return qml.expval(qml.Z(n_wires - 1)) ``` ```pycon >>> circuit(template_weights) 0.3839174759751649 ``` For matrix product state simulations (`method="mps"`), we can make the execution be approximate by setting `max_bond_dim` (see the [device's documentation](https://docs.pennylane.ai/en/stable/code/api/pennylane.devices.default_tensor.DefaultTensor.html) for more details). The maximum bond dimension has implications for the speed of the simulation and lets us control the degree of the approximation, as shown in the following example. First, set up the circuit: ```python import numpy as np n_layers = 10 n_wires = 10 initial_shape, weights_shape = qml.SimplifiedTwoDesign.shape(n_layers, n_wires) np.random.seed(1967) initial_layer_weights = np.random.random(initial_shape) weights = np.random.random(weights_shape) def f(): qml.SimplifiedTwoDesign(initial_layer_weights, weights, range(n_wires)) return qml.expval(qml.Z(0)) ``` The `default.tensor` device is instantiated with a `max_bond_dim` value: ```python dev_dq = qml.device("default.qubit") value_dq = qml.QNode(f, dev_dq)() dev_mps = qml.device("default.tensor", max_bond_dim=5) value_mps = qml.QNode(f, dev_mps)() ``` With this bond dimension, the expectation values calculated for `default.qubit` and `default.tensor` are different: ```pycon >>> np.abs(value_dq - value_mps) tensor(0.0253213, requires_grad=True) ``` Learn more about `default.tensor` and how to configure it by [visiting the how-to guide](https://pennylane.ai/qml/demos/tutorial_How_to_simulate_quantum_circuits_with_tensor_networks/).

Add noise models to your quantum circuits ๐Ÿ“บ

- Support for building noise models and applying them to a quantum circuit has been added via the `NoiseModel` class and an `add_noise` transform. [(#​5674)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5674) [(#​5684)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5684) [(#​5718)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5718) Under the hood, PennyLane's approach to noise models is insertion-based, meaning that noise is included by *inserting* additional operators (gates or channels) that describe the noise into the quantum circuit. Creating a `NoiseModel` boils down to defining Boolean conditions under which specific noisy operations are inserted. There are several ways to specify conditions for adding noisy operations: - `qml.noise.op_eq(op)`: if the operator `op` is encountered in the circuit, add noise. - `qml.noise.op_in(ops)`: if any operators in `ops` are encountered in the circuit, add noise. - `qml.noise.wires_eq(wires)`: if an operator is applied to `wires`, add noise. - `qml.noise.wires_in(wires)`: if an operator is applied to any wire in `wires`, add noise. - custom noise conditions: custom conditions can be defined as functions decorated with `qml.BooleanFn` that return a Boolean value. For example, the following function will insert noise if a `qml.RY` operator is encountered with an angle of rotation that is less than `0.5`: ```python @​qml.BooleanFn def c0(op): return isinstance(op, qml.RY) and op.parameters[0] < 0.5 ``` Conditions can also be combined together with `&`, `and`, `|`, etc. Once the conditions under which noise is to be inserted have been stated, we can specify exactly what noise is inserted with the following: - `qml.noise.partial_wires(op)`: insert `op` on the wires that are specified by the condition that triggers adding this noise - custom noise operations: custom noise can be specified by defining a standard quantum function like below. ```python def n0(op, **kwargs): qml.RY(op.parameters[0] * 0.05, wires=op.wires) ``` With that, we can create a `qml.NoiseModel` object whose argument must be a dictionary mapping conditions to noise: ```python c1 = qml.noise.op_eq(qml.X) & qml.noise.wires_in([0, 1]) n1 = qml.noise.partial_wires(qml.AmplitudeDamping, 0.4) noise_model = qml.NoiseModel({c0: n0, c1: n1}) ``` ```pycon >>> noise_model NoiseModel({ BooleanFn(c0): n0 OpEq(PauliX) | WiresIn([0, 1]): AmplitudeDamping(gamma=0.4) }) ``` The noise model created can then be added to a QNode with `qml.add_noise`: ```python dev = qml.device("lightning.qubit", wires=3) @​qml.qnode(dev) def circuit(): qml.Y(0) qml.CNOT([0, 1]) qml.RY(0.3, wires=2) # triggers c0 qml.X(1) # triggers c1 return qml.state() ``` ```pycon >>> print(qml.draw(circuit)()) 0: โ”€โ”€Yโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ญโ—โ”€โ”€โ”€โ”€โ”ค State 1: โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฐXโ”€โ”€Xโ”€โ”ค State 2: โ”€โ”€RY(0.30)โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค State >>> circuit = qml.add_noise(circuit, noise_model) >>> print(qml.draw(circuit)()) 0: โ”€โ”€Yโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ญโ—โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค State 1: โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฐXโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€Xโ”€โ”€AmplitudeDamping(0.40)โ”€โ”ค State 2: โ”€โ”€RY(0.30)โ”€โ”€RY(0.01)โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค State ``` If more than one transform is applied to a QNode, control over when/where the `add_noise` transform is applied in relation to the other transforms can be specified with the `level` keyword argument. By default, `add_noise` is applied after all the transforms that have been manually applied to the QNode until that point. To learn more about this new functionality, check out our [noise module documentation](https://docs.pennylane.ai/en/stable/code/qml_noise.html) and keep your eyes peeled for an in-depth demo!

Catch bugs with the PennyLane debugger ๐Ÿšซ๐Ÿž

- The new PennyLane quantum debugger allows pausing simulation via the `qml.breakpoint()` command and provides tools for analyzing quantum circuits during execution. [(#​5680)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5680) [(#​5749)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5749) [(#​5789)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5789) This includes monitoring the circuit via measurements using `qml.debug_state()`, `qml.debug_probs()`, `qml.debug_expval()`, and `qml.debug_tape()`, stepping through the operations in a quantum circuit, and interactively adding operations during execution. Including `qml.breakpoint()` in a circuit will cause the simulation to pause during execution and bring up the interactive console. For example, consider the following code in a Python file called `script.py`: ```python @​qml.qnode(qml.device('default.qubit', wires=(0,1,2))) def circuit(x): qml.Hadamard(wires=0) qml.CNOT(wires=(0,2)) qml.breakpoint() qml.RX(x, wires=1) qml.RY(x, wires=2) qml.breakpoint() return qml.sample() circuit(1.2345) ``` Upon executing `script.py`, the simulation pauses at the first breakpoint: ```pycon > /Users/your/path/to/script.py(8)circuit() -> qml.RX(x, wires=1) [pldb] ``` While debugging, we can access circuit information. For example, `qml.debug_tape()` returns the tape of the circuit, giving access to its operations and drawing: ```pycon [pldb] tape = qml.debug_tape() [pldb] print(tape.draw(wire_order=[0,1,2])) 0: โ”€โ”€Hโ”€โ•ญโ—โ”€โ”ค 2: โ”€โ”€โ”€โ”€โ•ฐXโ”€โ”ค [pldb] tape.operations [Hadamard(wires=[0]), CNOT(wires=[0, 2])] ``` While `qml.debug_state()` is equivalent to `qml.state()` and gives the current state: ```pycon [pldb] print(qml.debug_state()) [0.70710678+0.j 0. +0.j 0. +0.j 0. +0.j 1. +0.j 0.70710678+0.j 0. +0.j 0. +0.j] ``` Other debugger functions like `qml.debug_probs()` and `qml.debug_expval()` also function like their simulation counterparts (`qml.probs` and `qml.expval`, respectively) and are described in more detail in the [debugger documentation](https://docs.pennylane.ai/en/stable/code/qml_debugging.html) Additionally, standard debugging commands are available to navigate through code, including `list`, `longlist`, `next`, `continue`, and `quit`, as described in [the debugging documentation](https://docs.pennylane.ai/en/stable/code/qml_debugging.html#controlling-code-execution-in-the-debugging-context). Finally, to modify a circuit mid-run, simply call the desired PennyLane operations: ```pycon [pldb] qml.CNOT(wires=(0,2)) CNOT(wires=[0, 2]) [pldb] print(qml.debug_tape().draw(wire_order=[0,1,2])) 0: โ”€โ”€Hโ”€โ•ญโ—โ”€โ•ญโ—โ”€โ”ค 2: โ”€โ”€โ”€โ”€โ•ฐXโ”€โ•ฐXโ”€โ”ค ``` Stay tuned for an in-depth demonstration on using this feature with real-world examples!

Convert between OpenFermion and PennyLane ๐Ÿค

- Two new functions called `qml.from_openfermion` and `qml.to_openfermion` are now available to convert between OpenFermion and PennyLane objects. This includes both fermionic and qubit operators. [(#​5773)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5773) [(#​5808)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5808) [(#​5881)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5881) For fermionic operators: ```pycon >>> import openfermion >>> of_fermionic = openfermion.FermionOperator('0^ 2') >>> type(of_fermionic) >>> pl_fermionic = qml.from_openfermion(of_fermionic) >>> type(pl_fermionic) >>> print(pl_fermionic) aโบ(0) a(2) ``` And for qubit operators: ```pycon >>> of_qubit = 0.5 * openfermion.QubitOperator('X0 X5') >>> pl_qubit = qml.from_openfermion(of_qubit) >>> print(pl_qubit) 0.5 * (X(0) @​ X(5)) ```

Better control over when drawing and specs take place ๐ŸŽš๏ธ

- It is now possible to control the stage at which `qml.draw`, `qml.draw_mpl`, and `qml.specs` occur within a QNode's [transform](https://docs.pennylane.ai/en/stable/code/qml_transforms.html) program. [(#​5855)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5855) [(#​5781)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5781/) Consider the following circuit which has multiple transforms applied: ```python @​qml.transforms.split_non_commuting @​qml.transforms.cancel_inverses @​qml.transforms.merge_rotations @​qml.qnode(qml.device("default.qubit")) def f(): qml.Hadamard(0) qml.Y(0) qml.RX(0.4, 0) qml.RX(-0.4, 0) qml.Y(0) return qml.expval(qml.X(0) + 2 * qml.Y(0)) ``` We can specify a `level` value when using `qml.draw()`: ```pycon >>> print(qml.draw(f, level=0)()) # input program 0: โ”€โ”€Hโ”€โ”€Yโ”€โ”€RX(0.40)โ”€โ”€RX(-0.40)โ”€โ”€Yโ”€โ”ค >>> print(qml.draw(f, level=1)()) # rotations merged 0: โ”€โ”€Hโ”€โ”€Yโ”€โ”€Yโ”€โ”ค >>> print(qml.draw(f, level=2)()) # inverses cancelled 0: โ”€โ”€Hโ”€โ”ค >>> print(qml.draw(f, level=3)()) # Hamiltonian expanded 0: โ”€โ”€Hโ”€โ”ค 0: โ”€โ”€Hโ”€โ”ค ``` The [qml.workflow.get_transform_program function](https://docs.pennylane.ai/en/latest/code/api/pennylane.workflow.get_transform_program.html) can be used to see the full transform program. ```pycon >>> qml.workflow.get_transform_program(f) TransformProgram(merge_rotations, cancel_inverses, split_non_commuting, validate_device_wires, mid_circuit_measurements, decompose, validate_measurements, validate_observables, no_sampling) ``` Note that additional transforms can be added automatically from device preprocessing or gradient calculations. Rather than providing an integer value to `level`, it is possible to target the `"user"`, `"gradient"` or `"device"` stages: ```python n_wires = 3 x = np.random.random((2, n_wires)) @​qml.qnode(qml.device("default.qubit")) def f(): qml.BasicEntanglerLayers(x, range(n_wires)) return qml.expval(qml.X(0)) ``` ```pycon >>> print(qml.draw(f, level="device")()) 0: โ”€โ”€RX(0.28)โ”€โ•ญโ—โ”€โ”€โ”€โ”€โ•ญXโ”€โ”€RX(0.70)โ”€โ•ญโ—โ”€โ”€โ”€โ”€โ•ญXโ”€โ”ค 1: โ”€โ”€RX(0.52)โ”€โ•ฐXโ”€โ•ญโ—โ”€โ”‚โ”€โ”€โ”€RX(0.65)โ”€โ•ฐXโ”€โ•ญโ—โ”€โ”‚โ”€โ”€โ”ค 2: โ”€โ”€RX(0.00)โ”€โ”€โ”€โ”€โ•ฐXโ”€โ•ฐโ—โ”€โ”€RX(0.03)โ”€โ”€โ”€โ”€โ•ฐXโ”€โ•ฐโ—โ”€โ”ค ```

Improvements ๐Ÿ› 

Community contributions, including UnitaryHACK ๐Ÿ’›

- `default.clifford` now supports arbitrary state-based measurements with `qml.Snapshot`. [(#​5794)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5794) - `qml.equal` now properly handles `Pow`, `Adjoint`, `Exp`, and `SProd` operators as arguments across different interfaces and tolerances with the addition of four new keyword arguments: `check_interface`, `check_trainability`, `atol` and `rtol`. [(#​5668)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5668) - The implementation for `qml.assert_equal` has been updated for `Operator`, `Controlled`, `Adjoint`, `Pow`, `Exp`, `SProd`, `ControlledSequence`, `Prod`, `Sum`, `Tensor` and `Hamiltonian` instances. [(#​5780)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5780) [(#​5877)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5877) - `qml.from_qasm` now supports the ability to convert mid-circuit measurements from `OpenQASM 2` code, and it can now also take an optional argument to specify a list of measurements to be performed at the end of the circuit, just like `qml.from_qiskit`. [(#​5818)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5818) - Four new operators have been added for simulating noise on the `default.qutrit.mixed` device: [(#​5502)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5502) [(#​5793)](https://redirect.github.com/PennyLaneAI/pennylane/issues/5793) [(#​5503)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5503) [(#​5757)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5757) [(#​5799)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5799) [(#​5784)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5784) - `qml.QutritDepolarizingChannel`: a channel that adds depolarizing noise. - `qml.QutritChannel`: enables the specification of noise using a collection of (3x3) Kraus matrices. - `qml.QutritAmplitudeDamping`: a channel that adds noise processes modelled by amplitude damping. - `qml.TritFlip`: a channel that adds trit flip errors, such as misclassification.

Faster and more flexible mid-circuit measurements

- The `default.qubit` device supports a depth-first tree-traversal algorithm to accelerate native mid-circuit measurement execution. Accessible through the QNode argument `mcm_method="tree-traversal"`, this new implementation supports classical control, collecting statistics, and post-selection, along with all measurements enabled with `qml.dynamic_one_shot`. More information about this new mid-circuit measurement method can be found on our [measurement documentation page](https://docs.pennylane.ai/en/stable/introduction/dynamic_quantum_circuits.html#tree-traversal-algorithm). [(#​5180)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5180) - `qml.QNode` and the `@qml.qnode` decorator now accept two new keyword arguments: `postselect_mode` and `mcm_method`. These keyword arguments can be used to configure how the device should behave when running circuits with mid-circuit measurements. [(#​5679)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5679) [(#​5833)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5833) [(#​5850)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5850) - `postselect_mode="hw-like"` indicates to devices to discard invalid shots when postselecting mid-circuit measurements. Use `postselect_mode="fill-shots"` to unconditionally sample the postselected value, thus making all samples valid. This is equivalent to sampling until the number of valid samples matches the total number of shots. - `mcm_method` will indicate which strategy to use for running circuits with mid-circuit measurements. Use `mcm_method="deferred"` to use the deferred measurements principle, or `mcm_method="one-shot"` to execute once for each shot. If `qml.qjit` is being used (the Catalyst compiler), `mcm_method="single-branch-statistics"` is also available. Using this method, a single branch of the execution tree will be randomly explored. - The `dynamic_one_shot` transform received a few improvements: - `dynamic_one_shot` is now compatible with `qml.qjit` (the Catalyst compiler). [(#​5766)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5766) [(#​5888)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5888) - `dynamic_one_shot` now uses a single auxiliary tape with a shot vector and `default.qubit` implements the loop over shots with `jax.vmap`. [(#​5617)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5617) - `dynamic_one_shot` is now compatible with `jax.jit`. [(#​5557)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5557) - When using `defer_measurements` with postselection, operations that will never be active due to the postselected state are skipped in the transformed quantum circuit. In addition, postselected controls are skipped, as they are evaluated when the transform is applied. This optimization feature can be turned off by setting `reduce_postselected=False`. [(#​5558)](https://redirect.github.com/PennyLaneAI/pennylane/pull/5558) Consider a simple circuit with three mid-circuit measurements, two of which are postselecting, and a single gate conditioned on those measurements: ```python @​qml.qnode(qml.device("default.qubit")) def node(x): qml.RX(x, 0) qml.RX(x, 1) qml.RX(x, 2) mcm0 = qml.measure(0, postselect=0, reset=False) mcm1 = qml.measure(1, postselect=None, reset=True) mcm2 = qml.measure(2, postselect=1, reset=False) qml.cond(mcm0 + mcm1 + mcm2 == 1, qml.RX)(0.5, 3) return qml.expval(qml.Z(0) @​ qml.Z(3)) ``` Without the new optimization, we obtain three gates, each controlled on the three measured qubits. They correspond to the combinations of controls that satisfy the condition `mcm0 + mcm1 + mcm2 == 1`: ```pycon >>> print(qml.draw(qml.defer_measurements(node, reduce_postselected=False))(0.6)) 0: โ”€โ”€RX(0.60)โ”€โ”€|0โŸฉโŸจ0|โ”€โ•ญโ—โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ•ญ 1: โ”€โ”€RX(0.60)โ”€โ”€โ”€โ”€

Configuration

๐Ÿ“… Schedule: Branch creation - "after 10pm every weekday,before 5am every weekday,every weekend" in timezone Asia/Tokyo, Automerge - At any time (no schedule defined).

๐Ÿšฆ Automerge: Disabled by config. Please merge this manually once you are satisfied.

โ™ป Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

๐Ÿ”• Ignore: Close this PR and you won't be reminded about this update again.



This PR was generated by Mend Renovate. View the repository job log.

codecov[bot] commented 8 months ago

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Project coverage is 92.35%. Comparing base (20b5f57) to head (bda7960).

:exclamation: Current head bda7960 differs from pull request most recent head 3d92eac. Consider uploading reports for the commit 3d92eac to get more accurate results

Additional details and impacted files ```diff @@ Coverage Diff @@ ## main #276 +/- ## ======================================= Coverage 92.35% 92.35% ======================================= Files 15 15 Lines 1086 1086 Branches 202 202 ======================================= Hits 1003 1003 Misses 50 50 Partials 33 33 ```

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

renovate[bot] commented 3 weeks ago

โš ๏ธ Artifact update problem

Renovate failed to update an artifact related to this branch. You probably do not want to merge this PR as-is.

โ™ป Renovate will retry this branch, including artifacts, only when one of the following happens:

The artifact failure details are included below:

File name: poetry.lock
Updating dependencies
Resolving dependencies...

Creating virtualenv skqulacs in /tmp/renovate/repos/github/Qulacs-Osaka/scikit-qulacs/.venv

The current project's Python requirement (>=3.8.1,<3.12) is not compatible with some of the required packages Python requirement:
  - pennylane-lightning requires Python >=3.9, so it will not be satisfied for Python >=3.8.1,<3.9

Because no versions of pennylane match >0.38.0,<0.39.0
 and pennylane (0.38.0) depends on pennylane-lightning (>=0.38), pennylane (>=0.38.0,<0.39.0) requires pennylane-lightning (>=0.38).
Because no versions of pennylane-lightning match >0.38
 and pennylane-lightning (0.38.0) requires Python >=3.9, pennylane-lightning is forbidden.
Thus, pennylane is forbidden.
So, because skqulacs depends on PennyLane (^0.38.0), version solving failed.

  โ€ข Check your dependencies Python requirement: The Python requirement can be specified via the `python` or `markers` properties

    For pennylane-lightning, a possible solution would be to set the `python` property to ">=3.9,<3.12"

    https://python-poetry.org/docs/dependency-specification/#python-restricted-dependencies,
    https://python-poetry.org/docs/dependency-specification/#using-environment-markers