From 74ba10dc7aefaa2699e18cbf268f1b69e78def13 Mon Sep 17 00:00:00 2001 From: Rahil Jain <51580546+RahilJain1366@users.noreply.github.com> Date: Sun, 23 Nov 2025 11:30:33 -0600 Subject: [PATCH] change from float to numbers.real --- recirq/fermi_hubbard/parameters.py | 111 +++++++++--------- .../lattice_gauge/lattice_gauge_experiment.py | 3 +- recirq/optimize/mgd_test.py | 5 +- recirq/optimize/mpg_test.py | 5 +- recirq/qcqmc/optimize_wf.py | 3 +- 5 files changed, 66 insertions(+), 61 deletions(-) diff --git a/recirq/fermi_hubbard/parameters.py b/recirq/fermi_hubbard/parameters.py index 29f4131b..43f6497c 100644 --- a/recirq/fermi_hubbard/parameters.py +++ b/recirq/fermi_hubbard/parameters.py @@ -18,7 +18,7 @@ import abc from itertools import product -from numbers import Number +from numbers import Number, Real as NumbersReal import cirq import numpy as np @@ -30,7 +30,8 @@ ZigZagLayout ) -Real = Union[int, float] +# Type alias for real numbers (supports int, float, np.float32, np.float64, etc.) +RealNumber = Union[int, float] @dataclass(init=False) @@ -61,23 +62,23 @@ class Hamiltonian: mu_down: Local chemical potential for spin-down states μ_↓. """ sites_count: int - j: Union[Real, Tuple[Real]] - u: Union[Real, Tuple[Real]] - v: Union[Real, Tuple[Real]] - local_charge: Union[Real, Tuple[Real]] - local_spin: Union[Real, Tuple[Real]] - mu_up: Union[Real, Tuple[Real]] - mu_down: Union[Real, Tuple[Real]] + j: Union[RealNumber, Tuple[RealNumber]] + u: Union[RealNumber, Tuple[RealNumber]] + v: Union[RealNumber, Tuple[RealNumber]] + local_charge: Union[RealNumber, Tuple[RealNumber]] + local_spin: Union[RealNumber, Tuple[RealNumber]] + mu_up: Union[RealNumber, Tuple[RealNumber]] + mu_down: Union[RealNumber, Tuple[RealNumber]] def __init__(self, *, sites_count: int, - j: Union[Real, Iterable[Real]], - u: Union[Real, Iterable[Real]], - v: Union[Real, Iterable[Real]] = 0, - local_charge: Union[Real, Iterable[Real]] = 0, - local_spin: Union[Real, Iterable[Real]] = 0, - mu_up: Union[Real, Iterable[Real]] = 0, - mu_down: Union[Real, Iterable[Real]] = 0, + j: Union[RealNumber, Iterable[RealNumber]], + u: Union[RealNumber, Iterable[RealNumber]], + v: Union[RealNumber, Iterable[RealNumber]] = 0, + local_charge: Union[RealNumber, Iterable[RealNumber]] = 0, + local_spin: Union[RealNumber, Iterable[RealNumber]] = 0, + mu_up: Union[RealNumber, Iterable[RealNumber]] = 0, + mu_down: Union[RealNumber, Iterable[RealNumber]] = 0, ) -> None: self.sites_count = sites_count self.j = _iterable_to_tuple(j) @@ -102,45 +103,45 @@ def interactions_count(self) -> int: @property def j_array(self) -> np.ndarray: - if isinstance(self.j, tuple): - return np.array(self.j) - return np.full(self.interactions_count, self.j) + if isinstance(self.j, NumbersReal): + return np.full(self.interactions_count, self.j) + return np.array(self.j) @property def u_array(self) -> np.ndarray: - if isinstance(self.u, tuple): - return np.array(self.u) - return np.full(self.sites_count, self.u) + if isinstance(self.u, NumbersReal): + return np.full(self.sites_count, self.u) + return np.array(self.u) @property def v_array(self) -> np.ndarray: - if isinstance(self.v, tuple): - return np.array(self.v) - return np.full(self.interactions_count, self.v) + if isinstance(self.v, NumbersReal): + return np.full(self.interactions_count, self.v) + return np.array(self.v) @property def local_charge_array(self) -> np.ndarray: - if isinstance(self.local_charge, tuple): - return np.array(self.local_charge) - return np.full(self.sites_count, self.local_charge) + if isinstance(self.local_charge, NumbersReal): + return np.full(self.sites_count, self.local_charge) + return np.array(self.local_charge) @property def local_spin_array(self) -> np.ndarray: - if isinstance(self.local_spin, tuple): - return np.array(self.local_spin) - return np.full(self.sites_count, self.local_spin) + if isinstance(self.local_spin, NumbersReal): + return np.full(self.sites_count, self.local_spin) + return np.array(self.local_spin) @property def mu_up_array(self) -> np.ndarray: - if isinstance(self.mu_up, tuple): - return np.array(self.mu_up) - return np.full(self.sites_count, self.mu_up) + if isinstance(self.mu_up, NumbersReal): + return np.full(self.sites_count, self.mu_up) + return np.array(self.mu_up) @property def mu_down_array(self) -> np.ndarray: - if isinstance(self.mu_down, tuple): - return np.array(self.mu_down) - return np.full(self.sites_count, self.mu_down) + if isinstance(self.mu_down, NumbersReal): + return np.full(self.sites_count, self.mu_down) + return np.array(self.mu_down) @property def local_up_array(self): @@ -311,11 +312,11 @@ class PhasedGaussianSingleParticle(SingleParticle): interval, m = position * (sites_count - 1) + 1. """ - k: Real - sigma: Real - position: Real + k: RealNumber + sigma: RealNumber + position: RealNumber - def __init__(self, *, k: Real, sigma: Real, position: Real) -> None: + def __init__(self, *, k: RealNumber, sigma: RealNumber, position: RealNumber) -> None: self.k = k self.sigma = sigma self.position = position @@ -356,7 +357,7 @@ def get_potential(self, sites_count: int) -> np.ndarray: def as_quadratic_hamiltonian(self, sites_count: int, - j: Union[Real, Iterable[Real]], + j: Union[RealNumber, Iterable[RealNumber]], ) -> openfermion.QuadraticHamiltonian: """Creates a nonintercting Hamiltonian H_0 that describes particle in a trapping potential: @@ -383,9 +384,9 @@ def as_quadratic_hamiltonian(self, class FixedTrappingPotential(TrappingPotential): """Fixed array describing trapping potential.""" particles: int - potential: Tuple[Real] + potential: Tuple[RealNumber] - def __init__(self, *, particles: int, potential: Iterable[Real]) -> None: + def __init__(self, *, particles: int, potential: Iterable[RealNumber]) -> None: self.particles = particles self.potential = tuple(potential) @@ -450,15 +451,15 @@ class GaussianTrappingPotential(TrappingPotential): """ particles: int - center: Real - sigma: Real - scale: Real + center: RealNumber + sigma: RealNumber + scale: RealNumber def __init__(self, *, particles: int, - center: Real, - sigma: Real, - scale: Real) -> None: + center: RealNumber, + sigma: RealNumber, + scale: RealNumber) -> None: self.particles = particles self.center = center self.sigma = sigma @@ -634,14 +635,14 @@ def gaussian(x): def _potential_to_quadratic_hamiltonian( potential: np.ndarray, - j: Union[Real, Iterable[Real]] + j: Union[RealNumber, Iterable[RealNumber]] ) -> openfermion.QuadraticHamiltonian: sites_count = len(potential) - if isinstance(j, Iterable): - j = np.array(j) - else: + if isinstance(j, NumbersReal): j = np.full(sites_count - 1, j) + else: + j = np.array(j) if len(j) != sites_count - 1: raise ValueError('Hopping coefficient size incompatible with potential') @@ -662,4 +663,4 @@ def _potential_to_quadratic_hamiltonian( def _iterable_to_tuple(value: Any) -> Any: - return tuple(value) if isinstance(value, Iterable) else value + return value if isinstance(value, NumbersReal) else tuple(value) diff --git a/recirq/lattice_gauge/lattice_gauge_experiment.py b/recirq/lattice_gauge/lattice_gauge_experiment.py index 5342ca58..bfba2f84 100644 --- a/recirq/lattice_gauge/lattice_gauge_experiment.py +++ b/recirq/lattice_gauge/lattice_gauge_experiment.py @@ -13,6 +13,7 @@ # limitations under the License. from collections.abc import Sequence +import numbers from typing import Any import cirq @@ -601,7 +602,7 @@ def cnot_on_layer( cirq.Moment(cirq.CZ.on(qc, qt) for qc, qt in pairs_list), cirq.Moment(cirq.H.on_each(pair[1] for pair in pairs_list)), ] - elif isinstance(depolarization_probability, float): + elif isinstance(depolarization_probability, numbers.Real): return [ cirq.Moment(cirq.H.on_each(pair[1] for pair in pairs_list)), cirq.Moment(cirq.CZ.on(qc, qt) for qc, qt in pairs_list), diff --git a/recirq/optimize/mgd_test.py b/recirq/optimize/mgd_test.py index 6cd08e38..f799ba83 100644 --- a/recirq/optimize/mgd_test.py +++ b/recirq/optimize/mgd_test.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import numbers import numpy as np from recirq.optimize.mgd import model_gradient_descent @@ -72,7 +73,7 @@ def test_model_gradient_descent_limited_iterations(): max_iterations=15) assert isinstance(result.x, np.ndarray) - assert isinstance(result.fun, float) + assert isinstance(result.fun, numbers.Real) assert result.nit == 15 @@ -90,5 +91,5 @@ def test_model_gradient_descent_limited_evaluations(): max_evaluations=15) assert isinstance(result.x, np.ndarray) - assert isinstance(result.fun, float) + assert isinstance(result.fun, numbers.Real) assert result.nfev == 12 diff --git a/recirq/optimize/mpg_test.py b/recirq/optimize/mpg_test.py index 82f41bfe..2e559b6a 100644 --- a/recirq/optimize/mpg_test.py +++ b/recirq/optimize/mpg_test.py @@ -13,6 +13,7 @@ # limitations under the License. import numpy as np +import numbers from recirq.optimize.mpg import model_policy_gradient @@ -81,7 +82,7 @@ def test_model_policy_gradient_limited_iterations(): ) assert isinstance(result.x, np.ndarray) - assert isinstance(result.fun, float) + assert isinstance(result.fun, numbers.Real) assert result.nit == 15 @@ -103,7 +104,7 @@ def test_model_policy_gradient_limited_evaluations(): ) assert isinstance(result.x, np.ndarray) - assert isinstance(result.fun, float) + assert isinstance(result.fun, numbers.Real) assert result.nfev == 91 diff --git a/recirq/qcqmc/optimize_wf.py b/recirq/qcqmc/optimize_wf.py index 47308b7f..9b88a0e0 100644 --- a/recirq/qcqmc/optimize_wf.py +++ b/recirq/qcqmc/optimize_wf.py @@ -15,6 +15,7 @@ import copy import itertools +import numbers from typing import Dict, List, Mapping, Optional, Sequence, Tuple import cirq @@ -295,7 +296,7 @@ def get_energy_and_check_sanity( ansatz_energy = np.real_if_close( (np.conj(circuit_wf) @ sparse_ham @ circuit_wf) ).item() - assert isinstance(ansatz_energy, float) + assert isinstance(ansatz_energy, numbers.Real) fqe_energy = np.real(fqe_wf.expectationValue(fqe_ham) + e_core) np.testing.assert_array_almost_equal(ansatz_energy, fqe_energy)