Skip to content

Commit

Permalink
Fix bug in fermi op arithmetic for np.array([1, 2])[0] (#4262)
Browse files Browse the repository at this point in the history
* switch len with qml.math.size

* update change log
  • Loading branch information
lillian542 authored Jun 16, 2023
1 parent dbadf45 commit 2e39c51
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 10 deletions.
1 change: 1 addition & 0 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
using `+`, `-` and `*` between
`FermiWord`, `FermiSentence` and `int`, `float` and `complex` objects.
[(#4209)](https://github.com/PennyLaneAI/pennylane/pull/4209)
[(#4262)](https://github.com/PennyLaneAI/pennylane/pull/4262)

* Added the `one_qubit_decomposition` function to provide a unified interface for all one qubit decompositions. All
decompositions simplify the rotations angles to be between `0` and `4` pi.
Expand Down
22 changes: 12 additions & 10 deletions pennylane/fermi/fermionic.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
from numbers import Number
from numpy import ndarray

import pennylane as qml


class FermiWord(dict):
r"""Immutable dictionary used to represent a Fermi word, a product of fermionic creation and
Expand Down Expand Up @@ -133,7 +135,7 @@ def __add__(self, other):
return self_fs + FermiSentence({other: 1.0})

if isinstance(other, (Number, ndarray)):
if isinstance(other, ndarray) and len(other) > 1:
if isinstance(other, ndarray) and qml.math.size(other) > 1:
raise ValueError(
f"Arithmetic Fermi operations can only accept an array of length 1, "
f"but received {other} of length {len(other)}"
Expand Down Expand Up @@ -165,7 +167,7 @@ def __sub__(self, other):
return self_fs + other_fs

if isinstance(other, (Number, ndarray)):
if isinstance(other, ndarray) and len(other) > 1:
if isinstance(other, ndarray) and qml.math.size(other) > 1:
raise ValueError(
f"Arithmetic Fermi operations can only accept an array of length 1, "
f"but received {other} of length {len(other)}"
Expand All @@ -177,7 +179,7 @@ def __sub__(self, other):
def __rsub__(self, other):
"""Subtract a FermiWord to a constant, i.e. `2 - FermiWord({...})`"""
if isinstance(other, (Number, ndarray)):
if isinstance(other, ndarray) and len(other) > 1:
if isinstance(other, ndarray) and qml.math.size(other) > 1:
raise ValueError(
f"Arithmetic Fermi operations can only accept an array of length 1, "
f"but received {other} of length {len(other)}"
Expand Down Expand Up @@ -222,7 +224,7 @@ def __mul__(self, other):
return FermiSentence({self: 1}) * other

if isinstance(other, (Number, ndarray)):
if isinstance(other, ndarray) and len(other) > 1:
if isinstance(other, ndarray) and qml.math.size(other) > 1:
raise ValueError(
f"Arithmetic Fermi operations can only accept an array of length 1, "
f"but received {other} of length {len(other)}"
Expand All @@ -240,7 +242,7 @@ def __rmul__(self, other):
will fail to multiply with a FermiWord"""

if isinstance(other, (Number, ndarray)):
if isinstance(other, ndarray) and len(other) > 1:
if isinstance(other, ndarray) and qml.math.size(other) > 1:
raise ValueError(
f"Arithmetic Fermi operations can only accept an array of length 1, "
f"but received {other} of length {len(other)}"
Expand Down Expand Up @@ -314,7 +316,7 @@ def __add__(self, other):
if isinstance(other, Number):
other = FermiSentence({FermiWord({}): other})
if isinstance(other, ndarray):
if len(other) > 1:
if qml.math.size(other) > 1:
raise ValueError(
f"Arithmetic Fermi operations can only accept an array of length 1, "
f"but received {other} of length {len(other)}"
Expand Down Expand Up @@ -351,7 +353,7 @@ def __sub__(self, other):
return self.__add__(other)

if isinstance(other, ndarray):
if len(other) > 1:
if qml.math.size(other) > 1:
raise ValueError(
f"Arithmetic Fermi operations can only accept an array of length 1, "
f"but received {other} of length {len(other)}"
Expand All @@ -372,7 +374,7 @@ def __rsub__(self, other):
"""

if isinstance(other, (Number, ndarray)):
if isinstance(other, ndarray) and len(other) > 1:
if isinstance(other, ndarray) and qml.math.size(other) > 1:
raise ValueError(
f"Arithmetic Fermi operations can only accept an array of length 1, "
f"but received {other} of length {len(other)}"
Expand Down Expand Up @@ -403,7 +405,7 @@ def __mul__(self, other):
return product

if isinstance(other, (Number, ndarray)):
if isinstance(other, ndarray) and len(other) > 1:
if isinstance(other, ndarray) and qml.math.size(other) > 1:
raise ValueError(
f"Arithmetic Fermi operations can only accept an array of length 1, "
f"but received {other} of length {len(other)}"
Expand All @@ -422,7 +424,7 @@ def __rmul__(self, other):
will fail to multiply with a FermiSentence"""

if isinstance(other, (Number, ndarray)):
if isinstance(other, ndarray) and len(other) > 1:
if isinstance(other, ndarray) and qml.math.size(other) > 1:
raise ValueError(
f"Arithmetic Fermi operations can only accept an array of length 1, "
f"but received {other} of length {len(other)}"
Expand Down
36 changes: 36 additions & 0 deletions tests/fermi/test_fermionic.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ def test_mul_fermi_word_and_sentence(self, fw, fs, result):
(fw2, 2j, FermiSentence({fw2: 2j})), # complex
(fw2, np.array([2]), FermiSentence({fw2: 2})), # numpy array
(fw1, pnp.array([2]), FermiSentence({fw1: 2})), # pennylane numpy array
(fw1, pnp.array([2, 2])[0], FermiSentence({fw1: 2})), # pennylane tensor with no length
)

@pytest.mark.parametrize("fw, number, result", WORDS_AND_NUMBERS_MUL)
Expand Down Expand Up @@ -282,6 +283,11 @@ def test_add_fermi_words_and_sentences(self, w, s, res):
(fw3, (1 + 3j), FermiSentence({fw3: 1, fw4: (1 + 3j)})), # complex
(fw1, np.array([5]), FermiSentence({fw1: 1, fw4: 5})), # numpy array
(fw2, pnp.array([2.8]), FermiSentence({fw2: 1, fw4: 2.8})), # pennylane numpy array
(
fw1,
pnp.array([2, 2])[0],
FermiSentence({fw1: 1, fw4: 2}),
), # pennylane tensor with no length
(fw4, 2, FermiSentence({fw4: 3})), # FermiWord is Identity
]

Expand Down Expand Up @@ -345,6 +351,11 @@ def test_subtract_fermi_words_and_sentences(self, w, s, res):
(fw3, (1 + 3j), FermiSentence({fw3: 1, fw4: -(1 + 3j)})), # complex
(fw1, np.array([5]), FermiSentence({fw1: 1, fw4: -5})), # numpy array
(fw2, pnp.array([2.8]), FermiSentence({fw2: 1, fw4: -2.8})), # pennylane numpy array
(
fw1,
pnp.array([2, 2])[0],
FermiSentence({fw1: 1, fw4: -2}),
), # pennylane tensor with no length
(fw4, 2, FermiSentence({fw4: -1})), # FermiWord is Identity
]

Expand All @@ -366,6 +377,11 @@ def test_subtract_constant_from_fermi_word(self, w, c, res):
(fw3, (1 + 3j), FermiSentence({fw3: -1, fw4: (1 + 3j)})), # complex
(fw1, np.array([5]), FermiSentence({fw1: -1, fw4: 5})), # numpy array
(fw2, pnp.array([2.8]), FermiSentence({fw2: -1, fw4: 2.8})), # pennylane numpy array
(
fw1,
pnp.array([2, 2])[0],
FermiSentence({fw1: -1, fw4: 2}),
), # pennylane tensor with no length
(fw4, 2, FermiSentence({fw4: 1})), # FermiWord is Identity
]

Expand Down Expand Up @@ -665,6 +681,11 @@ def test_mul_fermi_word_and_sentence(self, fw, fs, result):
pnp.array([2]),
FermiSentence({fw1: 1.23 * 2, fw2: 4j * 2, fw3: -0.5 * 2}),
), # pennylane numpy array
(
fs1,
pnp.array([2, 2])[0],
FermiSentence({fw1: 1.23 * 2, fw2: 4j * 2, fw3: -0.5 * 2}),
), # pennylane tensor with no length
)

@pytest.mark.parametrize("fs, number, result", SENTENCES_AND_NUMBERS_MUL)
Expand Down Expand Up @@ -736,6 +757,11 @@ def test_add_fermi_words_and_sentences(self, w, s, res):
pnp.array([3]),
FermiSentence({fw1: 1.2, fw3: 3j, fw4: 3}),
), # pennylane numpy array
(
FermiSentence({fw1: 1.2, fw3: 3j}),
pnp.array([3, 0])[0],
FermiSentence({fw1: 1.2, fw3: 3j, fw4: 3}),
), # pennylane tensor with no length
]

@pytest.mark.parametrize("s, c, res", SENTENCES_AND_CONSTANTS_ADD)
Expand Down Expand Up @@ -803,6 +829,11 @@ def test_subtract_fermi_word_from_fermi_sentence(self, fs, fw, result):
pnp.array([3]),
FermiSentence({fw1: 1.2, fw3: 3j, fw4: -3}),
), # pennylane numpy array
(
FermiSentence({fw1: 1.2, fw3: 3j}),
pnp.array([3, 2])[0],
FermiSentence({fw1: 1.2, fw3: 3j, fw4: -3}),
), # pennylane tensor with no len
)

@pytest.mark.parametrize("fs, c, result", SENTENCE_MINUS_CONSTANT)
Expand Down Expand Up @@ -834,6 +865,11 @@ def test_subtract_constant_from_fermi_sentence(self, fs, c, result):
pnp.array([3]),
FermiSentence({fw1: -1.2, fw3: -3j, fw4: 3}),
), # pennylane numpy array
(
FermiSentence({fw1: 1.2, fw3: 3j}),
pnp.array([3, 3])[0],
FermiSentence({fw1: -1.2, fw3: -3j, fw4: 3}),
), # pennylane tensor with to len
)

@pytest.mark.parametrize("fs, c, result", CONSTANT_MINUS_SENTENCE)
Expand Down

0 comments on commit 2e39c51

Please sign in to comment.