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

Add norm for second quantized Hamiltonian #2653

Merged
merged 19 commits into from
Jun 20, 2022
Merged
Show file tree
Hide file tree
Changes from 16 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
15 changes: 15 additions & 0 deletions doc/code/qml_resources.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
qml.resources
=============

Overview
--------

The resources module provides the functionality to estimate the cost of implementing advanced
quantum algorithms.

.. currentmodule:: pennylane.resources

.. automodapi:: pennylane.resources
:no-heading:
:include-all-objects:
:no-inheritance-diagram:
1 change: 1 addition & 0 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ PennyLane is **free** and **open source**, released under the Apache License, Ve
code/qml_hf
code/qml_qchem
code/qml_qnn
code/qml_resources
code/qml_tape
code/qml_transforms
code/qml_drawer
Expand Down
1 change: 1 addition & 0 deletions pennylane/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import pennylane.math
import pennylane.operation
import pennylane.qnn
import pennylane.resources
import pennylane.templates
import pennylane.hf
import pennylane.qchem
Expand Down
1 change: 1 addition & 0 deletions pennylane/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"""
This subpackage provides the functionality for algorithm resource estimation.
"""
from .second_quantization import norm_df
81 changes: 81 additions & 0 deletions pennylane/resources/second_quantization.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Copyright 2018-2022 Xanadu Quantum Technologies Inc.

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
This module contains the functions needed for resource estimation with double factorization method.
"""

from pennylane import numpy as np


def norm_df(one, two, eigvals):
r"""Return the 1-norm of a molecular Hamiltonian from the one- and two-electron integrals and
eigenvalues of the factorized two-electron integral tensor.

The 1-norm of a double-factorized molecular Hamiltonian is computed as
[`arXiv:2007.14460 <https://arxiv.org/abs/2007.14460>`_]

.. math::

\lambda = ||T|| + \frac{1}{4} \sum_r ||L^{(r)}||^2,

where the Schatten 1-norm for a given matrix :math:`T` is defined as

.. math::

||T|| = \sum_k |\text{eigvals}[T]_k|.

The matrices :math:`L^{(r)}` are obtained from factorization of the two-electron integral
tensor :math:`V` such that

.. math::

V_{ijkl} = \sum_r L_{ij}^{(r)} L_{kl}^{(r) T}.

The matrix :math:`T` is constructed from the one- and two-electron integrals as

.. math::

T = h_{ij} - \frac{1}{2} \sum_l V_{illj} + \sum_l V_{llij}.

Note that the two-electron integral tensor must be arranged in the chemist notation.

Args:
one (array[array[float]]): one-electron integrals
two (array[array[float]]): two-electron integrals
eigvals (array[float]): eigenvalues of the matrices obtained from factorizing the
two-electron integral tensor

Returns:
array[float]: 1-norm of the Hamiltonian

**Example**

>>> symbols = ['H', 'H', 'O']
>>> geometry = np.array([[0.00000000, 0.00000000, 0.28377432],
>>> [0.00000000, 1.45278171, -1.00662237],
>>> [0.00000000, -1.45278171, -1.00662237]], requires_grad=False)
>>> mol = qml.qchem.Molecule(symbols, geometry, basis_name='sto-3g')
>>> core, one, two = qml.qchem.electron_integrals(mol)()
>>> two = np.swapaxes(two, 1, 3) # convert to the chemists notation
>>> _, eigvals, _ = factorize(two, 1e-5)
>>> print(norm(one, two, eigvals))
soranjh marked this conversation as resolved.
Show resolved Hide resolved
52.98762043980203
"""
lambda_one = 0.25 * np.sum([np.sum(abs(v)) ** 2 for v in eigvals])

t_matrix = one - 0.5 * np.einsum("illj", two) + np.einsum("llij", two)
t_eigvals, _ = np.linalg.eigh(t_matrix)
lambda_two = np.sum(abs(t_eigvals))

return lambda_one + lambda_two
52 changes: 52 additions & 0 deletions tests/resources/test_second_quantization.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Copyright 2018-2021 Xanadu Quantum Technologies Inc.

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Unit tests for functions needed for resource estimation with double factorization method.
"""
import pytest

import pennylane as qml
from pennylane import numpy as np


@pytest.mark.parametrize(
("one", "two", "eigvals", "lamb_ref"),
[
(
np.array([[-1.25330961e00, 4.01900735e-14], [4.01900735e-14, -4.75069041e-01]]),
# two-electron integral is arranged in the chemist notation [11|22]
np.array(
[
[
[[6.74755872e-01, -4.60742555e-14], [-4.60742555e-14, 6.63711349e-01]],
[[-4.61020111e-14, 1.81210478e-01], [1.81210478e-01, -4.26325641e-14]],
],
[
[[-4.60464999e-14, 1.81210478e-01], [1.81210478e-01, -4.25215418e-14]],
[[6.63711349e-01, -4.28546088e-14], [-4.24105195e-14, 6.97651447e-01]],
],
]
),
np.tensor(
[[-0.10489852, 0.10672343], [-0.42568824, 0.42568824], [-0.82864211, -0.81447282]]
),
1.6570518796336895, # lambda value obtained from openfermion
)
],
)
def test_df_norm(one, two, eigvals, lamb_ref):
r"""Test that the norm function returns the correct 1-norm."""
lamb = qml.resources.norm_df(one, two, eigvals)

assert np.allclose(lamb, lamb_ref)