From 65472190f4f518d33a8a11b936202e871d0e16cf Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 21:21:00 +0000 Subject: [PATCH] Daily rc sync to master (#6200) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Automatic sync from the release candidate to master during a feature freeze. --------- Co-authored-by: Astral Cai Co-authored-by: Christina Lee Co-authored-by: Utkarsh Co-authored-by: Pietropaolo Frisoni Co-authored-by: Guillermo Alonso-Linaje <65235481+KetpuntoG@users.noreply.github.com> Co-authored-by: Mudit Pandey Co-authored-by: Justin Pickering <79890410+justinpickering@users.noreply.github.com> Co-authored-by: lillian542 <38584660+lillian542@users.noreply.github.com> Co-authored-by: Jack Brown Co-authored-by: Diksha Dhawan <40900030+ddhawan11@users.noreply.github.com> Co-authored-by: soranjh <40344468+soranjh@users.noreply.github.com> Co-authored-by: soranjh Co-authored-by: Cristian Emiliano Godinez Ramirez <57567043+EmilianoG-byte@users.noreply.github.com> Co-authored-by: Alex Preciado Co-authored-by: Jorge J. Martínez de Lejarza <61199780+gmlejarza@users.noreply.github.com> Co-authored-by: Isaac De Vlugt <34751083+isaacdevlugt@users.noreply.github.com> Co-authored-by: Josh Izaac Co-authored-by: GitHub Actions Bot <> --- doc/_static/templates/arithmetic/adder.png | Bin 0 -> 24007 bytes .../arithmetic/integercomparator.png | Bin 0 -> 32690 bytes doc/_static/templates/arithmetic/modexp.png | Bin 0 -> 34670 bytes .../templates/arithmetic/multiplier.png | Bin 0 -> 26777 bytes doc/_static/templates/arithmetic/outadder.png | Bin 0 -> 32441 bytes .../templates/arithmetic/outmultiplier.png | Bin 0 -> 36317 bytes .../templates/arithmetic/phaseadder.png | Bin 0 -> 31542 bytes doc/code/qml_spin.rst | 15 + doc/development/deprecations.rst | 2 +- doc/index.rst | 3 +- doc/introduction/templates.rst | 39 ++ doc/releases/changelog-0.38.0.md | 600 ++++++++++++++---- pennylane/devices/qubit/sampling.py | 13 +- pennylane/math/matrix_manipulation.py | 4 + pennylane/spin/lattice.py | 7 +- pennylane/spin/spin_hamiltonian.py | 102 +-- pennylane/templates/subroutines/adder.py | 107 ++-- pennylane/templates/subroutines/mod_exp.py | 78 ++- pennylane/templates/subroutines/multiplier.py | 81 ++- pennylane/templates/subroutines/out_adder.py | 98 ++- .../templates/subroutines/out_multiplier.py | 101 ++- .../templates/subroutines/phase_adder.py | 79 ++- tests/capture/test_templates.py | 2 +- .../default_qubit/test_default_qubit.py | 46 ++ tests/devices/qubit/test_sampling.py | 12 +- tests/ops/functions/test_assert_valid.py | 2 +- tests/ops/op_math/test_prod.py | 10 + .../templates/test_subroutines/test_adder.py | 20 +- .../test_subroutines/test_mod_exp.py | 22 + .../test_subroutines/test_multiplier.py | 18 +- .../test_subroutines/test_out_adder.py | 25 + .../test_subroutines/test_out_multiplier.py | 25 + .../test_subroutines/test_phase_adder.py | 22 + 33 files changed, 1200 insertions(+), 333 deletions(-) create mode 100644 doc/_static/templates/arithmetic/adder.png create mode 100644 doc/_static/templates/arithmetic/integercomparator.png create mode 100644 doc/_static/templates/arithmetic/modexp.png create mode 100644 doc/_static/templates/arithmetic/multiplier.png create mode 100644 doc/_static/templates/arithmetic/outadder.png create mode 100644 doc/_static/templates/arithmetic/outmultiplier.png create mode 100644 doc/_static/templates/arithmetic/phaseadder.png create mode 100644 doc/code/qml_spin.rst diff --git a/doc/_static/templates/arithmetic/adder.png b/doc/_static/templates/arithmetic/adder.png new file mode 100644 index 0000000000000000000000000000000000000000..bff56c84e7abc0eaef3be8361fc0ea2d6b4f1d55 GIT binary patch literal 24007 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 IEoT<^KX@7qE&u=k literal 0 HcmV?d00001 diff --git a/doc/_static/templates/arithmetic/integercomparator.png b/doc/_static/templates/arithmetic/integercomparator.png new file mode 100644 index 0000000000000000000000000000000000000000..9ba2ec3df89a31ed0d5add3fcb1cb0facc48c6d3 GIT binary patch literal 32690 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˵Db+@|J6KkIh zw#RHLyUU*FqW3d47K{1q@fS{bD>|KeAe{c|0|A5KPXD4d=TGTkvmiy#52w$jB=$Wi4=NOY5#8% z&wJSImG!FSb-Nm^)(*!MO=h#7Q<1y6+V_RyvxN}4?gbtq2k#Lm(J>zY8(UtzVPSMy!Xx@ z(JynB5uzKed>6OtcD-6{60^Vru)%}Ary(OO#fC5&JvMp;Aj1i{zXzYEd!Nullszdj?cL zJY0Q#aQkd63qxouhF)Lp4Ld=a_h8*U{90F=<$}Sef-DNXWH%gIb~$HRAkUUgB?^N0 zna&AU+p1G%�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 b{RQf!(u7zKxwHEX@FO82D_kb1>-T>Fn-F_T literal 0 HcmV?d00001 diff --git a/doc/_static/templates/arithmetic/modexp.png b/doc/_static/templates/arithmetic/modexp.png new file mode 100644 index 0000000000000000000000000000000000000000..862b79d10fbd8042d76c5fdeb06161add9fcd93a GIT binary patch literal 34670 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 literal 0 HcmV?d00001 diff --git a/doc/_static/templates/arithmetic/outadder.png b/doc/_static/templates/arithmetic/outadder.png new file mode 100644 index 0000000000000000000000000000000000000000..e1bdfff6c8e3157f3307555e636943cd33910daf GIT binary patch literal 32441 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 ba!)$OzAx;VF#r6bc?elaC5f8XChz_)Zejxz literal 0 HcmV?d00001 diff --git a/doc/_static/templates/arithmetic/outmultiplier.png b/doc/_static/templates/arithmetic/outmultiplier.png new file mode 100644 index 0000000000000000000000000000000000000000..12a217f73b662683199eb215afa55bedf5c7eb6b GIT binary patch literal 36317 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 W{d__}?*CV_T1HY)qFT&2@c#kfsDTFn literal 0 HcmV?d00001 diff --git a/doc/code/qml_spin.rst b/doc/code/qml_spin.rst new file mode 100644 index 00000000000..97cc407587d --- /dev/null +++ b/doc/code/qml_spin.rst @@ -0,0 +1,15 @@ +qml.spin +========= + +Overview +-------- + +This module contains functions and classes for creating and manipulating Hamiltonians for the spin models. + +.. currentmodule:: pennylane.spin + +.. automodapi:: pennylane.spin + :no-heading: + :no-main-docstr: + :skip: Lattice + :include-all-objects: diff --git a/doc/development/deprecations.rst b/doc/development/deprecations.rst index 2f05830d4b8..5bd83558324 100644 --- a/doc/development/deprecations.rst +++ b/doc/development/deprecations.rst @@ -16,7 +16,7 @@ Pending deprecations - Will be removed in v0.39 * 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`. + compatible device is now deprecated, as it was in place for the deprecated ``default.qubit.legacy``. - Deprecated in v0.38 - Will be removed in v0.39 diff --git a/doc/index.rst b/doc/index.rst index be37298567b..85c20538942 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -216,7 +216,8 @@ PennyLane is **free** and **open source**, released under the Apache License, Ve code/qml_qaoa code/qml_qchem code/qml_qnn - + code/qml_spin + .. toctree:: :maxdepth: 1 :caption: Internals diff --git a/doc/introduction/templates.rst b/doc/introduction/templates.rst index f972735a51c..9593e203830 100644 --- a/doc/introduction/templates.rst +++ b/doc/introduction/templates.rst @@ -124,6 +124,45 @@ state preparation is typically used as the first operation. .. _intro_ref_temp_subroutines: +Arithmetic templates +-------------------- + +Quantum arithmetic templates enable in-place and out-place modular operations such +as addition, multiplication and exponentiation. + +.. gallery-item:: + :description: :doc:`PhaseAdder <../code/api/pennylane.PhaseAdder>` + :figure: _static/templates/arithmetic/phaseadder.png + +.. gallery-item:: + :description: :doc:`Adder <../code/api/pennylane.Adder>` + :figure: _static/templates/arithmetic/adder.png + +.. gallery-item:: + :description: :doc:`OutAdder <../code/api/pennylane.OutAdder>` + :figure: _static/templates/arithmetic/outadder.png + +.. gallery-item:: + :description: :doc:`Multiplier <../code/api/pennylane.Multiplier>` + :figure: _static/templates/arithmetic/multiplier.png + +.. gallery-item:: + :description: :doc:`OutMultiplier <../code/api/pennylane.OutMultiplier>` + :figure: _static/templates/arithmetic/outmultiplier.png + +.. gallery-item:: + :description: :doc:`ModExp <../code/api/pennylane.ModExp>` + :figure: _static/templates/arithmetic/modexp.png + +.. gallery-item:: + :description: :doc:`IntegerComparator <../code/api/pennylane.IntegerComparator>` + :figure: _static/templates/arithmetic/integercomparator.png + + +.. raw:: html + +

+ Quantum Chemistry templates --------------------------- diff --git a/doc/releases/changelog-0.38.0.md b/doc/releases/changelog-0.38.0.md index 9729959b83a..391f9dbf36d 100644 --- a/doc/releases/changelog-0.38.0.md +++ b/doc/releases/changelog-0.38.0.md @@ -4,112 +4,396 @@

New features since last release

-

Converting noise models from Qiskit ♻️

+

Registers of wires 🧸

-* A new `qml.from_qiskit_noise` method now allows one to convert a Qiskit ``NoiseModel`` to a - PennyLane ``NoiseModel`` via the Pennylane-Qiskit plugin. - [(#5996)](https://github.com/PennyLaneAI/pennylane/pull/5996) +* A new function called `qml.registers` has been added that lets you seamlessly create registers of + wires. + [(#5957)](https://github.com/PennyLaneAI/pennylane/pull/5957) + [(#6102)](https://github.com/PennyLaneAI/pennylane/pull/6102) -

Registers of wires 🌈

+ 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. -* Set operations are now supported by Wires. - [(#5983)](https://github.com/PennyLaneAI/pennylane/pull/5983) + ```python + >>> wire_reg = qml.registers({"alice": 4, "bob": 3}) + >>> wire_reg + {'alice': Wires([0, 1, 2, 3]), 'bob': Wires([4, 5, 6])} + ``` -* The representation for `Wires` has now changed to be more copy-paste friendly. - [(#5958)](https://github.com/PennyLaneAI/pennylane/pull/5958) + 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. -* A new function `qml.registers` has been added, enabling the creation of registers, which are implemented as a dictionary of `Wires` instances. - [(#5957)](https://github.com/PennyLaneAI/pennylane/pull/5957) - [(#6102)](https://github.com/PennyLaneAI/pennylane/pull/6102) + 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://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://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 🧮

-* The `qml.Adder` and `qml.PhaseAdder` templates are added to perform in-place modular addition. +* Several new operator templates have been added to PennyLane that let you perform quantum arithmetic + operations. [(#6109)](https://github.com/PennyLaneAI/pennylane/pull/6109) - -* The `qml.Multiplier` and `qml.OutMultiplier` templates are added to perform modular multiplication. [(#6112)](https://github.com/PennyLaneAI/pennylane/pull/6112) - -* The `qml.OutAdder` and `qml.ModExp` templates are added to perform out-of-place modular addition and modular exponentiation. [(#6121)](https://github.com/PennyLaneAI/pennylane/pull/6121) + * `qml.Adder` performs in-place modular addition: + :math:`\text{Adder}(k, m)\vert x \rangle = \vert x + k \; \text{mod} \; m\rangle`. -

Creating spin Hamiltonians 🧑‍🎨

+ * `qml.PhaseAdder` is similar to `qml.Adder`, but it performs in-place modular addition in the Fourier + basis. -* The function ``transverse_ising`` is added to generate transverse-field Ising Hamiltonian. - [(#6106)](https://github.com/PennyLaneAI/pennylane/pull/6106) + * `qml.Multiplier` performs in-place multiplication: + :math:`\text{Multiplier}(k, m)\vert x \rangle = \vert x \times k \; \text{mod} \; m \rangle`. -* The functions ``heisenberg`` and ``fermi_hubbard`` are added to generate Heisenberg and Fermi-Hubbard Hamiltonians respectively. - [(#6128)](https://github.com/PennyLaneAI/pennylane/pull/6128) + * `qml.OutAdder` performs out-place modular addition: + :math:`\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: + :math:`\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: + :math:`\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://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://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://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 🛠

-* Counts measurements with `all_outcomes=True` can now be used with jax jitting. Measurements - broadcasted across all available wires (`qml.probs()`) can now be used with jit and devices that - allow variable numbers of wires (`qml.device('default.qubit')`). - [(#6108)](https://github.com/PennyLaneAI/pennylane/pull/6108/) +

Creating spin Hamiltonians

+ +* Three new functions are now available for creating commonly-used spin Hamiltonians in PennyLane: + [(#6106)](https://github.com/PennyLaneAI/pennylane/pull/6106) + [(#6128)](https://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

-* The `qml.PrepSelPrep` template is added. The template implements a block-encoding of a linear - combination of unitaries. +* A new template called `qml.PrepSelPrep` has been added that implements a block-encoding of a linear + combination of unitaries. [(#5756)](https://github.com/PennyLaneAI/pennylane/pull/5756) [(#5987)](https://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://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. + the Trotter error, but would result in deeper circuits. [(#5801)](https://github.com/PennyLaneAI/pennylane/pull/5801) -* The `qubit_observable` function is modified to return an ascending wire order for molecular +* The `qml.qchem.qubit_observable` function has been modified to return an ascending wire order for molecular Hamiltonians. [(#5950)](https://github.com/PennyLaneAI/pennylane/pull/5950) -* A new method `to_mat` has been added to the `FermiWord` and `FermiSentence` classes, which allows - computing the matrix representation of these Fermi operators. +* 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://github.com/PennyLaneAI/pennylane/pull/5920) - -* `qml.pauli.group_observables` now uses `Rustworkx` colouring algorithms to solve the Minimum Clique Cover problem. - This adds two new options for the `method` argument: `dsatur` and `gis`. In addition, the creation of the adjacency matrix - now takes advantage of the symplectic representation of the Pauli observables. An additional function `qml.pauli.compute_partition_indices` - is added to calculate the indices from the partitioned observables more efficiently. `qml.pauli.grouping.PauliGroupingStrategy.idx_partitions_from_graph` - can be used to compute partitions of custom indices. These changes improve the wall time of `qml.LinearCombination.compute_grouping` - and `grouping_type='qwc'` by orders of magnitude. - [(#6043)](https://github.com/PennyLaneAI/pennylane/pull/6043)

Improvements to operators

-* `GlobalPhase` now supports parameter broadcasting. +* `qml.GlobalPhase` now supports parameter broadcasting. [(#5923)](https://github.com/PennyLaneAI/pennylane/pull/5923) -* Added the `compute_decomposition` method for `qml.Hermitian`. +* `qml.Hermitian` now has a `compute_decomposition` method. [(#6062)](https://github.com/PennyLaneAI/pennylane/pull/6062) -* Port the fast `apply_operation` implementation of `PauliZ` to `PhaseShift`, `S` and `T`. +* The implementation of `qml.PhaseShift`, `qml.S`, and `qml.T` has been improved, resulting in faster + circuit execution times. [(#5876)](https://github.com/PennyLaneAI/pennylane/pull/5876) -* The `tree-traversal` algorithm implemented in `default.qubit` is refactored - into an iterative (instead of recursive) implementation, doing away with - potential stack overflow for deep circuits. - [(#5868)](https://github.com/PennyLaneAI/pennylane/pull/5868) - -* The `tree-traversal` algorithm is compatible with analytic-mode execution (`shots=None`). - [(#5868)](https://github.com/PennyLaneAI/pennylane/pull/5868) - -* `fuse_rot_angles` now respects the global phase of the combined rotations. - [(#6031)](https://github.com/PennyLaneAI/pennylane/pull/6031) - -* The `CNOT` operator no longer decomposes to itself. Instead, it raises a `qml.DecompositionUndefinedError`. +* The `qml.CNOT` operator no longer decomposes into itself. Instead, it raises a `qml.DecompositionUndefinedError`. [(#6039)](https://github.com/PennyLaneAI/pennylane/pull/6039) -

Mid-circuit measurement improvements

+

Mid-circuit measurements

-* `qml.dynamic_one_shot` now supports circuits using the `"tensorflow"` interface. +* The `qml.dynamic_one_shot` transform now supports circuits using the `"tensorflow"` interface. [(#5973)](https://github.com/PennyLaneAI/pennylane/pull/5973) * If the conditional does not include a mid-circuit measurement, then `qml.cond` @@ -137,39 +421,41 @@

Transforms

-* The `diagonalize_measurements` transform is added. This transform converts measurements - to the Z basis by applying the relevant diagonalizing gates. It can be set to diagonalize only - a subset of the base observables `{X, Y, Z, Hadamard}`. +* `qml.transforms.single_qubit_fusion` and `qml.transforms.merge_rotations` now respect global phases. + [(#6031)](https://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://github.com/PennyLaneAI/pennylane/pull/5829) -* The `split_to_single_terms` transform is added. This transform splits expectation values of sums - into multiple single-term measurements on a single tape, providing better support for simulators +* 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://github.com/PennyLaneAI/pennylane/pull/5884) -* New functionality has been added to natively support exponential extrapolation when using the `mitigate_with_zne`. This allows - users to have more control over the error mitigation protocol without needing to add further dependencies. +* 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://github.com/PennyLaneAI/pennylane/pull/5972) -* `fuse_rot_angles` now respects the global phase of the combined rotations. - [(#6031)](https://github.com/PennyLaneAI/pennylane/pull/6031) -

Capturing and representing hybrid programs

* `qml.for_loop` now supports `range`-like syntax with default `step=1`. [(#6068)](https://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. +* 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://github.com/PennyLaneAI/pennylane/pull/5966) [(#5967)](https://github.com/PennyLaneAI/pennylane/pull/5967) [(#5999)](https://github.com/PennyLaneAI/pennylane/pull/5999) [(#6058)](https://github.com/PennyLaneAI/pennylane/pull/6058) -* During experimental program capture, functions that accept and/or return `pytree` structures can now be handled in the `QNode` call, `cond`, `for_loop` and `while_loop`. +* 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://github.com/PennyLaneAI/pennylane/pull/6081) -* During experimental program capture, the qnode can now use closure variables. +* During experimental program capture, QNodes can now use closure variables. [(#6052)](https://github.com/PennyLaneAI/pennylane/pull/6052) * Mid-circuit measurements can now be captured with `qml.capture` enabled. @@ -179,9 +465,8 @@ [(#6041)](https://github.com/PennyLaneAI/pennylane/pull/6041) [(#6064)](https://github.com/PennyLaneAI/pennylane/pull/6064) -* `qml.for_loop` and `qml.while_loop` now fallback to standard Python control - flow if `@qjit` is not present, allowing the same code to work with and without - `@qjit` without any rewrites. +* `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://github.com/PennyLaneAI/pennylane/pull/6014) ```python @@ -226,55 +511,80 @@

Community contributions 🥳

-* Resolved the bug in `qml.ThermalRelaxationError` where there was a typo from `tq` to `tg`. +* Fixed a bug in `qml.ThermalRelaxationError` where there was a typo from `tq` to `tg`. [(#5988)](https://github.com/PennyLaneAI/pennylane/issues/5988) -* `DefaultQutritMixed` readout error has been added using parameters `readout_relaxation_probs` and - `readout_misclassification_probs` on the `default.qutrit.mixed` device. These parameters add a `~.QutritAmplitudeDamping` and a `~.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://github.com/PennyLaneAI/pennylane/pull/5842)s +* 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://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://github.com/PennyLaneAI/pennylane/pull/5790)

Other improvements

-* Added the decomposition of zyz for special unitaries with multiple control wires. +* `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://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://github.com/PennyLaneAI/pennylane/pull/6108/) + +* `qml.ops.op_math.ctrl_decomp_zyz` can now decompose special unitaries with multiple control wires. [(#6042)](https://github.com/PennyLaneAI/pennylane/pull/6042) -* A new method `process_density_matrix` has been added to the `ProbabilityMP` and `DensityMatrixMP` - classes, 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. +* 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://github.com/PennyLaneAI/pennylane/pull/5830) * `SProd.terms` now flattens out the terms if the base is a multi-term observable. [(#5885)](https://github.com/PennyLaneAI/pennylane/pull/5885) -* `QNGOptimizer` now supports cost functions with multiple arguments, updating each argument independently. +* `qml.QNGOptimizer` now supports cost functions with multiple arguments, updating each argument independently. [(#5926)](https://github.com/PennyLaneAI/pennylane/pull/5926) -* Removed `semantic_version` from the list of required packages in PennyLane. +* `semantic_version` has been removed from the list of required packages in PennyLane. [(#5836)](https://github.com/PennyLaneAI/pennylane/pull/5836) -* `qml.devices.LegacyDeviceFacade` has been added to map the legacy devices to the new - device interface. +* `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://github.com/PennyLaneAI/pennylane/pull/5927) -* Added the `compute_sparse_matrix` method for `qml.ops.qubit.BasisStateProjector`. - [(#5790)](https://github.com/PennyLaneAI/pennylane/pull/5790) - -* `StateMP.process_state` defines rules in `cast_to_complex` for complex casting, avoiding a superfluous state vector copy in Lightning simulations +* `StateMP.process_state` now defines rules in `cast_to_complex` for complex casting, avoiding a superfluous + statevector copy in PennyLane-Lightning simulations. [(#5995)](https://github.com/PennyLaneAI/pennylane/pull/5995) * `QuantumScript.hash` is now cached, leading to performance improvements. [(#5919)](https://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). +* 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://github.com/PennyLaneAI/pennylane/pull/5890) -* Added `is_leaf` parameter to function `flatten` in the `qml.pytrees` module. This is to allow node flattening to be stopped for any node where the `is_leaf` optional argument evaluates to being `True`. +* 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://github.com/PennyLaneAI/pennylane/issues/6107) -* Added a progress bar when downloading datasets with `qml.data.load()` +* A progress bar has been added to `qml.data.load()` when downloading a dataset. [(#5560)](https://github.com/PennyLaneAI/pennylane/pull/5560) * Upgraded and simplified `StatePrep` and `AmplitudeEmbedding` templates. @@ -287,33 +597,34 @@

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 - jitting when a measurement is broadcasted across all available wires, but the device does not specify wires. + `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://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. +* If the shape of a probability measurement is affected by a `Device.cutoff` property, it will no longer + work with jitting. [(#6108)](https://github.com/PennyLaneAI/pennylane/pull/6108/) -* `GlobalPhase` is considered non-differentiable with tape transforms. - As a consequence, `qml.gradients.finite_diff` and `qml.gradients.spsa_grad` no longer - support differentiation of `GlobalPhase` with state-based outputs. +* `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://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. +* 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://github.com/PennyLaneAI/pennylane/pull/5907) -* `queue_idx` attribute has been removed from the `Operator`, `CompositeOp`, and `SymbolicOp` classes. +* The `queue_idx` attribute has been removed from the `Operator`, `CompositeOp`, and `SymbolicOp` classes. [(#6005)](https://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. +* `qml.from_qasm` no longer removes measurements from the QASM code. Use `measurements=[]` to remove + measurements from the original circuit. [(#5982)](https://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 :func:`~.pennylane.transform` for more information. +* `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://github.com/PennyLaneAI/pennylane/pull/5981) * `QuantumScript.interface` has been removed. @@ -327,7 +638,7 @@ * The `max_expansion` argument in `qml.QNode` has been deprecated. [(#6026)](https://github.com/PennyLaneAI/pennylane/pull/6026) -* The `expansion_strategy` attribute in the `QNode` class is deprecated. +* The `expansion_strategy` attribute `qml.QNode` has been deprecated. [(#5989)](https://github.com/PennyLaneAI/pennylane/pull/5989) * The `expansion_strategy` argument has been deprecated in all of `qml.draw`, `qml.draw_mpl`, and `qml.specs`. @@ -338,32 +649,33 @@ for equivalent behaviour. [(#5994)](https://github.com/PennyLaneAI/pennylane/pull/5994) -* `pennylane.transforms.sum_expand` and `pennylane.transforms.hamiltonian_expand` have been deprecated. - Users should instead use `pennylane.transforms.split_non_commuting` for equivalent behaviour. +* `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://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`. +* 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://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 `TransformProgram` and pass it to the `transform_program` argument of `qml.execute`. + 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://github.com/PennyLaneAI/pennylane/pull/5984) -* The `override_shots` argument in `qml.execute` is deprecated. - Instead, please add the shots to the `QuantumTape`'s to be executed. +* The `override_shots` argument in `qml.execute` has been deprecated. + Instead, please add the shots to the `QuantumTape`s to be executed. [(#5984)](https://github.com/PennyLaneAI/pennylane/pull/5984) -* The `device_batch_transform` argument in `qml.execute` is deprecated. +* 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://github.com/PennyLaneAI/pennylane/pull/5984) -* `pennylane.qinfo.classical_fisher` and `pennylane.qinfo.quantum_fisher` have been deprecated. - Instead, use `pennylane.gradients.classical_fisher` and `pennylane.gradients.quantum_fisher`. +* `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://github.com/PennyLaneAI/pennylane/pull/5985) -* The legacy devices `default.qubit.{autograd,torch,tf,jax,legacy}` are deprecated. - Instead, use `default.qubit` as it now supports backpropagation through the several backends. +* 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://github.com/PennyLaneAI/pennylane/pull/5997) * The logic for internally switching a device for a different backpropagation @@ -373,15 +685,23 @@

Documentation 📝

-* Improves the docstring for `qinfo.quantum_fisher` regarding the internally used functions and - potentially required auxiliary wires. +* The docstring for `qml.qinfo.quantum_fisher`, regarding the internally used functions and potentially + required auxiliary wires, has been improved. [(#6074)](https://github.com/PennyLaneAI/pennylane/pull/6074) -* Improves the docstring for `QuantumScript.expand` and `qml.tape.tape.expand_tape`. +* The docstring for `QuantumScript.expand` and `qml.tape.tape.expand_tape` has been improved. [(#5974)](https://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://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://github.com/PennyLaneAI/pennylane/pull/6190) + * Fix Pytree serialization of operators with empty shot vectors [(#6155)](https://github.com/PennyLaneAI/pennylane/pull/6155) @@ -395,17 +715,17 @@ batch size. [(#6147)](https://github.com/PennyLaneAI/pennylane/pull/6147) -* Catalyst replaced `argnum` with `argnums` in gradient related functions, therefore we update the Catalyst +* Catalyst replaced `argnum` with `argnums` in gradient related functions, therefore we updated the Catalyst calls to those functions in PennyLane. [(#6117)](https://github.com/PennyLaneAI/pennylane/pull/6117) -* `fuse_rot_angles` no longer returns wrong derivatives at singular points but returns NaN. +* `fuse_rot_angles` now returns NaN instead of incorrect derivatives at singular points. [(#6031)](https://github.com/PennyLaneAI/pennylane/pull/6031) -* `qml.GlobalPhase` and `qml.I` can now be captured when acting on no wires. +* `qml.GlobalPhase` and `qml.Identity` can now be captured with plxpr when acting on no wires. [(#6060)](https://github.com/PennyLaneAI/pennylane/pull/6060) -* Fix `jax.grad` + `jax.jit` not working for `AmplitudeEmbedding`, `StatePrep` and `MottonenStatePreparation`. +* Fixed `jax.grad` and `jax.jit` to work for `qml.AmplitudeEmbedding`, `qml.StatePrep` and `qml.MottonenStatePreparation`. [(#5620)](https://github.com/PennyLaneAI/pennylane/pull/5620) * Fixed a bug in `qml.center` that omitted elements from the center if they were @@ -418,35 +738,37 @@ * Fixed a bug in `qml.SPSAOptimizer` that ignored keyword arguments in the objective function. [(#6027)](https://github.com/PennyLaneAI/pennylane/pull/6027) -* `dynamic_one_shot` was broken for old-API devices since `override_shots` was deprecated. +* Fixed `dynamic_one_shot` for use with devices using the old device API, since `override_shots` was deprecated. [(#6024)](https://github.com/PennyLaneAI/pennylane/pull/6024) * `CircuitGraph` can now handle circuits with the same operation instance occuring multiple times. [(#5907)](https://github.com/PennyLaneAI/pennylane/pull/5907) -* `qml.QSVT` is updated to store wire order correctly. +* `qml.QSVT` has been updated to store wire order correctly. [(#5959)](https://github.com/PennyLaneAI/pennylane/pull/5959) * `qml.devices.qubit.measure_with_samples` now returns the correct result if the provided measurements - contain sum of operators acting on the same wire. + contain a sum of operators acting on the same wire. [(#5978)](https://github.com/PennyLaneAI/pennylane/pull/5978) * `qml.AmplitudeEmbedding` has better support for features using low precision integer data types. [(#5969)](https://github.com/PennyLaneAI/pennylane/pull/5969) -* `qml.BasisState` and `qml.BasisEmbedding` now works with jax.jit, lightning.qubit and give the correct decomposition. +* `qml.BasisState` and `qml.BasisEmbedding` now works with jax.jit, `lightning.qubit`, and give the correct + decomposition. [(#6021)](https://github.com/PennyLaneAI/pennylane/pull/6021) -* Jacobian shape is fixed for measurements with dimension in `qml.gradients.vjp.compute_vjp_single`. -[(5986)](https://github.com/PennyLaneAI/pennylane/pull/5986) +* Jacobian shape has been fixed for measurements with dimension in `qml.gradients.vjp.compute_vjp_single`. + [(5986)](https://github.com/PennyLaneAI/pennylane/pull/5986) -* `qml.lie_closure` works with sums of Paulis. +* `qml.lie_closure` now works with sums of Paulis. [(#6023)](https://github.com/PennyLaneAI/pennylane/pull/6023) * Workflows that parameterize the coefficients of `qml.exp` are now jit-compatible. [(#6082)](https://github.com/PennyLaneAI/pennylane/pull/6082) -* Fixes a bug where `CompositeOp.overlapping_ops` changes the original ordering of ops, causing incorrect matrix generated for `Prod` with `Sum` as operands. +* 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://github.com/PennyLaneAI/pennylane/pull/6091) * `qml.qsvt` now works with "Wx" convention and any number of angles. diff --git a/pennylane/devices/qubit/sampling.py b/pennylane/devices/qubit/sampling.py index 50377cbad90..be6090a0354 100644 --- a/pennylane/devices/qubit/sampling.py +++ b/pennylane/devices/qubit/sampling.py @@ -471,9 +471,9 @@ def sample_state( Returns: ndarray[int]: Sample values of the shape (shots, num_wires) """ - if prng_key is not None: + if prng_key is not None or qml.math.get_interface(state) == "jax": return _sample_state_jax( - state, shots, prng_key, is_state_batched=is_state_batched, wires=wires + state, shots, prng_key, is_state_batched=is_state_batched, wires=wires, seed=rng ) rng = np.random.default_rng(rng) @@ -530,6 +530,7 @@ def _sample_state_jax( prng_key, is_state_batched: bool = False, wires=None, + seed=None, ) -> np.ndarray: """ Returns a series of samples of a state for the JAX interface based on the PRNG. @@ -541,6 +542,7 @@ def _sample_state_jax( the key to the JAX pseudo random number generator. is_state_batched (bool): whether the state is batched or not wires (Sequence[int]): The wires to sample + seed (numpy.random.Generator): seed to use to generate a key if a ``prng_key`` is not present. ``None`` by default. Returns: ndarray[int]: Sample values of the shape (shots, num_wires) @@ -549,7 +551,8 @@ def _sample_state_jax( import jax import jax.numpy as jnp - key = prng_key + if prng_key is None: + prng_key = jax.random.PRNGKey(np.random.default_rng(seed).integers(100000)) total_indices = len(state.shape) - is_state_batched state_wires = qml.wires.Wires(range(total_indices)) @@ -574,6 +577,6 @@ def _sample_state_jax( _, key = jax_random_split(prng_key) samples = jax.random.choice(key, basis_states, shape=(shots,), p=probs) - powers_of_two = 1 << np.arange(num_wires, dtype=np.int64)[::-1] + powers_of_two = 1 << np.arange(num_wires, dtype=int)[::-1] states_sampled_base_ten = samples[..., None] & powers_of_two - return (states_sampled_base_ten > 0).astype(np.int64) + return (states_sampled_base_ten > 0).astype(int) diff --git a/pennylane/math/matrix_manipulation.py b/pennylane/math/matrix_manipulation.py index fb06140011d..6e2d487ac19 100644 --- a/pennylane/math/matrix_manipulation.py +++ b/pennylane/math/matrix_manipulation.py @@ -105,6 +105,10 @@ def expand_matrix(mat, wires, wire_order=None, sparse_format="csr"): if (wire_order is None) or (wire_order == wires): return mat + if not wires and qml.math.shape(mat) == (2, 2): + # global phase + wires = wire_order[0:1] + wires = list(wires) wire_order = list(wire_order) diff --git a/pennylane/spin/lattice.py b/pennylane/spin/lattice.py index 5a8ec5511fa..84bae270698 100644 --- a/pennylane/spin/lattice.py +++ b/pennylane/spin/lattice.py @@ -33,7 +33,8 @@ class Lattice: n_cells (list[int]): Number of cells in each direction of the grid. vectors (list[list[float]]): Primitive vectors for the lattice. positions (list[list[float]]): Initial positions of spin cites. Default value is - ``[[0.0]*number of dimensions]``. + ``[[0.0]`` :math:`\times` ``number of dimensions]``. + boundary_condition (bool or list[bool]): Defines boundary conditions in different lattice axes, default is ``False`` indicating open boundary condition. neighbour_order (int): Specifies the interaction level for neighbors within the lattice. @@ -53,13 +54,15 @@ class Lattice: Lattice object **Example** + >>> n_cells = [2,2] >>> vectors = [[0, 1], [1, 0]] >>> boundary_condition = [True, False] >>> lattice = qml.spin.Lattice(n_cells, vectors, >>> boundary_condition=boundary_condition) - >>> print(lattice.edges) + >>> lattice.edges [(2, 3, 0), (0, 2, 0), (1, 3, 0), (0, 1, 0)] + """ def __init__( diff --git a/pennylane/spin/spin_hamiltonian.py b/pennylane/spin/spin_hamiltonian.py index 71cf365dc1a..3d6c78cd1f2 100644 --- a/pennylane/spin/spin_hamiltonian.py +++ b/pennylane/spin/spin_hamiltonian.py @@ -27,7 +27,7 @@ def transverse_ising( lattice, n_cells, coupling=1.0, h=1.0, boundary_condition=False, neighbour_order=1 ): - r"""Generates the transverse-field Ising model on a lattice. + r"""Generates the Hamiltonian for the transverse-field Ising model on a lattice. The Hamiltonian is represented as: @@ -39,20 +39,21 @@ def transverse_ising( transverse magnetic field and ``i,j`` represent the indices for neighbouring spins. Args: - lattice (str): Shape of the lattice. Input Values can be ``'chain'``, ``'square'``, - ``'rectangle'``, ``'honeycomb'``, ``'triangle'``, or ``'kagome'``. - n_cells (List[int]): Number of cells in each direction of the grid. - coupling (float or List[float] or List[math.array[float]]): Coupling between spins. It can be a - number, a list of length equal to ``neighbour_order`` or a square matrix of size - ``(num_spins, num_spins)``. Default value is 1.0. - h (float): Value of external magnetic field. Default is 1.0. - boundary_condition (bool or list[bool]): Defines boundary conditions for different lattice axes, - default is ``False`` indicating open boundary condition. - neighbour_order (int): Specifies the interaction level for neighbors within the lattice. - Default is 1, indicating nearest neighbours. + lattice (str): Shape of the lattice. Input values can be ``'chain'``, ``'square'``, + ``'rectangle'``, ``'honeycomb'``, ``'triangle'``, or ``'kagome'``. + n_cells (List[int]): Number of cells in each direction of the grid. + coupling (float or List[float] or List[math.array[float]]): Coupling between spins. It can + be a number, a list of length equal to ``neighbour_order`` or a square matrix of shape + ``(num_spins, num_spins)``, where ``num_spins`` is the total number of spins. Default + value is 1.0. + h (float): Value of external magnetic field. Default is 1.0. + boundary_condition (bool or list[bool]): Defines boundary conditions for different lattice + axes, default is ``False`` indicating open boundary condition. + neighbour_order (int): Specifies the interaction level for neighbors within the lattice. + Default is 1, indicating nearest neighbours. Returns: - pennylane.LinearCombination: Hamiltonian for the transverse-field Ising model. + ~ops.op_math.Sum: Hamiltonian for the transverse-field Ising model. **Example** @@ -102,7 +103,7 @@ def transverse_ising( def heisenberg(lattice, n_cells, coupling=None, boundary_condition=False, neighbour_order=1): - r"""Generates the Heisenberg model on a lattice. + r"""Generates the Hamiltonian for the Heisenberg model on a lattice. The Hamiltonian is represented as: @@ -110,22 +111,23 @@ def heisenberg(lattice, n_cells, coupling=None, boundary_condition=False, neighb \hat{H} = J\sum_{}(\sigma_i^x\sigma_j^x + \sigma_i^y\sigma_j^y + \sigma_i^z\sigma_j^z) - where ``J`` is the coupling constant defined for the Hamiltonian, and ``i,j`` represent the indices for neighbouring spins. + where ``J`` is the coupling constant defined for the Hamiltonian, and ``i,j`` represent the + indices for neighbouring spins. Args: - lattice (str): Shape of the lattice. Input Values can be ``'chain'``, ``'square'``, ``'rectangle'``, - ``'honeycomb'``, ``'triangle'``, or ``'kagome'``. - n_cells (List[int]): Number of cells in each direction of the grid. - coupling (List[List[float]] or List[math.array[float]]): Coupling between spins. It can be a 2D array - of shape (neighbour_order, 3) or a 3D array of shape 3 * number of spins * number of spins. - Default value is [1.0, 1.0, 1.0]. - boundary_condition (bool or list[bool]): Defines boundary conditions for different lattice axes, - default is ``False`` indicating open boundary condition. - neighbour_order (int): Specifies the interaction level for neighbors within the lattice. - Default is 1, indicating nearest neighbours. + lattice (str): Shape of the lattice. Input values can be ``'chain'``, ``'square'``, + ``'rectangle'``, ``'honeycomb'``, ``'triangle'``, or ``'kagome'``. + n_cells (List[int]): Number of cells in each direction of the grid. + coupling (List[List[float]] or List[math.array[float]]): Coupling between spins. It can be a + 2D array of shape ``(neighbour_order, 3)`` or a 3D array of shape + ``(3, num_spins, num_spins)``, where ``num_spins`` is the total number of spins. + boundary_condition (bool or list[bool]): Defines boundary conditions for different lattice + axes, default is ``False`` indicating open boundary condition. + neighbour_order (int): Specifies the interaction level for neighbors within the lattice. + Default is 1, indicating nearest neighbours. Returns: - pennylane.LinearCombination: Hamiltonian for the heisenberg model. + ~ops.op_math.Sum: Hamiltonian for the heisenberg model. **Example** @@ -192,7 +194,7 @@ def fermi_hubbard( neighbour_order=1, mapping="jordan_wigner", ): - r"""Generates the Fermi-Hubbard model on a lattice. + r"""Generates the Hamiltonian for the Fermi-Hubbard model on a lattice. The Hamiltonian is represented as: @@ -200,37 +202,41 @@ def fermi_hubbard( \hat{H} = -t\sum_{, \sigma}(c_{i\sigma}^{\dagger}c_{j\sigma}) + U\sum_{i}n_{i \uparrow} n_{i\downarrow} - where ``t`` is the hopping term representing the kinetic energy of electrons, ``U`` is the on-site Coulomb interaction, - representing the repulsion between electrons, ``i,j`` represent the indices for neighbouring spins, ``\sigma`` - is the spin degree of freedom, and ``n_{i \uparrow}, n_{i \downarrow}`` are number operators for spin-up and - spin-down fermions at site ``i``. - This function assumes there are two fermions with opposite spins on each lattice site. + where ``t`` is the hopping term representing the kinetic energy of electrons, ``U`` is the + on-site Coulomb interaction, representing the repulsion between electrons, ``i,j`` represent the + indices for neighbouring spins, :math:`\sigma` is the spin degree of freedom, and + :math:`n_{i \uparrow}, n_{i \downarrow}` are number operators for spin-up and spin-down fermions + at site ``i``. This function assumes there are two fermions with opposite spins on each lattice + site. Args: - lattice (str): Shape of the lattice. Input Values can be ``'chain'``, ``'square'``, - ``'rectangle'``, ``'honeycomb'``, ``'triangle'``, or ``'kagome'``. - n_cells (List[int]): Number of cells in each direction of the grid. - hopping (float or List[float] or List[math.array(float)]): Hopping strength between neighbouring sites, it can be a - number, a list of length equal to ``neighbour_order`` or a square matrix of size - ``(num_spins, num_spins)``. Default value is 1.0. - coulomb (float or List[float]): Coulomb interaction between spins, it can be a constant or a list of length ``num_spins``. - boundary_condition (bool or list[bool]): Defines boundary conditions for different lattice axes, - default is ``False`` indicating open boundary condition. - neighbour_order (int): Specifies the interaction level for neighbors within the lattice. - Default is 1, indicating nearest neighbours. - mapping (str): Specifies the fermion-to-qubit mapping. Input values can be - ``'jordan_wigner'``, ``'parity'`` or ``'bravyi_kitaev'``. + lattice (str): Shape of the lattice. Input values can be ``'chain'``, ``'square'``, + ``'rectangle'``, ``'honeycomb'``, ``'triangle'``, or ``'kagome'``. + n_cells (List[int]): Number of cells in each direction of the grid. + hopping (float or List[float] or List[math.array(float)]): Hopping strength between + neighbouring sites, it can be a number, a list of length equal to ``neighbour_order`` or + a square matrix of size ``(num_spins, num_spins)``, where ``num_spins`` is the total + number of spins. Default value is 1.0. + coulomb (float or List[float]): Coulomb interaction between spins. It can be a constant or a + list of length equal to number of spins. + boundary_condition (bool or list[bool]): Defines boundary conditions for different lattice + axes, default is ``False`` indicating open boundary condition. + neighbour_order (int): Specifies the interaction level for neighbors within the lattice. + Default is 1, indicating nearest neighbours. + mapping (str): Specifies the fermion-to-qubit mapping. Input values can be + ``'jordan_wigner'``, ``'parity'`` or ``'bravyi_kitaev'``. Returns: - pennylane.operator: Hamiltonian for the Fermi-Hubbard model. + ~ops.op_math.Sum: Hamiltonian for the Fermi-Hubbard model. **Example** >>> n_cells = [2] >>> h = [0.5] - >>> u = [1.0] + >>> u = 1.0 >>> spin_ham = qml.spin.fermi_hubbard("chain", n_cells, hopping=h, coulomb=u) >>> spin_ham + ( -0.25 * (Y(0) @ Z(1) @ Y(2)) + -0.25 * (X(0) @ Z(1) @ X(2)) + 0.5 * I(0) @@ -242,7 +248,7 @@ def fermi_hubbard( + -0.25 * Z(3) + -0.25 * Z(2) + 0.25 * (Z(2) @ Z(3)) - + ) """ lattice = _generate_lattice(lattice, n_cells, boundary_condition, neighbour_order) diff --git a/pennylane/templates/subroutines/adder.py b/pennylane/templates/subroutines/adder.py index 32a621c4985..074b92f6ab3 100644 --- a/pennylane/templates/subroutines/adder.py +++ b/pennylane/templates/subroutines/adder.py @@ -22,54 +22,79 @@ class Adder(Operation): r"""Performs the in-place modular addition operation. - This operator performs the modular addition by an integer :math:`k` modulo :math:`mod` in the - computational basis: + This operator performs the modular addition by an integer :math:`k` modulo :math:`mod` in the + computational basis: - .. math:: + .. math:: - \text{Adder}(k, mod) |x \rangle = | x+k \; \text{modulo} \; mod \rangle. + \text{Adder}(k, mod) |x \rangle = | x+k \; \text{mod} \; mod \rangle. - The implementation is based on the quantum Fourier transform method presented in - `arXiv:2311.08555 `_. + The implementation is based on the quantum Fourier transform method presented in + `arXiv:2311.08555 `_. .. note:: - Note that :math:`x` must be smaller than :math:`mod` to get the correct result. + To obtain the correct result, :math:`x` must be smaller than :math:`mod`. + .. seealso:: :class:`~.PhaseAdder` and :class:`~.OutAdder`. - Args: - k (int): the number that needs to be added - x_wires (Sequence[int]): the wires the operation acts on - mod (int): the modulus for performing the addition, default value is :math:`2^{len(x\_wires)}` - work_wires (Sequence[int]): the auxiliary wires to be used for performing the addition + Args: + k (int): the number that needs to be added + x_wires (Sequence[int]): the wires the operation acts on. The number of wires must be enough + for encoding `x` in the computational basis. The number of wires also limits the + maximum value for `mod`. + mod (int): the modulo for performing the addition. If not provided, it will be set to its maximum value, :math:`2^{\text{len(x_wires)}}`. + work_wires (Sequence[int]): the auxiliary wires to use for the addition. The + work wires are not needed if :math:`mod=2^{\text{len(x_wires)}}`, otherwise two work wires + should be provided. Defaults to ``None``. - **Example** + **Example** This example computes the sum of two integers :math:`x=8` and :math:`k=5` modulo :math:`mod=15`. - .. code-block:: + .. code-block:: - x = 8 - k = 5 - mod = 15 + x = 8 + k = 5 + mod = 15 - x_wires =[0,1,2,3] - work_wires=[4,5] + x_wires =[0,1,2,3] + work_wires=[4,5] - dev = qml.device("default.qubit", shots=1) - @qml.qnode(dev) - def circuit(x, k, mod, x_wires, work_wires): - qml.BasisEmbedding(x, wires=x_wires) - qml.Adder(k, x_wires, mod, work_wires) - return qml.sample(wires=x_wires) + dev = qml.device("default.qubit", shots=1) + @qml.qnode(dev) + def circuit(): + qml.BasisEmbedding(x, wires=x_wires) + qml.Adder(k, x_wires, mod, work_wires) + return qml.sample(wires=x_wires) - .. code-block:: pycon + .. code-block:: pycon - >>> print(circuit(x, k, mod,x_wires, work_wires)) - [1 1 0 1] + >>> print(circuit()) + [1 1 0 1] - The result, :math:`[1 1 0 1]`, is the ket representation of - :math:`8 + 5 \, \text{modulo} \, 15 = 13`. + The result, :math:`[1 1 0 1]`, is the binary representation of + :math:`8 + 5 \; \text{modulo} \; 15 = 13`. + + .. details:: + :title: Usage Details + + This template takes as input two different sets of wires. + + The first one is ``x_wires``, used to encode the integer :math:`x < \text{mod}` in the Fourier basis. + To represent :math:`x`, ``x_wires`` must include at least :math:`\lceil \log_2(x) \rceil` wires. + After the modular addition, the result can be as large as :math:`\text{mod} - 1`, + requiring at least :math:`\lceil \log_2(\text{mod}) \rceil` wires. Since :math:`x < \text{mod}`, + :math:`\lceil \log_2(\text{mod}) \rceil` is a sufficient length for ``x_wires`` to cover all possible inputs and outputs. + + The second set of wires is ``work_wires`` which consist of the auxiliary qubits used to perform the modular addition operation. + + - If :math:`mod = 2^{\text{len(x_wires)}}`, there will be no need for ``work_wires``, hence ``work_wires=None``. This is the case by default. + + - If :math:`mod \neq 2^{\text{len(x_wires)}}`, two ``work_wires`` have to be provided. + + Note that the ``Adder`` template allows us to perform modular addition in the computational basis. However if one just wants to perform standard addition (with no modulo), that would be equivalent to setting + the modulo :math:`mod` to a large enough value to ensure that :math:`x+k < mod`. """ grad_method = None @@ -80,17 +105,22 @@ def __init__( x_wires = qml.wires.Wires(x_wires) + num_works_wires = 0 if work_wires is None else len(work_wires) + if mod is None: mod = 2 ** len(x_wires) - elif work_wires is None and mod != 2 ** len(x_wires): - raise ValueError(f"If mod is not 2^{len(x_wires)}, two work wires should be provided.") + elif mod != 2 ** len(x_wires) and num_works_wires != 2: + raise ValueError(f"If mod is not 2^{len(x_wires)}, two work wires should be provided") if not isinstance(k, int) or not isinstance(mod, int): raise ValueError("Both k and mod must be integers") if work_wires is not None: if any(wire in work_wires for wire in x_wires): raise ValueError("None of the wires in work_wires should be included in x_wires.") if mod > 2 ** len(x_wires): - raise ValueError("Adder must have enough x_wires to represent mod.") + raise ValueError( + "Adder must have enough x_wires to represent mod. The maximum mod " + f"with len(x_wires)={len(x_wires)} is {2 ** len(x_wires)}, but received {mod}." + ) self.hyperparameters["k"] = k self.hyperparameters["mod"] = mod @@ -135,11 +165,16 @@ def _primitive_bind_call(cls, *args, **kwargs): @staticmethod def compute_decomposition(k, x_wires, mod, work_wires): # pylint: disable=arguments-differ r"""Representation of the operator as a product of other operators. + Args: k (int): the number that needs to be added - x_wires (Sequence[int]): the wires the operation acts on - mod (int): the modulus for performing the addition, default value is :math:`2^{len(x\_wires)}` - work_wires (Sequence[int]): the auxiliary wires to be used for performing the addition + x_wires (Sequence[int]): the wires the operation acts on. The number of wires must be enough + for encoding `x` in the computational basis. The number of wires also limits the + maximum value for `mod`. + mod (int): the modulo for performing the addition. If not provided, it will be set to its maximum value, :math:`2^{\text{len(x_wires)}}`. + work_wires (Sequence[int]): the auxiliary wires to use for the addition. The + work wires are not needed if :math:`mod=2^{\text{len(x_wires)}}`, otherwise two work wires + should be provided. Defaults to ``None``. Returns: list[.Operator]: Decomposition of the operator diff --git a/pennylane/templates/subroutines/mod_exp.py b/pennylane/templates/subroutines/mod_exp.py index 52d652d5dfb..37e15d016e7 100644 --- a/pennylane/templates/subroutines/mod_exp.py +++ b/pennylane/templates/subroutines/mod_exp.py @@ -14,6 +14,8 @@ """ Contains the ModExp template. """ +import numpy as np + import pennylane as qml from pennylane.operation import Operation @@ -26,26 +28,28 @@ class ModExp(Operation): .. math:: - \text{ModExp}(base,mod) |x \rangle |k \rangle = |x \rangle |k*base^x \, \text{mod} \, mod \rangle, + \text{ModExp}(base,mod) |x \rangle |b \rangle = |x \rangle |b \cdot base^x \; \text{mod} \; mod \rangle, The implementation is based on the quantum Fourier transform method presented in `arXiv:2311.08555 `_. .. note:: - Note that :math:`x` must be smaller than :math:`mod` to get the correct result. - Also, it is required that :math:`base` has inverse, :math:`base^-1` modulo :math:`mod`. - That means :math:`base*base^-1 modulo mod = 1`, which will only be possible if :math:`base` + To obtain the correct result, :math:`x` must be smaller than :math:`mod`. + Also, it is required that :math:`base` has a modular inverse, :math:`base^{-1}`, with respect to :math:`mod`. + That means :math:`base \cdot base^{-1}` modulo :math:`mod` is equal to 1, which will only be possible if :math:`base` and :math:`mod` are coprime. + .. seealso:: :class:`~.Multiplier`. + Args: x_wires (Sequence[int]): the wires that store the integer :math:`x` - output_wires (Sequence[int]): the wires that store the exponentiation result + output_wires (Sequence[int]): the wires that store the operator result. These wires also encode :math:`b`. base (int): integer that needs to be exponentiated - mod (int): the modulus for performing the exponentiation, default value is :math:`2^{len(output\_wires)}` - work_wires (Sequence[int]): the auxiliary wires to be used for the exponentiation. There - must be as many as ``output_wires`` and if :math:`mod \neq 2^{len(x\_wires)}`, two more - wires must be added. + mod (int): the modulo for performing the exponentiation. If not provided, it will be set to its maximum value, :math:`2^{\text{len(output_wires)}}` + work_wires (Sequence[int]): the auxiliary wires to use for the exponentiation. If + :math:`mod=2^{\text{len(output_wires)}}`, the number of auxiliary wires must be ``len(output_wires)``. Otherwise + ``len(output_wires) + 2`` auxiliary wires are needed. **Example** @@ -53,17 +57,19 @@ class ModExp(Operation): .. code-block:: - x, k = 3, 1 + x, b = 3, 1 base = 2 mod = 7 + x_wires = [0, 1] output_wires = [2, 3, 4] work_wires = [5, 6, 7, 8, 9] + dev = qml.device("default.qubit", shots=1) @qml.qnode(dev) def circuit(): qml.BasisEmbedding(x, wires = x_wires) - qml.BasisEmbedding(k, wires = output_wires) + qml.BasisEmbedding(b, wires = output_wires) qml.ModExp(x_wires, output_wires, base, mod, work_wires) return qml.sample(wires = output_wires) @@ -72,8 +78,35 @@ def circuit(): >>> print(circuit()) [0 0 1] - The result :math:`[0 0 1]`, is the ket representation of - :math:`2^3 \, \text{modulo} \, 7 = 1`. + The result :math:`[0 0 1]`, is the binary representation of + :math:`2^3 \; \text{modulo} \; 7 = 1`. + + .. details:: + :title: Usage Details + + This template takes as input three different sets of wires. + + The first one is ``x_wires`` which is used + to encode the integer :math:`x < mod` in the computational basis. Therefore, ``x_wires`` must contain at least + :math:`\lceil \log_2(x)\rceil` wires to represent :math:`x`. + + The second one is ``output_wires`` which is used + to encode the integer :math:`b \cdot base^x \; \text{mod} \; mod` in the computational basis. Therefore, at least + :math:`\lceil \log_2(mod)\rceil` ``output_wires`` are required to represent :math:`b \cdot base^x \; \text{mod} \; mod`. Note that these wires can be initialized with any integer + :math:`b`, but the most common choice is :math:`b=1` to obtain as a final result :math:`base^x \; \text{mod} \; mod`. + + The third set of wires is ``work_wires`` which consist of the auxiliary qubits used to perform the modular exponentiation operation. + + - If :math:`mod = 2^{\text{len(output_wires)}}`, the length of ``work_wires`` must be equal to the length of ``output_wires``. + + - If :math:`mod \neq 2^{\text{len(output_wires)}}`, the length of ``work_wires`` must be ``len(output_wires) + 2`` + + Note that the ``ModExp`` template allows us to perform modular exponentiation in the computational basis. However if one just wants to perform standard exponentiation (with no modulo), + that would be equivalent to setting the modulo :math:`mod` to a large enough value to ensure that :math:`base^x < mod`. + + Also, to perform the out-place modular exponentiation operator it is required that :math:`base` has inverse, :math:`base^{-1} \; \text{mod} \; mod`. That means + :math:`base \cdot base^{-1}` modulo :math:`mod` is equal to 1, which will only be possible if :math:`base` and + :math:`mod` are coprime. In other words, :math:`base` and :math:`mod` should not have any common factors other than 1. """ grad_method = None @@ -84,11 +117,14 @@ def __init__( output_wires = qml.wires.Wires(output_wires) + if work_wires is None: + raise ValueError("Work wires must be specified for ModExp") + if mod is None: mod = 2 ** (len(output_wires)) if len(output_wires) == 0 or (mod > 2 ** (len(output_wires))): raise ValueError("ModExp must have enough wires to represent mod.") - if mod != 2 ** len(x_wires): + if mod != 2 ** len(output_wires): if len(work_wires) < (len(output_wires) + 2): raise ValueError("ModExp needs as many work_wires as output_wires plus two.") else: @@ -103,6 +139,10 @@ def __init__( ) if any(wire in x_wires for wire in output_wires): raise ValueError("None of the wires in x_wires should be included in output_wires.") + + if np.gcd(base, mod) != 1: + raise ValueError("The operator cannot be built because base has no inverse modulo mod.") + wire_keys = ["x_wires", "output_wires", "work_wires"] for key in wire_keys: self.hyperparameters[key] = qml.wires.Wires(locals()[key]) @@ -161,13 +201,15 @@ def compute_decomposition( x_wires, output_wires, base, mod, work_wires ): # pylint: disable=arguments-differ r"""Representation of the operator as a product of other operators. + Args: x_wires (Sequence[int]): the wires that store the integer :math:`x` - output_wires (Sequence[int]): the wires that store the exponentiation result + output_wires (Sequence[int]): the wires that store the operator result. These wires also encode :math:`b`. base (int): integer that needs to be exponentiated - mod (int): the modulus for performing the exponentiation, default value is :math:`2^{len(output\_wires)}` - work_wires (Sequence[int]): the auxiliary wires to be used for the exponentiation. There must be as many as ``output_wires`` and if :math:`mod \neq 2^{len(x\_wires)}`, two more wires must be added. - + mod (int): the modulo for performing the exponentiation. If not provided, it will be set to its maximum value, :math:`2^{\text{len(output_wires)}}` + work_wires (Sequence[int]): the auxiliary wires to use for the exponentiation. If + :math:`mod=2^{\text{len(output_wires)}}`, the number of auxiliary wires must be ``len(output_wires)``. Otherwise + ``len(output_wires) + 2`` auxiliary wires are needed. Returns: list[.Operator]: Decomposition of the operator diff --git a/pennylane/templates/subroutines/multiplier.py b/pennylane/templates/subroutines/multiplier.py index dbc3ff96325..70a929c018b 100644 --- a/pennylane/templates/subroutines/multiplier.py +++ b/pennylane/templates/subroutines/multiplier.py @@ -41,24 +41,25 @@ class Multiplier(Operation): .. math:: - \text{Multiplier}(k,mod) |x \rangle = | x \cdot k \; \text{modulo} \; \text{mod} \rangle. + \text{Multiplier}(k,mod) |x \rangle = | x \cdot k \; \text{mod} \; mod \rangle. The implementation is based on the quantum Fourier transform method presented in `arXiv:2311.08555 `_. .. note:: - Note that :math:`x` must be smaller than :math:`mod` to get the correct result. Also, it - is required that :math:`k` has inverse, :math:`k^-1`, modulo :math:`mod`. That means - :math:`k*k^-1 modulo mod is equal to 1`, which will only be possible if :math:`k` and - :math:`mod` are coprime. Furthermore, if :math:`mod \neq 2^{len(x\_wires)}`, two more - auxiliaries must be added. + To obtain the correct result, :math:`x` must be smaller than :math:`mod`. Also, it + is required that :math:`k` has modular inverse :math:`k^{-1}` with respect to :math:`mod`. That means + :math:`k \cdot k^{-1}` modulo :math:`mod` is equal to 1, which will only be possible if :math:`k` and + :math:`mod` are coprime. + + .. seealso:: :class:`~.PhaseAdder` and :class:`~.OutMultiplier`. Args: k (int): the number that needs to be multiplied - x_wires (Sequence[int]): the wires the operation acts on - mod (int): the modulus for performing the multiplication, default value is :math:`2^{len(x\_wires)}` - work_wires (Sequence[int]): the auxiliary wires to be used for performing the multiplication + x_wires (Sequence[int]): the wires the operation acts on. The number of wires must be enough for encoding `x` in the computational basis. The number of wires also limits the maximum value for `mod`. + mod (int): the modulo for performing the multiplication. If not provided, it will be set to its maximum value, :math:`2^{\text{len(x_wires)}}`. + work_wires (Sequence[int]): the auxiliary wires to use for the multiplication. If :math:`mod=2^{\text{len(x_wires)}}`, the number of auxiliary wires must be ``len(x_wires)``. Otherwise ``len(x_wires) + 2`` auxiliary wires are needed. **Example** @@ -70,23 +71,47 @@ class Multiplier(Operation): k = 4 mod = 7 - x_wires =[0,1,2] - work_wires=[3,4,5,6,7] + x_wires = [0,1,2] + work_wires = [3,4,5,6,7] dev = qml.device("default.qubit", shots=1) @qml.qnode(dev) - def circuit(x, k, mod, wires_m, work_wires): - qml.BasisEmbedding(x, wires=wires_m) + def circuit(): + qml.BasisEmbedding(x, wires=x_wires) qml.Multiplier(k, x_wires, mod, work_wires) - return qml.sample(wires=wires_m) + return qml.sample(wires=x_wires) .. code-block:: pycon - >>> print(circuit(x, k, mod, x_wires, work_wires)) + >>> print(circuit()) [1 0 1] - The result :math:`[1 0 1]`, is the ket representation of - :math:`3 \cdot 4 \, \text{modulo} \, 12 = 5`. + The result :math:`[1 0 1]`, is the binary representation of + :math:`3 \cdot 4 \; \text{modulo} \; 7 = 5`. + + .. details:: + :title: Usage Details + + This template takes as input two different sets of wires. + + The first one is ``x_wires``, used to encode the integer :math:`x < \text{mod}` in the Fourier basis. + To represent :math:`x`, ``x_wires`` must include at least :math:`\lceil \log_2(x) \rceil` wires. + After the modular addition, the result can be as large as :math:`\text{mod} - 1`, + requiring at least :math:`\lceil \log_2(\text{mod}) \rceil` wires. Since :math:`x < \text{mod}`, + :math:`\lceil \log_2(\text{mod}) \rceil` is a sufficient length for ``x_wires`` to cover all possible inputs and outputs. + + The second set of wires is ``work_wires`` which consist of the auxiliary qubits used to perform the modular multiplication operation. + + - If :math:`mod = 2^{\text{len(x_wires)}}`, the length of ``work_wires`` must be equal to the length of ``x_wires``. + + - If :math:`mod \neq 2^{\text{len(x_wires)}}`, the length of ``work_wires`` must be ``len(x_wires) + 2``. + + Note that the ``Multiplier`` template allows us to perform modular multiplication in the computational basis. However if one just want to perform standard multiplication (with no modulo), + that would be equivalent to setting the modulo :math:`mod` to a large enough value to ensure that :math:`x \cdot k < mod`. + + Also, to perform the in-place multiplication operator it is required that :math:`k` has inverse, :math:`k^{-1} \; \text{mod} \; mod`. That means + :math:`k \cdot k^{-1}` modulo :math:`mod` is equal to 1, which will only be possible if :math:`k` and + :math:`mod` are coprime. In other words, :math:`k` and :math:`mod` should not have any common factors other than 1. """ grad_method = None @@ -94,17 +119,26 @@ def circuit(x, k, mod, wires_m, work_wires): def __init__( self, k, x_wires, mod=None, work_wires=None, id=None ): # pylint: disable=too-many-arguments + if work_wires is None: + raise ValueError("Work wires must be specified for Multiplier") + + x_wires = qml.wires.Wires(x_wires) + work_wires = qml.wires.Wires(work_wires) + if any(wire in work_wires for wire in x_wires): raise ValueError("None of the wire in work_wires should be included in x_wires.") if mod is None: mod = 2 ** len(x_wires) - if mod != 2 ** len(x_wires) and len(work_wires) < (len(x_wires) + 2): + if mod != 2 ** len(x_wires) and len(work_wires) != (len(x_wires) + 2): raise ValueError("Multiplier needs as many work_wires as x_wires plus two.") if len(work_wires) < len(x_wires): raise ValueError("Multiplier needs as many work_wires as x_wires.") - if (not hasattr(x_wires, "__len__")) or (mod > 2 ** len(x_wires)): - raise ValueError("Multiplier must have enough wires to represent mod.") + if mod > 2 ** len(x_wires): + raise ValueError( + "Multiplier must have enough wires to represent mod. The maximum mod " + f"with len(x_wires)={len(x_wires)} is {2 ** len(x_wires)}, but received {mod}." + ) k = k % mod if np.gcd(k, mod) != 1: @@ -158,11 +192,12 @@ def _primitive_bind_call(cls, *args, **kwargs): @staticmethod def compute_decomposition(k, x_wires, mod, work_wires): # pylint: disable=arguments-differ r"""Representation of the operator as a product of other operators. + Args: k (int): the number that needs to be multiplied - x_wires (Sequence[int]): the wires the operation acts on - mod (int): the modulus for performing the multiplication, default value is :math:`2^{len(x\_wires)}` - work_wires (Sequence[int]): the auxiliary wires to be used for performing the multiplication + x_wires (Sequence[int]): the wires the operation acts on. The number of wires must be enough for encoding `x` in the computational basis. The number of wires also limits the maximum value for `mod`. + mod (int): the modulo for performing the multiplication. If not provided, it will be set to its maximum value, :math:`2^{\text{len(x_wires)}}`. + work_wires (Sequence[int]): the auxiliary wires to use for the multiplication. If :math:`mod=2^{\text{len(x_wires)}}`, the number of auxiliary wires must be ``len(x_wires)``. Otherwise ``len(x_wires) + 2`` auxiliary wires are needed. Returns: list[.Operator]: Decomposition of the operator diff --git a/pennylane/templates/subroutines/out_adder.py b/pennylane/templates/subroutines/out_adder.py index 2f8a398e1a6..40006e402fc 100644 --- a/pennylane/templates/subroutines/out_adder.py +++ b/pennylane/templates/subroutines/out_adder.py @@ -27,25 +27,28 @@ class OutAdder(Operation): .. math:: - \text{OutAdder}(mod) |x \rangle | y \rangle | b \rangle = |x \rangle | y \rangle | b+x+y \, \text{mod} \, mod \rangle, + \text{OutAdder}(mod) |x \rangle | y \rangle | b \rangle = |x \rangle | y \rangle | b+x+y \; \text{mod} \; mod \rangle, The implementation is based on the quantum Fourier transform method presented in `arXiv:2311.08555 `_. .. note:: - Note that :math:`x` and :math:`y` must be smaller than :math:`mod` to get the correct result. + To obtain the correct result, :math:`x`, :math:`y` and :math:`b` must be smaller than :math:`mod`. + + .. seealso:: :class:`~.PhaseAdder` and :class:`~.Adder`. Args: x_wires (Sequence[int]): the wires that store the integer :math:`x` y_wires (Sequence[int]): the wires that store the integer :math:`y` - output_wires (Sequence[int]): the wires that store the addition result - mod (int): the modulus for performing the addition, default value is :math:`2^{\text{len(output\_wires)}}` - work_wires (Sequence[int]): the auxiliary wires to use for the addition + output_wires (Sequence[int]): the wires that store the addition result. If the register is in a non-zero state :math:`b`, the solution will be added to this value. + mod (int): the modulo for performing the addition. If not provided, it will be set to its maximum value, :math:`2^{\text{len(output_wires)}}`. + work_wires (Sequence[int]): the auxiliary wires to use for the addition. The work wires are not needed if :math:`mod=2^{\text{len(output_wires)}}`, otherwise two work wires should be provided. Defaults to ``None``. **Example** This example computes the sum of two integers :math:`x=5` and :math:`y=6` modulo :math:`mod=7`. + We'll let :math:`b=0`. See Usage Details for :math:`b \neq 0`. .. code-block:: @@ -71,8 +74,65 @@ def circuit(): >>> print(circuit()) [1 0 0] - The result :math:`[1 0 0]`, is the ket representation of - :math:`5 + 6 \, \text{modulo} \, 7 = 4`. + The result :math:`[1 0 0]`, is the binary representation of + :math:`5 + 6 \; \text{modulo} \; 7 = 4`. + + .. details:: + :title: Usage Details + + This template takes as input four different sets of wires. + + The first one is ``x_wires`` which is used + to encode the integer :math:`x < mod` in the computational basis. Therefore, ``x_wires`` must contain + at least :math:`\lceil \log_2(x)\rceil` to represent :math:`x`. + + The second one is ``y_wires`` which is used + to encode the integer :math:`y < mod` in the computational basis. Therefore, ``y_wires`` must contain + at least :math:`\lceil \log_2(y)\rceil` wires to represent :math:`y`. + + The third one is ``output_wires`` which is used + to encode the integer :math:`b+x+y \; \text{mod} \; mod` in the computational basis. Therefore, it will require at least + :math:`\lceil \log_2(mod)\rceil` ``output_wires`` to represent :math:`b+x+y \; \text{mod} \; mod`. Note that these wires can be initialized with any integer + :math:`b < mod`, but the most common choice is :math:`b=0` to obtain as a final result :math:`x + y \; \text{mod} \; mod`. + The following is an example for :math:`b = 1`. + + .. code-block:: + + b=1 + x=5 + y=6 + mod=7 + + x_wires=[0,1,2] + y_wires=[3,4,5] + output_wires=[7,8,9] + work_wires=[6,10] + + dev = qml.device("default.qubit", shots=1) + @qml.qnode(dev) + def circuit(): + qml.BasisEmbedding(x, wires=x_wires) + qml.BasisEmbedding(y, wires=y_wires) + qml.BasisEmbedding(b, wires=output_wires) + qml.OutAdder(x_wires, y_wires, output_wires, mod, work_wires) + return qml.sample(wires=output_wires) + + .. code-block:: pycon + + >>> print(circuit()) + [1 0 1] + + The result :math:`[1 0 1]`, is the binary representation of + :math:`5 + 6 + 1\; \text{modulo} \; 7 = 5`. + + The fourth set of wires is ``work_wires`` which consist of the auxiliary qubits used to perform the modular addition operation. + + - If :math:`mod = 2^{\text{len(output_wires)}}`, there will be no need for ``work_wires``, hence ``work_wires=None``. This is the case by default. + + - If :math:`mod \neq 2^{\text{len(output_wires)}}`, two ``work_wires`` have to be provided. + + Note that the ``OutAdder`` template allows us to perform modular addition in the computational basis. However if one just wants to perform standard addition (with no modulo), + that would be equivalent to setting the modulo :math:`mod` to a large enough value to ensure that :math:`x+k < mod`. """ grad_method = None @@ -81,10 +141,23 @@ def __init__( self, x_wires, y_wires, output_wires, mod=None, work_wires=None, id=None ): # pylint: disable=too-many-arguments + x_wires = qml.wires.Wires(x_wires) + y_wires = qml.wires.Wires(y_wires) + output_wires = qml.wires.Wires(output_wires) + + num_work_wires = 0 if work_wires is None else len(work_wires) + if mod is None: mod = 2 ** (len(output_wires)) - if (not hasattr(output_wires, "__len__")) or (mod > 2 ** len(output_wires)): - raise ValueError("OutAdder must have enough wires to represent mod.") + if mod > 2 ** len(output_wires): + raise ValueError( + "OutAdder must have enough wires to represent mod. The maximum mod " + f"with len(output_wires)={len(output_wires)} is {2 ** len(output_wires)}, but received {mod}." + ) + if mod != 2 ** len(output_wires) and num_work_wires != 2: + raise ValueError( + f"If mod is not 2^{len(output_wires)}, two work wires should be provided." + ) if work_wires is not None: if any(wire in work_wires for wire in x_wires): raise ValueError("None of the wires in work_wires should be included in x_wires.") @@ -150,12 +223,13 @@ def compute_decomposition( x_wires, y_wires, output_wires, mod, work_wires ): # pylint: disable=arguments-differ r"""Representation of the operator as a product of other operators. + Args: x_wires (Sequence[int]): the wires that store the integer :math:`x` y_wires (Sequence[int]): the wires that store the integer :math:`y` - output_wires (Sequence[int]): the wires that store the addition result - mod (int): the modulus for performing the addition, default value is :math:`2^{\text{len(output\_wires)}}` - work_wires (Sequence[int]): the auxiliary wires to use for the addition + output_wires (Sequence[int]): the wires that store the addition result. If the register is in a non-zero state :math:`b`, the solution will be added to this value. + mod (int): the modulo for performing the addition. If not provided, it will be set to its maximum value, :math:`2^{\text{len(output_wires)}}`. + work_wires (Sequence[int]): the auxiliary wires to use for the addition. The work wires are not needed if :math:`mod=2^{\text{len(output_wires)}}`, otherwise two work wires should be provided. Defaults to ``None``. Returns: list[.Operator]: Decomposition of the operator diff --git a/pennylane/templates/subroutines/out_multiplier.py b/pennylane/templates/subroutines/out_multiplier.py index 3fd9a8a2043..d551fd8299e 100644 --- a/pennylane/templates/subroutines/out_multiplier.py +++ b/pennylane/templates/subroutines/out_multiplier.py @@ -26,25 +26,30 @@ class OutMultiplier(Operation): :math:`mod` in the computational basis: .. math:: - \text{OutMultiplier}(mod) |x \rangle |y \rangle |b \rangle = |x \rangle |y \rangle |b + x \cdot y \; \text{modulo} \; mod \rangle, + \text{OutMultiplier}(mod) |x \rangle |y \rangle |b \rangle = |x \rangle |y \rangle |b + x \cdot y \; \text{mod} \; mod \rangle, The implementation is based on the quantum Fourier transform method presented in `arXiv:2311.08555 `_. .. note:: - Note that :math:`x` and :math:`y` must be smaller than :math:`mod` to get the correct result. + To obtain the correct result, :math:`x`, :math:`y` and :math:`b` must be smaller than :math:`mod`. + + .. seealso:: :class:`~.PhaseAdder` and :class:`~.Multiplier`. Args: x_wires (Sequence[int]): the wires that store the integer :math:`x` y_wires (Sequence[int]): the wires that store the integer :math:`y` - output_wires (Sequence[int]): the wires that store the multiplication result - mod (int): the modulus for performing the multiplication, default value is :math:`2^{len(output\_wires)}` - work_wires (Sequence[int]): the auxiliary wires to use for the multiplication modulo + output_wires (Sequence[int]): the wires that store the multiplication result. If the register is in a non-zero state :math:`b`, the solution will be added to this value + mod (int): the modulo for performing the multiplication. If not provided, it will be set to its maximum value, :math:`2^{\text{len(output_wires)}}` + work_wires (Sequence[int]): the auxiliary wires to use for the multiplication. The + work wires are not needed if :math:`mod=2^{\text{len(output_wires)}}`, otherwise two work wires + should be provided. Defaults to ``None``. **Example** This example performs the multiplication of two integers :math:`x=2` and :math:`y=7` modulo :math:`mod=12`. + We'll let :math:`b=0`. See Usage Details for :math:`b \neq 0`. .. code-block:: @@ -70,8 +75,65 @@ def circuit(): >>> print(circuit()) [0 0 1 0] - The result :math:`[0 0 1 0]`, is the ket representation of - :math:`2 \cdot 7 \, \text{modulo} \, 12 = 2`. + The result :math:`[0 0 1 0]`, is the binary representation of + :math:`2 \cdot 7 \; \text{modulo} \; 12 = 2`. + + .. details:: + :title: Usage Details + + This template takes as input four different sets of wires. + + The first one is ``x_wires`` which is used + to encode the integer :math:`x < mod` in the computational basis. Therefore, ``x_wires`` must contain + at least :math:`\lceil \log_2(x)\rceil` wires to represent :math:`x`. + + The second one is ``y_wires`` which is used + to encode the integer :math:`y < mod` in the computational basis. Therefore, ``y_wires`` must contain + at least :math:`\lceil \log_2(y)\rceil` wires to represent :math:`y`. + + The third one is ``output_wires`` which is used + to encode the integer :math:`b+ x \cdot y \; \text{mod} \; mod` in the computational basis. Therefore, it will require at least + :math:`\lceil \log_2(mod)\rceil` ``output_wires`` to represent :math:`b + x \cdot y \; \text{mod} \; mod`. Note that these wires can be initialized with any integer + :math:`b < mod`, but the most common choice is :math:`b=0` to obtain as a final result :math:`x \cdot y \; \text{mod} \; mod`. + The following is an example for :math:`b = 1`. + + .. code-block:: + + b = 1 + x = 2 + y = 7 + mod = 12 + + x_wires = [0, 1] + y_wires = [2, 3, 4] + output_wires = [6, 7, 8, 9] + work_wires = [5, 10] + + dev = qml.device("default.qubit", shots=1) + @qml.qnode(dev) + def circuit(): + qml.BasisEmbedding(x, wires=x_wires) + qml.BasisEmbedding(y, wires=y_wires) + qml.BasisEmbedding(b, wires=output_wires) + qml.OutMultiplier(x_wires, y_wires, output_wires, mod, work_wires) + return qml.sample(wires=output_wires) + + .. code-block:: pycon + + >>> print(circuit()) + [0 0 1 1] + + The result :math:`[0 0 1 1]`, is the binary representation of + :math:`2 \cdot 7 + 1\; \text{modulo} \; 12 = 3`. + + The fourth set of wires is ``work_wires`` which consist of the auxiliary qubits used to perform the modular multiplication operation. + + - If :math:`mod = 2^{\text{len(output_wires)}}`, there will be no need for ``work_wires``, hence ``work_wires=None``. This is the case by default. + + - If :math:`mod \neq 2^{\text{len(output_wires)}}`, two ``work_wires`` have to be provided. + + Note that the ``OutMultiplier`` template allows us to perform modular multiplication in the computational basis. However if one just wants to perform + standard multiplication (with no modulo), that would be equivalent to setting the modulo :math:`mod` to a large enough value to ensure that :math:`x \cdot k < mod`. """ grad_method = None @@ -80,14 +142,23 @@ def __init__( self, x_wires, y_wires, output_wires, mod=None, work_wires=None, id=None ): # pylint: disable=too-many-arguments + x_wires = qml.wires.Wires(x_wires) + y_wires = qml.wires.Wires(y_wires) + output_wires = qml.wires.Wires(output_wires) + + num_work_wires = 0 if work_wires is None else len(work_wires) + if mod is None: mod = 2 ** len(output_wires) - if mod != 2 ** len(output_wires) and work_wires is None: + if mod != 2 ** len(output_wires) and num_work_wires != 2: raise ValueError( f"If mod is not 2^{len(output_wires)}, two work wires should be provided." ) - if (not hasattr(output_wires, "__len__")) or (mod > 2 ** (len(output_wires))): - raise ValueError("OutMultiplier must have enough wires to represent mod.") + if mod > 2 ** (len(output_wires)): + raise ValueError( + "OutMultiplier must have enough wires to represent mod. The maximum mod " + f"with len(output_wires)={len(output_wires)} is {2 ** len(output_wires)}, but received {mod}." + ) if work_wires is not None: if any(wire in work_wires for wire in x_wires): @@ -159,12 +230,16 @@ def compute_decomposition( x_wires, y_wires, output_wires, mod, work_wires ): # pylint: disable=arguments-differ r"""Representation of the operator as a product of other operators. + Args: x_wires (Sequence[int]): the wires that store the integer :math:`x` y_wires (Sequence[int]): the wires that store the integer :math:`y` - output_wires (Sequence[int]): the wires that store the multiplication result - mod (int): the modulus for performing the multiplication, default value is :math:`2^{len(output\_wires)}` - work_wires (Sequence[int]): the auxiliary wires to use for the multiplication + output_wires (Sequence[int]): the wires that store the multiplication result. If the register is in a non-zero state :math:`b`, the solution will be added to this value + mod (int): the modulo for performing the multiplication. If not provided, it will be set to its maximum value, :math:`2^{\text{len(output_wires)}}` + work_wires (Sequence[int]): the auxiliary wires to use for the multiplication. The + work wires are not needed if :math:`mod=2^{\text{len(output_wires)}}`, otherwise two work wires + should be provided. Defaults to ``None``. + Returns: list[.Operator]: Decomposition of the operator diff --git a/pennylane/templates/subroutines/phase_adder.py b/pennylane/templates/subroutines/phase_adder.py index e76a9ff8c1e..548857eb9a8 100644 --- a/pennylane/templates/subroutines/phase_adder.py +++ b/pennylane/templates/subroutines/phase_adder.py @@ -37,28 +37,34 @@ class PhaseAdder(Operation): .. math:: - \text{PhaseAdder}(k,mod) |\phi (x) \rangle = |\phi (x+k \; \text{modulo} \; mod) \rangle, + \text{PhaseAdder}(k,mod) |\phi (x) \rangle = |\phi (x+k \; \text{mod} \; mod) \rangle, - where :math:`|\phi (x) \rangle` represents the :math:`| x \rangle` : state in the Fourier basis, + where :math:`|\phi (x) \rangle` represents the :math:`| x \rangle` state in the Fourier basis, - .. math:: + .. math:: - \text{QFT} |x \rangle = |\phi (x) \rangle. + \text{QFT} |x \rangle = |\phi (x) \rangle. The implementation is based on the quantum Fourier transform method presented in `arXiv:2311.08555 `_. .. note:: - Note that :math:`x` must be smaller than :math:`mod` to get the correct result. Also, when - :math:`mod \neq 2^{\text{len(x\_wires)}}` we need :math:`x < 2^{\text{len(x\_wires)}}/2`, - which means that we need one extra wire in ``x_wires``. + To obtain the correct result, :math:`x` must be smaller than :math:`mod`. Also, when + :math:`mod \neq 2^{\text{len(x_wires)}}`, :math:`x` must satisfy :math:`x < 2^{\text{len(x_wires)}-1}`, + which means that one extra wire in ``x_wires`` is required. + + .. seealso:: :class:`~.QFT` and :class:`~.Adder`. Args: k (int): the number that needs to be added - x_wires (Sequence[int]): the wires the operation acts on - mod (int): the modulus for performing the addition, default value is :math:`2^{len(x\_wires)}` - work_wire (Sequence[int]): the auxiliary wire to be used for performing the addition + x_wires (Sequence[int]): the wires the operation acts on. The number of wires must be enough + for a binary representation of the value being targeted, :math:`x`. In some cases an additional + wire is needed, see usage details below. The number of wires also limits the maximum + value for `mod`. + mod (int): the modulo for performing the addition. If not provided, it will be set to its maximum value, :math:`2^{\text{len(x_wires)}}`. + work_wire (Sequence[int] or int): the auxiliary wire to use for the addition. Optional + when `mod` is :math:`2^{len(x\_wires)}`. Defaults to ``None``. **Example** @@ -75,7 +81,7 @@ class PhaseAdder(Operation): dev = qml.device("default.qubit", shots=1) @qml.qnode(dev) - def circuit(x, k, mod, x_wires, work_wire): + def circuit(): qml.BasisEmbedding(x, wires=x_wires) qml.QFT(wires=x_wires) qml.PhaseAdder(k, x_wires, mod, work_wire) @@ -84,11 +90,34 @@ def circuit(x, k, mod, x_wires, work_wire): .. code-block:: pycon - >>> print(circuit(x, k, mod, x_wires, work_wire)) + >>> print(circuit()) [1 1 0 1] - The result, :math:`[1 1 0 1]`, is the ket representation of - :math:`8 + 5 \, \text{modulo} \, 15 = 13`. + The result, :math:`[1 1 0 1]`, is the binary representation of + :math:`8 + 5 \; \text{modulo} \; 15 = 13`. + + .. details:: + :title: Usage Details + + This template takes as input two different sets of wires. + + The first one is ``x_wires``, used to encode the integer :math:`x < \text{mod}` in the Fourier basis. + To represent :math:`x`, at least :math:`\lceil \log_2(x) \rceil` wires are needed. + After the modular addition, the result can be as large as :math:`\text{mod} - 1`, + requiring at least :math:`\lceil \log_2(\text{mod}) \rceil` wires. Since :math:`x < \text{mod}`, a length of + :math:`\lceil \log_2(\text{mod}) \rceil` is sufficient for ``x_wires`` to cover all possible inputs and + outputs when :math:`mod = 2^{\text{len(x_wires)}}`. + An exception occurs when :math:`mod \neq 2^{\text{len(x_wires)}}`. In that case one extra wire in ``x_wires`` will be needed to correctly perform the phase + addition operation. + + The second set of wires is ``work_wire`` which consist of the auxiliary qubit used to perform the modular phase addition operation. + + - If :math:`mod = 2^{\text{len(x_wires)}}`, there will be no need for ``work_wire``, hence ``work_wire=None``. This is the case by default. + + - If :math:`mod \neq 2^{\text{len(x_wires)}}`, one ``work_wire`` has to be provided. + + Note that the ``PhaseAdder`` template allows us to perform modular addition in the Fourier basis. However if one just wants to perform standard addition (with no modulo), + that would be equivalent to setting the modulo :math:`mod` to a large enough value to ensure that :math:`x+k < mod`. """ grad_method = None @@ -97,15 +126,22 @@ def __init__( self, k, x_wires, mod=None, work_wire=None, id=None ): # pylint: disable=too-many-arguments + work_wire = qml.wires.Wires(work_wire) if work_wire is not None else work_wire x_wires = qml.wires.Wires(x_wires) + + num_work_wires = 0 if work_wire is None else len(work_wire) + if mod is None: mod = 2 ** len(x_wires) - elif work_wire is None and mod != 2 ** len(x_wires): + elif mod != 2 ** len(x_wires) and num_work_wires != 1: raise ValueError(f"If mod is not 2^{len(x_wires)}, one work wire should be provided.") if not isinstance(k, int) or not isinstance(mod, int): raise ValueError("Both k and mod must be integers") if mod > 2 ** len(x_wires): - raise ValueError("PhaseAdder must have enough x_wires to represent mod.") + raise ValueError( + "PhaseAdder must have enough x_wires to represent mod. The maximum mod " + f"with len(x_wires)={len(x_wires)} is {2 ** len(x_wires)}, but received {mod}." + ) if work_wire is not None: if any(wire in work_wire for wire in x_wires): raise ValueError("None of the wires in work_wire should be included in x_wires.") @@ -153,11 +189,16 @@ def _primitive_bind_call(cls, *args, **kwargs): @staticmethod def compute_decomposition(k, x_wires, mod, work_wire): # pylint: disable=arguments-differ r"""Representation of the operator as a product of other operators. + Args: k (int): the number that needs to be added - x_wires (Sequence[int]): the wires the operation acts on - mod (int): the modulus for performing the addition, default value is :math:`2^{len(x_wires)}` - work_wire (Sequence[int]): the auxiliary wire to be used for performing the addition + x_wires (Sequence[int]): the wires the operation acts on. The number of wires must be enough + for a binary representation of the value being targeted, :math:`x`. In some cases an additional + wire is needed, see usage details below. The number of wires also limits the maximum + value for `mod`. + mod (int): the modulo for performing the addition. If not provided, it will be set to its maximum value, :math:`2^{\text{len(x_wires)}}`. + work_wire (Sequence[int]): the auxiliary wire to use for the addition. Optional + when `mod` is :math:`2^{len(x\_wires)}`. Defaults to ``None``. Returns: list[.Operator]: Decomposition of the operator diff --git a/tests/capture/test_templates.py b/tests/capture/test_templates.py index d9c4b0d96ee..d04990b2971 100644 --- a/tests/capture/test_templates.py +++ b/tests/capture/test_templates.py @@ -876,7 +876,7 @@ def test_mod_exp(self): kwargs = { "x_wires": [0, 1], "output_wires": [4, 5], - "base": 2, + "base": 3, "mod": None, "work_wires": [2, 3], } diff --git a/tests/devices/default_qubit/test_default_qubit.py b/tests/devices/default_qubit/test_default_qubit.py index 74d9628d1e7..8b3a1e257dd 100644 --- a/tests/devices/default_qubit/test_default_qubit.py +++ b/tests/devices/default_qubit/test_default_qubit.py @@ -2197,3 +2197,49 @@ def test_broadcasted_parameter(max_workers): results = dev.execute(batch, config) processed_results = pre_processing_fn(results) assert qml.math.allclose(processed_results, np.cos(x)) + + +@pytest.mark.jax +def test_renomalization_issue(): + """Test that no normalization error occurs with the following workflow in float32 mode. + Just tests executes without error. Not producing a more minimal example due to difficulty + finding an exact case that leads to renomalization issues. + """ + import jax + from jax import numpy as jnp + + initial_mode = jax.config.jax_enable_x64 + jax.config.update("jax_enable_x64", False) + + def gaussian_fn(p, t): + return p[0] * jnp.exp(-((t - p[1]) ** 2) / (2 * p[2] ** 2)) + + global_drive = qml.pulse.rydberg_drive( + amplitude=gaussian_fn, phase=0, detuning=0, wires=[0, 1, 2] + ) + + a = 5 + + coordinates = [(0, 0), (a, 0), (a / 2, np.sqrt(a**2 - (a / 2) ** 2))] + + settings = {"interaction_coeff": 862619.7915580727} + + H_interaction = qml.pulse.rydberg_interaction(coordinates, **settings) + + max_amplitude = 2.0 + displacement = 1.0 + sigma = 0.3 + + amplitude_params = [max_amplitude, displacement, sigma] + + params = [amplitude_params] + ts = [0.0, 1.75] + + def circuit(params): + qml.evolve(H_interaction + global_drive)(params, ts) + return qml.counts() + + circuit_qml = qml.QNode(circuit, qml.device("default.qubit", shots=1000), interface="jax") + + circuit_qml(params) + jax.config.update("jax_enable_x64", initial_mode) diff --git a/tests/devices/qubit/test_sampling.py b/tests/devices/qubit/test_sampling.py index 26a86a12592..4174ed63aae 100644 --- a/tests/devices/qubit/test_sampling.py +++ b/tests/devices/qubit/test_sampling.py @@ -94,8 +94,6 @@ def test_prng_key_as_seed_uses_sample_state_jax(self, mocker): # prng_key specified, should call _sample_state_jax _ = sample_state(state, 10, prng_key=jax.random.PRNGKey(15)) - # prng_key defaults to None, should NOT call _sample_state_jax - _ = sample_state(state, 10, rng=15) spy.assert_called_once() @@ -723,7 +721,7 @@ def test_nan_shadow_expval(self, H, interface, shots): two_qubit_state_to_be_normalized = np.array([[0, 1.0000000005j], [-1, 0]]) / np.sqrt(2) -two_qubit_state_not_normalized = np.array([[0, 1.0000005j], [-1.00000001, 0]]) / np.sqrt(2) +two_qubit_state_not_normalized = np.array([[0, 1.00005j], [-1.00000001, 0]]) / np.sqrt(2) batched_state_to_be_normalized = np.stack( [ @@ -752,8 +750,9 @@ def test_sample_state_renorm(self, interface): state = qml.math.array(two_qubit_state_to_be_normalized, like=interface) _ = sample_state(state, 10) + # jax.random.choice accepts unnormalized probabilities @pytest.mark.all_interfaces - @pytest.mark.parametrize("interface", ["numpy", "jax", "torch", "tensorflow"]) + @pytest.mark.parametrize("interface", ["numpy", "torch", "tensorflow"]) def test_sample_state_renorm_error(self, interface): """Test that renormalization does not occur if the error is too large.""" @@ -762,15 +761,16 @@ def test_sample_state_renorm_error(self, interface): _ = sample_state(state, 10) @pytest.mark.all_interfaces - @pytest.mark.parametrize("interface", ["numpy", "jax", "torch", "tensorflow"]) + @pytest.mark.parametrize("interface", ["numpy", "torch", "jax", "tensorflow"]) def test_sample_batched_state_renorm(self, interface): """Test renormalization for a batched state.""" state = qml.math.array(batched_state_to_be_normalized, like=interface) _ = sample_state(state, 10, is_state_batched=True) + # jax.random.choices accepts unnormalized probabilities @pytest.mark.all_interfaces - @pytest.mark.parametrize("interface", ["numpy", "jax", "torch", "tensorflow"]) + @pytest.mark.parametrize("interface", ["numpy", "torch", "tensorflow"]) def test_sample_batched_state_renorm_error(self, interface): """Test that renormalization does not occur if the error is too large.""" diff --git a/tests/ops/functions/test_assert_valid.py b/tests/ops/functions/test_assert_valid.py index 9fff7758338..e426b91a405 100644 --- a/tests/ops/functions/test_assert_valid.py +++ b/tests/ops/functions/test_assert_valid.py @@ -188,7 +188,7 @@ def __init__(self, f, wires): def test_bad_pickling(): """Test an error is raised in an operator cant be pickled.""" - with pytest.raises(AttributeError, match="Can't pickle local object"): + with pytest.raises(AttributeError): assert_valid(BadPickling0(lambda x: x, wires=0)) diff --git a/tests/ops/op_math/test_prod.py b/tests/ops/op_math/test_prod.py index fabdfe61bdc..7963ce3fb6c 100644 --- a/tests/ops/op_math/test_prod.py +++ b/tests/ops/op_math/test_prod.py @@ -541,6 +541,7 @@ def test_prod_fails_with_non_callable_arg(self): prod(1) +# pylint: disable=too-many-public-methods class TestMatrix: """Test matrix-related methods.""" @@ -845,6 +846,15 @@ def test_sparse_matrix(self, op1, mat1, op2, mat2): assert np.allclose(true_mat, prod_mat) + def test_sparse_matrix_global_phase(self): + """Test that a prod with a global phase still defines a sparse matrix.""" + + op = qml.GlobalPhase(0.5) @ qml.X(0) @ qml.X(0) + + sparse_mat = op.sparse_matrix(wire_order=(0, 1)) + mat = sparse_mat.todense() + assert qml.math.allclose(mat, np.exp(-0.5j) * np.eye(4)) + @pytest.mark.parametrize("op1, mat1", non_param_ops[:5]) @pytest.mark.parametrize("op2, mat2", non_param_ops[:5]) def test_sparse_matrix_same_wires(self, op1, mat1, op2, mat2): diff --git a/tests/templates/test_subroutines/test_adder.py b/tests/templates/test_subroutines/test_adder.py index 0f5a0ef4f59..d4fd3f7a205 100644 --- a/tests/templates/test_subroutines/test_adder.py +++ b/tests/templates/test_subroutines/test_adder.py @@ -118,6 +118,7 @@ def circuit(x): if mod is None: mod = 2 ** len(x_wires) + # pylint: disable=bad-reversed-sequence result = sum(bit * (2**i) for i, bit in enumerate(reversed(circuit(x)))) assert np.allclose(result, (x + k) % mod) @@ -131,13 +132,6 @@ def circuit(x): [3, 4], ("Adder must have enough x_wires to represent mod."), ), - ( - 1, - [0, 1, 2], - 9, - None, - (r"If mod is not"), - ), ( 3, [0, 1, 2, 3, 4], @@ -155,6 +149,17 @@ def test_operation_and_test_wires_error( with pytest.raises(ValueError, match=msg_match): qml.Adder(k, x_wires, mod, work_wires) + @pytest.mark.parametrize("work_wires", [None, [3], [3, 4, 5]]) + def test_validation_of_num_work_wires(self, work_wires): + """Test that when mod is not 2**len(x_wires), validation confirms two + work wires are present, while any work wires are accepted for mod=2**len(x_wires)""" + + # if mod=2**len(x_wires), anything goes + qml.Adder(1, [0, 1, 2], mod=8, work_wires=work_wires) + + with pytest.raises(ValueError, match="two work wires should be provided"): + qml.Adder(1, [0, 1, 2], mod=9, work_wires=work_wires) + @pytest.mark.parametrize( ("k", "x_wires", "mod", "work_wires", "msg_match"), [ @@ -220,5 +225,6 @@ def circuit(): qml.Adder(k, x_wires, mod, work_wires) return qml.sample(wires=x_wires) + # pylint: disable=bad-reversed-sequence result = sum(bit * (2**i) for i, bit in enumerate(reversed(circuit()))) assert jax.numpy.allclose(result, (x + k) % mod) diff --git a/tests/templates/test_subroutines/test_mod_exp.py b/tests/templates/test_subroutines/test_mod_exp.py index 221250d5050..963fb155c60 100644 --- a/tests/templates/test_subroutines/test_mod_exp.py +++ b/tests/templates/test_subroutines/test_mod_exp.py @@ -71,6 +71,7 @@ def circuit(x, k): if mod is None: mod = 2 ** len(output_wires) + # pylint: disable=bad-reversed-sequence assert np.allclose( sum(bit * (2**i) for i, bit in enumerate(reversed(circuit(x, k)))), (k * (base**x)) % mod, @@ -79,6 +80,14 @@ def circuit(x, k): @pytest.mark.parametrize( ("x_wires", "output_wires", "base", "mod", "work_wires", "msg_match"), [ + ( + [0, 1, 2], + [3, 4, 5], + 8, + 5, + None, + "Work wires must be specified for ModExp", + ), ( [0, 1, 2], [3, 4, 5], @@ -136,6 +145,18 @@ def test_wires_error( with pytest.raises(ValueError, match=msg_match): qml.ModExp(x_wires, output_wires, base, mod, work_wires) + def test_check_base_and_mod_are_coprime(self): + """Test that an error is raised when base and mod are not coprime""" + + with pytest.raises(ValueError, match="base has no inverse modulo mod"): + qml.ModExp( + x_wires=[0, 1, 2], + output_wires=[3, 4, 5], + base=8, + mod=6, + work_wires=[6, 7, 8, 9, 10], + ) + def test_decomposition(self): """Test that compute_decomposition and decomposition work as expected.""" x_wires, output_wires, base, mod, work_wires = ( @@ -183,6 +204,7 @@ def circuit(): qml.ModExp(x_wires, output_wires, base, mod, work_wires) return qml.sample(wires=output_wires) + # pylint: disable=bad-reversed-sequence assert jax.numpy.allclose( sum(bit * (2**i) for i, bit in enumerate(reversed(circuit()))), (base**x) % mod ) diff --git a/tests/templates/test_subroutines/test_multiplier.py b/tests/templates/test_subroutines/test_multiplier.py index 4cb9cadee5f..175c3076af1 100644 --- a/tests/templates/test_subroutines/test_multiplier.py +++ b/tests/templates/test_subroutines/test_multiplier.py @@ -101,6 +101,7 @@ def circuit(x): if mod is None: mod = 2 ** len(x_wires) + # pylint: disable=bad-reversed-sequence assert np.allclose( sum(bit * (2**i) for i, bit in enumerate(reversed(circuit(x)))), (x * k) % mod ) @@ -108,6 +109,13 @@ def circuit(x): @pytest.mark.parametrize( ("k", "x_wires", "mod", "work_wires", "msg_match"), [ + ( + 3, + [0, 1, 2, 3, 4], + 11, + None, + "Work wires must be specified for Multiplier", + ), ( 6, [0, 1], @@ -133,7 +141,14 @@ def circuit(x): 3, [0, 1, 2, 3, 4], 11, - [5, 6, 7, 8, 9, 10], + [5, 6, 7, 8, 9, 10], # not enough + "Multiplier needs as many work_wires as x_wires plus two.", + ), + ( + 3, + [0, 1, 2, 3, 4], + 11, + [5, 6, 7, 8, 9, 10, 11, 12], # too many "Multiplier needs as many work_wires as x_wires plus two.", ), ( @@ -197,6 +212,7 @@ def circuit(): qml.Multiplier(k, x_wires, mod, work_wires) return qml.sample(wires=x_wires) + # pylint: disable=bad-reversed-sequence assert jax.numpy.allclose( sum(bit * (2**i) for i, bit in enumerate(reversed(circuit()))), (x * k) % mod ) diff --git a/tests/templates/test_subroutines/test_out_adder.py b/tests/templates/test_subroutines/test_out_adder.py index f54edc3857b..7a53701f4a0 100644 --- a/tests/templates/test_subroutines/test_out_adder.py +++ b/tests/templates/test_subroutines/test_out_adder.py @@ -80,6 +80,7 @@ def circuit(x, y, z): if mod is None: mod = 2 ** len(output_wires) + # pylint: disable=bad-reversed-sequence assert np.allclose( sum(bit * (2**i) for i, bit in enumerate(reversed(circuit(x, y, z)))), (x + y + z) % mod, @@ -145,6 +146,29 @@ def test_wires_error( with pytest.raises(ValueError, match=msg_match): qml.OutAdder(x_wires, y_wires, output_wires, mod, work_wires) + @pytest.mark.parametrize("work_wires", [None, [9], [9, 10, 11]]) + def test_validation_of_num_work_wires(self, work_wires): + """Test that when mod is not 2**len(output_wires), validation confirms two + work wires are present, while any work wires are accepted for mod=2**len(output_wires)""" + + # if mod=2**len(output_wires), anything goes + qml.OutAdder( + x_wires=[0, 1, 2], + y_wires=[3, 4, 5], + output_wires=[6, 7, 8], + mod=8, + work_wires=work_wires, + ) + + with pytest.raises(ValueError, match="two work wires should be provided"): + qml.OutAdder( + x_wires=[0, 1, 2], + y_wires=[3, 4, 5], + output_wires=[6, 7, 8], + mod=7, + work_wires=work_wires, + ) + def test_decomposition(self): """Test that compute_decomposition and decomposition work as expected.""" x_wires, y_wires, output_wires, mod, work_wires = ( @@ -205,6 +229,7 @@ def circuit(): qml.OutAdder(x_wires, y_wires, output_wires, mod, work_wires) return qml.sample(wires=output_wires) + # pylint: disable=bad-reversed-sequence assert jax.numpy.allclose( sum(bit * (2**i) for i, bit in enumerate(reversed(circuit()))), (x + y) % mod ) diff --git a/tests/templates/test_subroutines/test_out_multiplier.py b/tests/templates/test_subroutines/test_out_multiplier.py index 9541474b7f3..938b03bb541 100644 --- a/tests/templates/test_subroutines/test_out_multiplier.py +++ b/tests/templates/test_subroutines/test_out_multiplier.py @@ -111,6 +111,7 @@ def circuit(x, y): if mod is None: mod = 2 ** len(output_wires) + # pylint: disable=bad-reversed-sequence assert np.allclose( sum(bit * (2**i) for i, bit in enumerate(reversed(circuit(x, y)))), (x * y) % mod ) @@ -183,6 +184,29 @@ def test_wires_error( with pytest.raises(ValueError, match=msg_match): OutMultiplier(x_wires, y_wires, output_wires, mod, work_wires) + @pytest.mark.parametrize("work_wires", [None, [9], [9, 10, 11]]) + def test_validation_of_num_work_wires(self, work_wires): + """Test that when mod is not 2**len(output_wires), validation confirms two + work wires are present, while any work wires are accepted for mod=2**len(output_wires)""" + + # if mod=2**len(output_wires), anything goes + OutMultiplier( + x_wires=[0, 1, 2], + y_wires=[3, 4, 5], + output_wires=[6, 7, 8], + mod=8, + work_wires=work_wires, + ) + + with pytest.raises(ValueError, match="two work wires should be provided"): + OutMultiplier( + x_wires=[0, 1, 2], + y_wires=[3, 4, 5], + output_wires=[6, 7, 8], + mod=7, + work_wires=work_wires, + ) + def test_decomposition(self): """Test that compute_decomposition and decomposition work as expected.""" x_wires, y_wires, output_wires, mod, work_wires = ( @@ -242,6 +266,7 @@ def circuit(): OutMultiplier(x_wires, y_wires, output_wires, mod, work_wires) return qml.sample(wires=output_wires) + # pylint: disable=bad-reversed-sequence assert jax.numpy.allclose( sum(bit * (2**i) for i, bit in enumerate(reversed(circuit()))), (x * y) % mod ) diff --git a/tests/templates/test_subroutines/test_phase_adder.py b/tests/templates/test_subroutines/test_phase_adder.py index 509228fc7df..fe4703328ec 100644 --- a/tests/templates/test_subroutines/test_phase_adder.py +++ b/tests/templates/test_subroutines/test_phase_adder.py @@ -131,6 +131,7 @@ def circuit(x): if mod is None: mod = 2 ** len(x_wires) + # pylint: disable=bad-reversed-sequence assert np.allclose( sum(bit * (2**i) for i, bit in enumerate(reversed(circuit(x)))), (x + k) % mod ) @@ -168,6 +169,26 @@ def test_operation_and_wires_error( with pytest.raises(ValueError, match=msg_match): qml.PhaseAdder(k, x_wires, mod, work_wire) + @pytest.mark.parametrize("work_wire", [None, [], [3, 4]]) + def test_validation_of_num_work_wires(self, work_wire): + """Test that when mod is not 2**len(x_wires), validation confirms two + work wires are present, while any work wires are accepted for mod=2**len(x_wires)""" + + # if mod=2**len(x_wires), anything goes + qml.PhaseAdder(3, [0, 1, 2], mod=8, work_wire=work_wire) + + with pytest.raises(ValueError, match="one work wire should be provided"): + qml.PhaseAdder(3, [0, 1, 2], mod=7, work_wire=work_wire) + + def test_valid_inputs_for_work_wires(self): + """Test that both an integer and a list with a length of 1 are valid + inputs for work_wires, and have the same result""" + + op1 = qml.PhaseAdder(3, [0, 1, 2], mod=8, work_wire=[3]) + op2 = qml.PhaseAdder(3, [0, 1, 2], mod=8, work_wire=3) + + assert op1.hyperparameters["work_wire"] == op2.hyperparameters["work_wire"] + @pytest.mark.parametrize( ("k", "x_wires", "mod", "work_wire", "msg_match"), [ @@ -248,6 +269,7 @@ def circuit(): qml.adjoint(qml.QFT)(wires=x_wires) return qml.sample(wires=x_wires) + # pylint: disable=bad-reversed-sequence assert jax.numpy.allclose( sum(bit * (2**i) for i, bit in enumerate(reversed(circuit()))), (x + k) % mod )