Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

modify low_rank for one-body-matrix truncation reference #833

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions src/openfermion/circuits/low_rank.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,22 +159,22 @@ def low_rank_two_body_decomposition(two_body_coefficients,
one_body_correction, truncation_value)


def prepare_one_body_squared_evolution(one_body_matrix, spin_basis=True):
def prepare_one_body_squared_evolution(one_body_matrix, spin_basis=True, truncation_ref=None):
r"""Get Givens angles and DiagonalHamiltonian to simulate squared one-body.

The goal here will be to prepare to simulate evolution under
$(\sum_{pq} h_{pq} a^\dagger_p a_q)^2$ by decomposing as
$R e^{-i \sum_{pq} V_{pq} n_p n_q} R^\dagger$ where
$R$ is a basis transformation matrix.

TODO: Add option for truncation based on one-body eigenvalues.

Args:
one_body_matrix (ndarray of floats): an N by N array storing the
coefficients of a one-body operator to be squared. For instance,
in the above the elements of this matrix are $h_{pq}$.
spin_basis (bool): Whether the matrix is passed in the
spin orbital basis.
truncation_ref (float): Eigenvalues under this threshold reference will
be truncated for density matrix calculation.
Comment on lines +176 to +177
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

document that this is optional and that None turns off truncation


Returns:
density_density_matrix(ndarray of floats) an N by N array storing
Expand Down Expand Up @@ -206,6 +206,18 @@ def prepare_one_body_squared_evolution(one_body_matrix, spin_basis=True):
numpy.eye(2))
eigenvalues = numpy.kron(eigenvalues, numpy.ones(2))

# If the truncation reference is valid,
# build truncated eigenvalues and eigenvectors
# based on the reference for density matrix
if truncation_ref is not None and isinstance(truncation_ref, float):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's rely on python duck typing for the type of truncation_ref instead of mandating that it is a float. E.g.: what if it's a np.float64?

valid_indices = numpy.where(eigenvalues >= truncation_ref)[0]
retained_indices = numpy.where(eigenvalues < truncation_ref)[0]
eigenvalues = eigenvalues[valid_indices]
eigenvectors = eigenvectors[:, valid_indices]
print(f"Retained {len(valid_indices)} eigenvalues and truncated {len(retained_indices)} eigenvalues from the one-body-matrix.")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please do not print in library code

else:
raise ValueError("truncation_ref argument must be a valid float.")

# Obtain the diagonal two-body matrix.
density_density_matrix = numpy.outer(eigenvalues, eigenvalues)

Expand Down
8 changes: 8 additions & 0 deletions src/openfermion/circuits/low_rank_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,3 +328,11 @@ def test_one_body_squared_nonhermitian_raises_error(self):
with self.assertRaises(ValueError):
prepare_one_body_squared_evolution(one_body_matrix,
spin_basis=False)

def test_one_body_squared_truncated(self):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add a test that actually works rather then just testing error handling

one_body_matrix = numpy.array([[2.0, 1.5, 0.2],[1.5, 3.0, 1.0],[0.2, 1.0, 4.0]])
truncation_reference = 1.0
with self.assertRaises(ValueError):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this raising an error? please use assertRaisesRegex to test against (and document) the error message you expect

prepare_one_body_squared_evolution(one_body_matrix,
spin_basis=False,
truncation_ref=truncation_reference)
Loading