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

enable check-untyped-defs mypy option #337

Merged
merged 1 commit into from
Oct 30, 2024
Merged
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
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ module-name = "ffsim._lib"
testpaths = ["tests"]

[tool.mypy]
check_untyped_defs = true
ignore_missing_imports = true
files = ["python/**/*.py", "python/**/*.pyi", "tests/**/*.py", "docs/**/*.py"]

Expand Down
7 changes: 5 additions & 2 deletions python/ffsim/_lib.pyi
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
from collections.abc import Iterator, Mapping
from collections.abc import Iterator, MutableMapping

import numpy as np

class FermionOperator(Mapping[tuple[tuple[bool, bool, int], ...], complex]):
class FermionOperator(MutableMapping[tuple[tuple[bool, bool, int], ...], complex]):
def __init__(
self, coeffs: dict[tuple[tuple[bool, bool, int], ...], complex]
) -> None: ...
def normal_ordered(self) -> "FermionOperator": ...
def conserves_particle_number(self) -> bool: ...
def conserves_spin_z(self) -> bool: ...
def many_body_order(self) -> int: ...
def copy(self) -> FermionOperator: ...
def __getitem__(self, key: tuple[tuple[bool, bool, int], ...]) -> complex: ...
def __setitem__(self, key: tuple[tuple[bool, bool, int], ...], complex) -> None: ...
def __delitem__(self, key: tuple[tuple[bool, bool, int], ...]) -> None: ...
def __contains__(self, key: object) -> bool: ...
def __iter__(self) -> Iterator[tuple[tuple[bool, bool, int], ...]]: ...
def __len__(self) -> int: ...
Expand Down
4 changes: 1 addition & 3 deletions python/ffsim/qiskit/gates/diag_coulomb.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,7 @@ def _define(self):

def inverse(self):
"""Inverse gate."""
return DiagCoulombEvolutionSpinlessJW(
self.norb, self.mat, -self.time, z_representation=self.z_representation
)
return DiagCoulombEvolutionSpinlessJW(self.norb, self.mat, -self.time)


def _diag_coulomb_evo_num_rep_spinless_jw(
Expand Down
2 changes: 1 addition & 1 deletion python/ffsim/variational/givens.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def __post_init__(self):
if len(self.thetas) != len(self.interaction_pairs):
raise ValueError(
"The number of thetas must equal the number of interaction pairs. "
f"Got {len(self.phis)} and {len(self.interaction_pairs)}."
f"Got {len(self.thetas)} and {len(self.interaction_pairs)}."
)
if self.phis is not None and len(self.phis) != len(self.interaction_pairs):
raise ValueError(
Expand Down
23 changes: 23 additions & 0 deletions python/ffsim/variational/hopgate.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import itertools
from dataclasses import dataclass
from typing import cast

import numpy as np

Expand Down Expand Up @@ -113,3 +114,25 @@ def from_parameters(
thetas=params,
final_orbital_rotation=final_orbital_rotation,
)

def _approx_eq_(self, other, rtol: float, atol: float) -> bool:
if isinstance(other, HopGateAnsatzOperator):
if self.norb != other.norb:
return False
if self.interaction_pairs != other.interaction_pairs:
return False
if not np.allclose(self.thetas, other.thetas, rtol=rtol, atol=atol):
return False
if (self.final_orbital_rotation is None) != (
other.final_orbital_rotation is None
):
return False
if self.final_orbital_rotation is not None:
return np.allclose(
cast(np.ndarray, self.final_orbital_rotation),
cast(np.ndarray, other.final_orbital_rotation),
rtol=rtol,
atol=atol,
)
return True
return NotImplemented
4 changes: 3 additions & 1 deletion python/ffsim/variational/num_num.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ def _apply_unitary_(
)

@staticmethod
def n_params(interaction_pairs: list[tuple[int, int]]) -> int:
def n_params(
interaction_pairs: tuple[list[tuple[int, int]], list[tuple[int, int]]],
) -> int:
"""Return the number of parameters of an ansatz with given settings.

Args:
Expand Down
5 changes: 5 additions & 0 deletions tests/python/molecular_data_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,15 @@ def test_molecular_data_run_methods():
mol_data.run_sci()
mol_data.run_fci()

assert isinstance(mol_data.mp2_energy, float)
np.testing.assert_allclose(mol_data.mp2_energy, -108.58852784026)
assert isinstance(mol_data.ccsd_energy, float)
np.testing.assert_allclose(mol_data.ccsd_energy, -108.5933309085008)
assert isinstance(mol_data.cisd_energy, float)
np.testing.assert_allclose(mol_data.cisd_energy, -108.5878344909782)
assert isinstance(mol_data.sci_energy, float)
np.testing.assert_allclose(mol_data.sci_energy, -108.59598682615388)
assert isinstance(mol_data.fci_energy, float)
np.testing.assert_allclose(mol_data.fci_energy, -108.595987350986)


Expand Down
2 changes: 1 addition & 1 deletion tests/python/operators/fermion_operator_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ def test_pow():
assert op**3 == op * op * op
assert pow(op, 2) == op * op
with pytest.raises(ValueError, match="mod argument"):
_ = pow(op, 2, 2)
_ = pow(op, 2, 2) # type: ignore


def test_normal_ordered():
Expand Down
10 changes: 5 additions & 5 deletions tests/python/states/bitstring_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
def test_indices_to_strings_string():
"""Test converting statevector indices to strings, output type string."""
norb = 3
nelec = 2
nelec: int | tuple[int, int] = 2
dim = ffsim.dim(norb, nelec)
strings = ffsim.indices_to_strings(range(dim), norb, nelec)
assert strings == [
Expand Down Expand Up @@ -84,7 +84,7 @@ def test_indices_to_strings_string():
def test_indices_to_strings_int():
"""Test converting statevector indices to strings, output type int."""
norb = 3
nelec = 2
nelec: int | tuple[int, int] = 2
dim = ffsim.dim(norb, nelec)
strings = ffsim.indices_to_strings(
range(dim), norb, nelec, bitstring_type=ffsim.BitstringType.INT
Expand Down Expand Up @@ -159,7 +159,7 @@ def test_indices_to_strings_int():
def test_indices_to_strings_bit_array():
"""Test converting statevector indices to strings, output type bit array."""
norb = 3
nelec = 2
nelec: int | tuple[int, int] = 2
dim = ffsim.dim(norb, nelec)
strings = ffsim.indices_to_strings(
range(dim), norb, nelec, bitstring_type=ffsim.BitstringType.BIT_ARRAY
Expand Down Expand Up @@ -536,7 +536,7 @@ def test_addresses_to_strings_large_address():
def test_strings_to_addresses_int():
"""Test converting statevector strings to addresses, input type int."""
norb = 3
nelec = 2
nelec: int | tuple[int, int] = 2
dim = ffsim.dim(norb, nelec)
indices = ffsim.strings_to_addresses(
[0b011, 0b101, 0b110],
Expand Down Expand Up @@ -571,7 +571,7 @@ def test_strings_to_addresses_int():
def test_strings_to_addresses_string():
"""Test converting statevector strings to indices, input type string."""
norb = 3
nelec = 2
nelec: int | tuple[int, int] = 2
dim = ffsim.dim(norb, nelec)
indices = ffsim.strings_to_addresses(
[
Expand Down
4 changes: 2 additions & 2 deletions tests/python/states/slater_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ def test_sample_slater_determinant_large():
shots = 5000
rotation_a = ffsim.random.random_unitary(norb, seed=rng)
rotation_b = ffsim.random.random_unitary(norb, seed=rng)
occupied_orbitals = [(0, 2, 3), (2, 4)]
occupied_orbitals = ((0, 2, 3), (2, 4))
rdm_a, rdm_b = ffsim.slater_determinant_rdms(
norb, occupied_orbitals, (rotation_a, rotation_b)
)
Expand All @@ -178,7 +178,7 @@ def test_sample_slater_determinant_restrict():
nelec = (4, 3)

shots = 10
occupied_orbitals = [(0, 2, 3, 5), (2, 3, 4)]
occupied_orbitals = ((0, 2, 3, 5), (2, 3, 4))
rdm_a, rdm_b = ffsim.slater_determinant_rdms(norb, occupied_orbitals)
samples = ffsim.sample_slater_determinant(
(rdm_a, rdm_b), norb, nelec, orbs=([1, 2, 5], [3, 4, 5]), shots=shots
Expand Down
6 changes: 1 addition & 5 deletions tests/python/variational/hopgate_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,4 @@ def ncycles(iterable, n):
interaction_pairs=interaction_pairs,
with_final_orbital_rotation=True,
)

np.testing.assert_allclose(roundtripped.thetas, operator.thetas)
np.testing.assert_allclose(
roundtripped.final_orbital_rotation, operator.final_orbital_rotation
)
assert ffsim.approx_eq(roundtripped, operator)
4 changes: 3 additions & 1 deletion tests/python/variational/num_num_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ def test_parameters_roundtrip():
thetas=(thetas_aa, thetas_ab),
)
assert (
operator.n_params(interaction_pairs=(pairs_aa, pairs_ab))
ffsim.NumNumAnsatzOpSpinBalanced.n_params(
interaction_pairs=(pairs_aa, pairs_ab)
)
== len(operator.to_parameters())
== 2 * norb
)
Expand Down
7 changes: 1 addition & 6 deletions tests/python/variational/uccsd_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,7 @@ def test_parameters_roundtrip():
nocc=nocc,
with_final_orbital_rotation=with_final_orbital_rotation,
)
np.testing.assert_allclose(roundtripped.t1, operator.t1)
np.testing.assert_allclose(roundtripped.t2, operator.t2)
if with_final_orbital_rotation:
np.testing.assert_allclose(
roundtripped.final_orbital_rotation, operator.final_orbital_rotation
)
assert ffsim.approx_eq(roundtripped, operator)


def test_approx_eq():
Expand Down
22 changes: 2 additions & 20 deletions tests/python/variational/ucj_spin_balanced_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,7 @@ def test_parameters_roundtrip_all_to_all():
n_reps=n_reps,
with_final_orbital_rotation=with_final_orbital_rotation,
)
np.testing.assert_allclose(
roundtripped.diag_coulomb_mats, operator.diag_coulomb_mats
)
np.testing.assert_allclose(
roundtripped.orbital_rotations, operator.orbital_rotations
)
if with_final_orbital_rotation:
np.testing.assert_allclose(
roundtripped.final_orbital_rotation, operator.final_orbital_rotation
)
assert ffsim.approx_eq(roundtripped, operator)


def test_parameters_roundtrip_interaction_pairs():
Expand All @@ -116,16 +107,7 @@ def test_parameters_roundtrip_interaction_pairs():
interaction_pairs=interaction_pairs,
with_final_orbital_rotation=with_final_orbital_rotation,
)
np.testing.assert_allclose(
roundtripped.diag_coulomb_mats, operator.diag_coulomb_mats
)
np.testing.assert_allclose(
roundtripped.orbital_rotations, operator.orbital_rotations
)
if with_final_orbital_rotation:
np.testing.assert_allclose(
roundtripped.final_orbital_rotation, operator.final_orbital_rotation
)
assert ffsim.approx_eq(roundtripped, operator)


def test_t_amplitudes_energy():
Expand Down
30 changes: 7 additions & 23 deletions tests/python/variational/ucj_spin_unbalanced_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,7 @@ def test_parameters_roundtrip_all_to_all():
n_reps=n_reps,
with_final_orbital_rotation=with_final_orbital_rotation,
)
np.testing.assert_allclose(
roundtripped.diag_coulomb_mats, operator.diag_coulomb_mats
)
np.testing.assert_allclose(
roundtripped.orbital_rotations, operator.orbital_rotations
)
if with_final_orbital_rotation:
np.testing.assert_allclose(
roundtripped.final_orbital_rotation, operator.final_orbital_rotation
)
assert ffsim.approx_eq(roundtripped, operator)


def test_parameters_roundtrip_interaction_pairs():
Expand All @@ -119,16 +110,7 @@ def test_parameters_roundtrip_interaction_pairs():
interaction_pairs=interaction_pairs,
with_final_orbital_rotation=with_final_orbital_rotation,
)
np.testing.assert_allclose(
roundtripped.diag_coulomb_mats, operator.diag_coulomb_mats
)
np.testing.assert_allclose(
roundtripped.orbital_rotations, operator.orbital_rotations
)
if with_final_orbital_rotation:
np.testing.assert_allclose(
roundtripped.final_orbital_rotation, operator.final_orbital_rotation
)
assert ffsim.approx_eq(roundtripped, operator)


def test_t_amplitudes_energy():
Expand All @@ -149,7 +131,7 @@ def test_t_amplitudes_energy():
mol_hamiltonian = mol_data.hamiltonian

# Construct UCJ operator
n_reps = 4
n_reps: int | tuple[int, int] = 4
operator = ffsim.UCJOpSpinUnbalanced.from_t_amplitudes(
ccsd.t2, t1=ccsd.t1, n_reps=n_reps
)
Expand Down Expand Up @@ -198,7 +180,8 @@ def test_t_amplitudes_random_n_reps():
nvrt_a = norb - nocc_a
nvrt_b = norb - nocc_b

for n_reps in [5, 50, (10, 5)]:
n_reps: int | tuple[int, int]
for n_reps in [5, 50, (10, 5)]: # type: ignore
t2aa = ffsim.random.random_t2_amplitudes(norb, nocc_a, seed=rng, dtype=float)
t2ab = rng.standard_normal((nocc_a, nocc_b, nvrt_a, nvrt_b))
t2bb = ffsim.random.random_t2_amplitudes(norb, nocc_b, seed=rng, dtype=float)
Expand All @@ -223,7 +206,8 @@ def test_t_amplitudes_zero_n_reps():
nvrt_a = norb - nocc_a
nvrt_b = norb - nocc_b

for n_reps in [5, 50, (10, 5)]:
n_reps: int | tuple[int, int]
for n_reps in [5, 50, (10, 5)]: # type: ignore
t2aa = np.zeros((nocc_a, nocc_a, nvrt_a, nvrt_a))
t2ab = np.zeros((nocc_a, nocc_b, nvrt_a, nvrt_b))
t2bb = np.zeros((nocc_b, nocc_b, nvrt_b, nvrt_b))
Expand Down
22 changes: 2 additions & 20 deletions tests/python/variational/ucj_spinless_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,16 +78,7 @@ def test_parameters_roundtrip_all_to_all():
n_reps=n_reps,
with_final_orbital_rotation=with_final_orbital_rotation,
)
np.testing.assert_allclose(
roundtripped.diag_coulomb_mats, operator.diag_coulomb_mats
)
np.testing.assert_allclose(
roundtripped.orbital_rotations, operator.orbital_rotations
)
if with_final_orbital_rotation:
np.testing.assert_allclose(
roundtripped.final_orbital_rotation, operator.final_orbital_rotation
)
assert ffsim.approx_eq(roundtripped, operator)


def test_parameters_roundtrip_interaction_pairs():
Expand All @@ -111,16 +102,7 @@ def test_parameters_roundtrip_interaction_pairs():
interaction_pairs=interaction_pairs,
with_final_orbital_rotation=with_final_orbital_rotation,
)
np.testing.assert_allclose(
roundtripped.diag_coulomb_mats, operator.diag_coulomb_mats
)
np.testing.assert_allclose(
roundtripped.orbital_rotations, operator.orbital_rotations
)
if with_final_orbital_rotation:
np.testing.assert_allclose(
roundtripped.final_orbital_rotation, operator.final_orbital_rotation
)
assert ffsim.approx_eq(roundtripped, operator)


def test_t_amplitudes_energy():
Expand Down
Loading