Skip to content

Commit

Permalink
FermiWord and FermiSentence to_mat() method optionally return sparse …
Browse files Browse the repository at this point in the history
…matrices (#6173)

This PR adds an optional flag to the `FermiWord` and `FermiSentence`
methods `to_mat` which when set will return a sparse matrix. Both are
used in the following way: `mat = fw.to_mat(format="csr")`. This PR
addresses [sc-72169].

---------

Co-authored-by: soranjh <40344468+soranjh@users.noreply.github.com>
  • Loading branch information
willjmax and soranjh authored Sep 9, 2024
1 parent 0d41e7a commit 48b9dc7
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 6 deletions.
3 changes: 3 additions & 0 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
unique representation of the object.
[(#6167)](https://github.com/PennyLaneAI/pennylane/pull/6167)

* The `to_mat` methods for `FermiWord` and `FermiSentence` now optionally return
a sparse matrix.
[(#6173)](https://github.com/PennyLaneAI/pennylane/pull/6173)

<h3>Breaking changes 💔</h3>

Expand Down
22 changes: 16 additions & 6 deletions pennylane/fermi/fermionic.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,12 +273,16 @@ def __pow__(self, value):

return operator

def to_mat(self, n_orbitals=None):
def to_mat(self, n_orbitals=None, format="dense", buffer_size=None):
r"""Return the matrix representation.
Args:
n_orbitals (int or None): Number of orbitals. If not provided, it will be inferred from
the largest orbital index in the Fermi operator.
format (str): The format of the matrix. It is "dense" by default. Use "csr" for sparse.
buffer_size (int or None)`: The maximum allowed memory in bytes to store intermediate results
in the calculation of sparse matrices. It defaults to ``2 ** 30`` bytes that make
1GB of memory. In general, larger buffers allow faster computations.
Returns:
NumpyArray: Matrix representation of the :class:`~.FermiWord`.
Expand All @@ -299,9 +303,10 @@ def to_mat(self, n_orbitals=None):
)

largest_order = n_orbitals or largest_orb_id
mat = qml.jordan_wigner(self, ps=True).to_mat(wire_order=list(range(largest_order)))

return mat
return qml.jordan_wigner(self, ps=True).to_mat(
wire_order=list(range(largest_order)), format=format, buffer_size=buffer_size
)


# pylint: disable=useless-super-delegation
Expand Down Expand Up @@ -493,12 +498,16 @@ def simplify(self, tol=1e-8):
if abs(coeff) <= tol:
del self[fw]

def to_mat(self, n_orbitals=None):
def to_mat(self, n_orbitals=None, format="dense", buffer_size=None):
r"""Return the matrix representation.
Args:
n_orbitals (int or None): Number of orbitals. If not provided, it will be inferred from
the largest orbital index in the Fermi operator
format (str): The format of the matrix. It is "dense" by default. Use "csr" for sparse.
buffer_size (int or None)`: The maximum allowed memory in bytes to store intermediate results
in the calculation of sparse matrices. It defaults to ``2 ** 30`` bytes that make
1GB of memory. In general, larger buffers allow faster computations.
Returns:
NumpyArray: Matrix representation of the :class:`~.FermiSentence`.
Expand All @@ -519,9 +528,10 @@ def to_mat(self, n_orbitals=None):
)

largest_order = n_orbitals or largest_orb_id
mat = qml.jordan_wigner(self, ps=True).to_mat(wire_order=list(range(largest_order)))

return mat
return qml.jordan_wigner(self, ps=True).to_mat(
wire_order=list(range(largest_order)), format=format, buffer_size=buffer_size
)


def from_string(fermi_string):
Expand Down
9 changes: 9 additions & 0 deletions tests/fermi/test_fermionic.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import numpy as np
import pytest
from scipy import sparse

import pennylane as qml
from pennylane import numpy as pnp
Expand Down Expand Up @@ -133,6 +134,11 @@ def test_to_mat(self):

mat = fw1.to_mat()
assert np.allclose(mat, expected_mat)
assert isinstance(mat, np.ndarray)

mat = fw1.to_mat(format="csr")
assert np.allclose(mat.toarray(), expected_mat)
assert isinstance(mat, sparse.csr_matrix)

def test_to_mat_error(self):
"""Test that an error is raised if the requested matrix dimension is smaller than the
Expand Down Expand Up @@ -636,6 +642,9 @@ def test_to_mat(self):
mat = fs7.to_mat()
assert np.allclose(mat, expected_mat)

mat = fs7.to_mat(format="csr")
assert np.allclose(mat.toarray(), expected_mat)

def test_to_mat_error(self):
"""Test that an error is raised if the requested matrix dimension is smaller than the
dimension inferred from the largest orbital index.
Expand Down

0 comments on commit 48b9dc7

Please sign in to comment.