diff --git a/src/openfermion/contrib/representability/_namedtensor.py b/src/openfermion/contrib/representability/_namedtensor.py index f4fe977ab..ed557cb11 100644 --- a/src/openfermion/contrib/representability/_namedtensor.py +++ b/src/openfermion/contrib/representability/_namedtensor.py @@ -1,4 +1,4 @@ -from typing import Iterable, Generator, Optional, Union +from typing import Iterable, Generator, Literal, Optional, Union from itertools import zip_longest import numpy as np from openfermion.contrib.representability._bijections import Bijection, index_index_basis @@ -9,6 +9,13 @@ class Tensor: Instantiation of named tensor """ + dim: int | None + ndim: int | None + data: np.ndarray | None + size: int | None + basis: Bijection | None + name: str | None + def __init__( self, *, @@ -156,6 +163,10 @@ def _iterator(self, ultri: str) -> Generator: """ Iterate over the a data store yielding the upper/lower/all values """ + if self.data is None or self.ndim is None or self.dim is None or self.basis is None: + raise TypeError("data store is not set") + + basis = self.basis if ultri not in ['upper', 'lower', 'all']: raise TypeError("iteration type {} is not 'upper', 'lower', or 'all'".format(ultri)) @@ -168,21 +179,24 @@ def _iterator(self, ultri: str) -> Generator: ) if ultri == 'upper' and left_idx_set <= right_idx_set: - yield it[0], map(lambda x: self.basis.fwd(x), it.multi_index) + yield it[0], map(lambda x: basis.fwd(x), it.multi_index) elif ultri == 'lower' and left_idx_set >= right_idx_set: - yield it[0], map(lambda x: self.basis.fwd(x), it.multi_index) + yield it[0], map(lambda x: basis.fwd(x), it.multi_index) elif ultri == 'all': - yield it[0], map(lambda x: self.basis.fwd(x), it.multi_index) + yield it[0], map(lambda x: basis.fwd(x), it.multi_index) it.iternext() - def vectorize(self, order: Optional[str] = 'C') -> np.ndarray: + def vectorize(self, order: Literal["A", "C", "F"] | None = "C") -> np.ndarray: """ Take a multidimensional array and vectorized via C ordering :return: a vector of self.size x 1 """ - return np.reshape(self.data, (-1, 1), order=order) + if self.data is None: + raise TypeError("data store is not set") + reshape_order: Literal["A", "C", "F"] = "C" if order is None else order + return self.data.reshape(-1, 1, order=reshape_order) # from standard library itertools recipe book diff --git a/src/openfermion/contrib/representability/_namedtensor_test.py b/src/openfermion/contrib/representability/_namedtensor_test.py index 0e5947962..83c6997c4 100644 --- a/src/openfermion/contrib/representability/_namedtensor_test.py +++ b/src/openfermion/contrib/representability/_namedtensor_test.py @@ -35,6 +35,10 @@ def test_namedtensor_getdata(): blank_td = Tensor(name='opdm') with pytest.raises(TypeError): _ = blank_td[0, 0] + with pytest.raises(TypeError, match='data store is not set'): + blank_td.vectorize() + with pytest.raises(TypeError, match='data store is not set'): + list(blank_td.utri_iterator()) def test_namedtensor_call(): diff --git a/src/openfermion/hamiltonians/plane_wave_hamiltonian.py b/src/openfermion/hamiltonians/plane_wave_hamiltonian.py index 096f674fb..27a1568bb 100644 --- a/src/openfermion/hamiltonians/plane_wave_hamiltonian.py +++ b/src/openfermion/hamiltonians/plane_wave_hamiltonian.py @@ -86,6 +86,8 @@ def dual_basis_external_potential( operator = FermionOperator(operators, coefficient) else: operator += FermionOperator(operators, coefficient) + if operator is None: + return FermionOperator() return operator diff --git a/src/openfermion/hamiltonians/plane_wave_hamiltonian_test.py b/src/openfermion/hamiltonians/plane_wave_hamiltonian_test.py index 1e43d99dc..b8c42b44b 100644 --- a/src/openfermion/hamiltonians/plane_wave_hamiltonian_test.py +++ b/src/openfermion/hamiltonians/plane_wave_hamiltonian_test.py @@ -16,16 +16,23 @@ import numpy as np from openfermion.hamiltonians.plane_wave_hamiltonian import ( + dual_basis_external_potential, jellium_model, jordan_wigner_dual_basis_hamiltonian, plane_wave_hamiltonian, ) +from openfermion.ops.operators import FermionOperator from openfermion.transforms.opconversions import jordan_wigner from openfermion.linalg import eigenspectrum, get_sparse_operator from openfermion.utils import Grid, is_hermitian class PlaneWaveHamiltonianTest(unittest.TestCase): + def test_dual_basis_external_potential_empty_geometry(self): + grid = Grid(dimensions=1, scale=1.0, length=2) + operator = dual_basis_external_potential(grid, geometry=[], spinless=True) + self.assertEqual(operator, FermionOperator()) + def test_plane_wave_hamiltonian_integration(self): length_set = [2, 3, 4] spinless_set = [True, False] diff --git a/src/openfermion/resource_estimates/pbc/thc/compute_thc_resources.py b/src/openfermion/resource_estimates/pbc/thc/compute_thc_resources.py index a91456528..3060b228f 100644 --- a/src/openfermion/resource_estimates/pbc/thc/compute_thc_resources.py +++ b/src/openfermion/resource_estimates/pbc/thc/compute_thc_resources.py @@ -18,6 +18,7 @@ from numpy.lib.scimath import arccos, arcsin from sympy import factorint from openfermion.resource_estimates.utils import QI +from openfermion.resource_estimates.pbc.df.compute_df_resources import compute_beta_for_resources from openfermion.resource_estimates.pbc.resources.data_types import ResourceEstimates from openfermion.resource_estimates.pbc.resources.qrom import QR3 @@ -48,6 +49,12 @@ def compute_cost( Returns: resources: THC factorized resource estimates """ + if beta is None: + num_kpts = int(np.prod(kmesh)) + beta = int(compute_beta_for_resources(num_spin_orbs, num_kpts, dE_for_qpe)) + else: + beta = int(beta) + # run once to determine stps parameter thc_costs = _compute_cost( n=num_spin_orbs, @@ -193,7 +200,7 @@ def _compute_cost( cs2 = 4 * n * (Nk - 1) # The QROM for the rotation angles the first time. - cs2a = QR3(Nk * (M + n / 2), n * beta)[1] + QI(Nk * (M + n / 2))[1] + cs2a = QR3(Nk * (M + n / 2), n * beta)[1] + QI(int(Nk * (M + n / 2)))[1] # The QROM for the rotation angles the second time. cs2b = QR3(Nk * M, n * beta)[1] + QI(Nk * M)[1]