Skip to content

Commit

Permalink
Merge branch 'master' into rc_2025-01-09-03-13-18
Browse files Browse the repository at this point in the history
  • Loading branch information
PietropaoloFrisoni authored Jan 10, 2025
2 parents 7e8a1eb + cc6849a commit 9926eaf
Show file tree
Hide file tree
Showing 18 changed files with 122 additions and 102 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ on:
- reopened
- synchronize
- ready_for_review
branches-ignore:
- 'v[0-9]+.[0-9]+.[0-9]+-docs'
# Scheduled trigger on Monday at 2:47am UTC
schedule:
- cron: "47 2 * * 1"
Expand Down
8 changes: 4 additions & 4 deletions doc/code/qml_fermi.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,15 @@ the orbital it acts on. The values of the dictionary are one of ``'+'`` or ``'-'
denote creation and annihilation operators, respectively. The operator
:math:`a^{\dagger}_0 a_3 a^{\dagger}_1` can then be constructed with

>>> qml.fermi.FermiWord({(0, 0): '+', (1, 3): '-', (2, 1): '+'})
>>> qml.FermiWord({(0, 0): '+', (1, 3): '-', (2, 1): '+'})
a⁺(0) a(3) a⁺(1)

A Fermi sentence can be constructed directly by passing a dictionary of Fermi words and their
corresponding coefficients to the :class:`~pennylane.fermi.FermiSentence` class. For instance, the
Fermi sentence :math:`1.2 a^{\dagger}_0 a_0 + 2.3 a^{\dagger}_3 a_3` can be constructed as

>>> fw1 = qml.fermi.FermiWord({(0, 0): '+', (1, 0): '-'})
>>> fw2 = qml.fermi.FermiWord({(0, 3): '+', (1, 3): '-'})
>>> qml.fermi.FermiSentence({fw1: 1.2, fw2: 2.3})
>>> fw1 = qml.FermiWord({(0, 0): '+', (1, 0): '-'})
>>> fw2 = qml.FermiWord({(0, 3): '+', (1, 3): '-'})
>>> qml.FermiSentence({fw1: 1.2, fw2: 2.3})
1.2 * a⁺(0) a(0)
+ 2.3 * a⁺(3) a(3)
9 changes: 6 additions & 3 deletions doc/releases/changelog-0.40.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,6 @@
* Added support to build a vibrational Hamiltonian in Taylor form.
[(#6523)](https://github.com/PennyLaneAI/pennylane/pull/6523)

* Added support to build a vibrational Hamiltonian in the Christiansen form.
[(#6560)](https://github.com/PennyLaneAI/pennylane/pull/6560)

<h3>Improvements 🛠</h3>

<h4>QChem improvements</h4>
Expand Down Expand Up @@ -494,6 +491,12 @@ such as `shots`, `rng` and `prng_key`.
for the horizontal Cartan subalgebra instead of `$\mathfrak{h}$`.
[(#6747)](https://github.com/PennyLaneAI/pennylane/pull/6747)

<h4>Construct vibrational Hamiltonians 🫨</h4>

* Added support to build a vibrational Hamiltonian in the Christiansen form.
[(#6560)](https://github.com/PennyLaneAI/pennylane/pull/6560)
[(#6792)](https://github.com/PennyLaneAI/pennylane/pull/6792)

<h3>Breaking changes 💔</h3>

* The default graph coloring method of `qml.dot`, `qml.sum`, and `qml.pauli.optimize_measurements` for grouping observables was changed
Expand Down
2 changes: 2 additions & 0 deletions pennylane/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
from pennylane.fermi import (
FermiC,
FermiA,
FermiWord,
FermiSentence,
jordan_wigner,
parity_transform,
bravyi_kitaev,
Expand Down
2 changes: 1 addition & 1 deletion pennylane/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
Version number (major.minor.patch[-label])
"""

__version__ = "0.41.0-dev3"
__version__ = "0.41.0-dev4"
20 changes: 10 additions & 10 deletions pennylane/bose/bosonic.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class BoseWord(dict):
symbols that denote creation and annihilation operators, respectively. The operator
:math:`b^{\dagger}_0 b_1` can then be constructed as
>>> w = qml.bose.BoseWord({(0, 0) : '+', (1, 1) : '-'})
>>> w = qml.BoseWord({(0, 0) : '+', (1, 1) : '-'})
>>> print(w)
b⁺(0) b(1)
"""
Expand Down Expand Up @@ -112,7 +112,7 @@ def to_string(self):
represented by the number of the wire it operates on, and a `+` or `-` to indicate either
a creation or annihilation operator.
>>> w = qml.bose.BoseWord({(0, 0) : '+', (1, 1) : '-'})
>>> w = qml.BoseWord({(0, 0) : '+', (1, 1) : '-'})
>>> w.to_string()
'b⁺(0) b(1)'
"""
Expand Down Expand Up @@ -209,7 +209,7 @@ def __rsub__(self, other):
def __mul__(self, other):
r"""Multiply a BoseWord with another BoseWord, a BoseSentence, or a constant.
>>> w = qml.bose.BoseWord({(0, 0) : '+', (1, 1) : '-'})
>>> w = qml.BoseWord({(0, 0) : '+', (1, 1) : '-'})
>>> print(w * w)
b⁺(0) b(1) b⁺(0) b(1)
"""
Expand Down Expand Up @@ -263,7 +263,7 @@ def __rmul__(self, other):
def __pow__(self, value):
r"""Exponentiate a Bose word to an integer power.
>>> w = qml.bose.BoseWord({(0, 0) : '+', (1, 1) : '-'})
>>> w = qml.BoseWord({(0, 0) : '+', (1, 1) : '-'})
>>> print(w**3)
b⁺(0) b(1) b⁺(0) b(1) b⁺(0) b(1)
"""
Expand All @@ -280,7 +280,7 @@ def __pow__(self, value):
def normal_order(self):
r"""Convert a BoseWord to its normal-ordered form.
>>> bw = qml.bose.BoseWord({(0, 0): "-", (1, 0): "-", (2, 0): "+", (3, 0): "+"})
>>> bw = qml.BoseWord({(0, 0): "-", (1, 0): "-", (2, 0): "+", (3, 0): "+"})
>>> print(bw.normal_order())
4.0 * b⁺(0) b(0)
+ 2.0 * I
Expand Down Expand Up @@ -420,9 +420,9 @@ class BoseSentence(dict):
r"""Dictionary used to represent a Bose sentence, a linear combination of Bose words,
with the keys as BoseWord instances and the values correspond to coefficients.
>>> w1 = qml.bose.BoseWord({(0, 0) : '+', (1, 1) : '-'})
>>> w2 = qml.bose.BoseWord({(0, 1) : '+', (1, 2) : '-'})
>>> s = BoseSentence({w1 : 1.2, w2: 3.1})
>>> w1 = qml.BoseWord({(0, 0) : '+', (1, 1) : '-'})
>>> w2 = qml.BoseWord({(0, 1) : '+', (1, 2) : '-'})
>>> s = qml.BoseSentence({w1 : 1.2, w2: 3.1})
>>> print(s)
1.2 * b⁺(0) b(1)
+ 3.1 * b⁺(1) b(2)
Expand Down Expand Up @@ -608,8 +608,8 @@ def simplify(self, tol=1e-8):
def normal_order(self):
r"""Convert a BoseSentence to its normal-ordered form.
>>> bw = qml.bose.BoseWord({(0, 0): "-", (1, 0): "-", (2, 0): "+", (3, 0): "+"})
>>> bs = qml.bose.BoseSentence({bw: 1})
>>> bw = qml.BoseWord({(0, 0): "-", (1, 0): "-", (2, 0): "+", (3, 0): "+"})
>>> bs = qml.BoseSentence({bw: 1})
>>> print(bw.normal_order())
4.0 * b⁺(0) b(0)
+ 2.0 * I
Expand Down
10 changes: 5 additions & 5 deletions pennylane/bose/bosonic_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def binary_mapping(
**Example**
>>> w = qml.bose.BoseWord({(0, 0): "+"})
>>> w = qml.BoseWord({(0, 0): "+"})
>>> qml.binary_mapping(w, n_states=4)
(
0.6830127018922193 * X(0)
Expand Down Expand Up @@ -95,7 +95,7 @@ def binary_mapping(
@singledispatch
def _binary_mapping_dispatch(bose_operator, n_states, tol):
"""Dispatches to appropriate function if bose_operator is a BoseWord or BoseSentence."""
raise ValueError(f"bose_operator must be a BoseWord or BoseSentence, got: {bose_operator}")
raise TypeError(f"bose_operator must be a BoseWord or BoseSentence, got: {bose_operator}")


@_binary_mapping_dispatch.register
Expand Down Expand Up @@ -190,7 +190,7 @@ def unary_mapping(
**Example**
>>> w = qml.bose.BoseWord({(0, 0): "+"})
>>> w = qml.BoseWord({(0, 0): "+"})
>>> qml.unary_mapping(w, n_states=4)
(
0.25 * X(0) @ X(1)
Expand Down Expand Up @@ -224,7 +224,7 @@ def unary_mapping(
@singledispatch
def _unary_mapping_dispatch(bose_operator, n_states, ps=False, wires_map=None, tol=None):
"""Dispatches to appropriate function if bose_operator is a BoseWord or BoseSentence."""
raise ValueError(f"bose_operator must be a BoseWord or BoseSentence, got: {bose_operator}")
raise TypeError(f"bose_operator must be a BoseWord or BoseSentence, got: {bose_operator}")


@_unary_mapping_dispatch.register
Expand Down Expand Up @@ -367,7 +367,7 @@ def christiansen_mapping(
@singledispatch
def _christiansen_mapping_dispatch(bose_operator, tol):
"""Dispatches to appropriate function if bose_operator is a BoseWord or BoseSentence."""
raise ValueError(f"bose_operator must be a BoseWord or BoseSentence, got: {bose_operator}")
raise TypeError(f"bose_operator must be a BoseWord or BoseSentence, got: {bose_operator}")


@_christiansen_mapping_dispatch.register
Expand Down
5 changes: 4 additions & 1 deletion pennylane/devices/_legacy_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,10 @@ def _all_multi_term_obs_supported(self, circuit):
# Some measurements are not observable based.
continue

if mp.obs.name == "LinearCombination" and not self.supports_observable("Hamiltonian"):
if mp.obs.name == "LinearCombination" and not (
self.supports_observable("Hamiltonian")
or self.supports_observable("LinearCombination")
):
return False

if mp.obs.name in (
Expand Down
24 changes: 14 additions & 10 deletions pennylane/fermi/fermionic.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class FermiWord(dict):
:math:`a^{\dagger}_0 a_1` can then be constructed as
>>> w = FermiWord({(0, 0) : '+', (1, 1) : '-'})
>>> w
>>> print(w)
a⁺(0) a(1)
"""

Expand Down Expand Up @@ -114,7 +114,7 @@ def to_string(self):
>>> w = FermiWord({(0, 0) : '+', (1, 1) : '-'})
>>> w.to_string()
a⁺(0) a(1)
'a⁺(0) a(1)'
"""
if len(self) == 0:
return "I"
Expand Down Expand Up @@ -211,7 +211,7 @@ def __mul__(self, other):
r"""Multiply a FermiWord with another FermiWord, a FermiSentence, or a constant.
>>> w = FermiWord({(0, 0) : '+', (1, 1) : '-'})
>>> w * w
>>> print(w * w)
a⁺(0) a(1) a⁺(0) a(1)
"""

Expand Down Expand Up @@ -265,7 +265,7 @@ def __pow__(self, value):
r"""Exponentiate a Fermi word to an integer power.
>>> w = FermiWord({(0, 0) : '+', (1, 1) : '-'})
>>> w**3
>>> print(w**3)
a⁺(0) a(1) a⁺(0) a(1) a⁺(0) a(1)
"""

Expand Down Expand Up @@ -348,7 +348,7 @@ def shift_operator(self, initial_position, final_position):
**Example**
>>> w = qml.fermi.FermiWord({(0, 0): '+', (1, 1): '-'})
>>> w = qml.FermiWord({(0, 0): '+', (1, 1): '-'})
>>> w.shift_operator(0, 1)
-1 * a(1) a⁺(0)
"""
Expand Down Expand Up @@ -427,7 +427,7 @@ class FermiSentence(dict):
>>> w1 = FermiWord({(0, 0) : '+', (1, 1) : '-'})
>>> w2 = FermiWord({(0, 1) : '+', (1, 2) : '-'})
>>> s = FermiSentence({w1 : 1.2, w2: 3.1})
>>> s
>>> print(s)
1.2 * a⁺(0) a(1)
+ 3.1 * a⁺(1) a(2)
"""
Expand Down Expand Up @@ -754,13 +754,15 @@ class FermiC(FermiWord):
To construct the operator :math:`a^{\dagger}_0`:
>>> FermiC(0)
>>> w = FermiC(0)
>>> print(w)
a⁺(0)
This can be combined with the annihilation operator :class:`~pennylane.FermiA`. For example,
:math:`a^{\dagger}_0 a_1 a^{\dagger}_2 a_3` can be constructed as:
>>> qml.FermiC(0) * qml.FermiA(1) * qml.FermiC(2) * qml.FermiA(3)
>>> w = qml.FermiC(0) * qml.FermiA(1) * qml.FermiC(2) * qml.FermiA(3)
>>> print(w)
a⁺(0) a(1) a⁺(2) a(3)
"""

Expand Down Expand Up @@ -796,13 +798,15 @@ class FermiA(FermiWord):
To construct the operator :math:`a_0`:
>>> FermiA(0)
>>> w = FermiA(0)
>>> print(w)
a(0)
This can be combined with the creation operator :class:`~pennylane.FermiC`. For example,
:math:`a^{\dagger}_0 a_1 a^{\dagger}_2 a_3` can be constructed as:
>>> qml.FermiC(0) * qml.FermiA(1) * qml.FermiC(2) * qml.FermiA(3)
>>> w = qml.FermiC(0) * qml.FermiA(1) * qml.FermiC(2) * qml.FermiA(3)
>>> print(w)
a⁺(0) a(1) a⁺(2) a(3)
"""

Expand Down
Loading

0 comments on commit 9926eaf

Please sign in to comment.