Skip to content
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
54 changes: 26 additions & 28 deletions recirq/fermi_hubbard/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import abc
from itertools import product
from numbers import Number
from numbers import Number, Real

import cirq
import numpy as np
Expand All @@ -30,8 +30,6 @@
ZigZagLayout
)

Real = Union[int, float]


@dataclass(init=False)
class Hamiltonian:
Expand Down Expand Up @@ -102,45 +100,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, Real):
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, Real):
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, Real):
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, Real):
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, Real):
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, Real):
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, Real):
return np.full(self.sites_count, self.mu_down)
return np.array(self.mu_down)

@property
def local_up_array(self):
Expand Down Expand Up @@ -257,7 +255,7 @@ def get_amplitudes(self, sites_count: int) -> np.ndarray:
if sites_count != len(self.amplitudes):
raise ValueError(f'Fixed single particle not compatible with '
f'{sites_count} sites')
return np.array(self.potential)
return np.array(self.amplitudes)

def _json_dict_(self):
return cirq.dataclass_json_dict(self)
Expand Down Expand Up @@ -638,10 +636,10 @@ def _potential_to_quadratic_hamiltonian(
) -> openfermion.QuadraticHamiltonian:
sites_count = len(potential)

if isinstance(j, Iterable):
j = np.array(j)
else:
if isinstance(j, Real):
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')
Expand Down
57 changes: 29 additions & 28 deletions recirq/kpz/experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"""

from typing import Iterator, List, Union, Optional
from numbers import Real

import cirq
import numpy as np
Expand All @@ -57,7 +58,7 @@
rng = np.random.default_rng()


def _dec_to_binary_right(d: Union[np.ndarray, int], n: int) -> Union[np.ndarray, int]:
def _dec_to_binary_right(d: Union[np.ndarray, Real], n: int) -> Union[np.ndarray, Real]:
i = np.arange(n // 2)
return (
np.floor(np.outer(d, 1 / 2**i)) - np.floor(np.outer(d, 1 / 2 ** (i + 1))) * 2
Expand Down Expand Up @@ -103,46 +104,46 @@ def __init__(self, prob_right: np.ndarray, initial_states: np.ndarray):
self.skewness = self._skewness()
self.kurtosis = self._kurtosis()

def _mean(self) -> float:
def _mean(self) -> Real:
return (
self.transferred_magnetization_probs @ self.transferred_magnetization_vals
)

def _variance(self) -> float:
def _variance(self) -> Real:
return (
self.transferred_magnetization_probs
@ (self.transferred_magnetization_vals - self.mean) ** 2
)

def _skewness(self) -> float:
def _skewness(self) -> Real:
return (
self.transferred_magnetization_probs
@ (self.transferred_magnetization_vals - self.mean) ** 3
/ self.variance ** (3 / 2)
)

def _kurtosis(self) -> float:
def _kurtosis(self) -> Real:
return (
self.transferred_magnetization_probs
@ (self.transferred_magnetization_vals - self.mean) ** 4
/ self.variance**2
- 3
)

def _mean_excluding_i(self, i: int) -> float:
def _mean_excluding_i(self, i: int) -> Real:
p = np.mean(
np.delete(self.transferred_magnetization_probs_all, i, axis=0), axis=0
)
return p @ self.transferred_magnetization_vals

def _variance_excluding_i(self, i: int) -> float:
def _variance_excluding_i(self, i: int) -> Real:
p = np.mean(
np.delete(self.transferred_magnetization_probs_all, i, axis=0), axis=0
)
mean_i = p @ self.transferred_magnetization_vals
return p @ (self.transferred_magnetization_vals - mean_i) ** 2

def _skew_excluding_i(self, i: int) -> float:
def _skew_excluding_i(self, i: int) -> Real:
p = np.mean(
np.delete(self.transferred_magnetization_probs_all, i, axis=0), axis=0
)
Expand All @@ -154,7 +155,7 @@ def _skew_excluding_i(self, i: int) -> float:
/ variance_i ** (3 / 2)
)

def _kurtosis_excluding_i(self, i: int) -> float:
def _kurtosis_excluding_i(self, i: int) -> Real:
p = np.mean(
np.delete(self.transferred_magnetization_probs_all, i, axis=0), axis=0
)
Expand All @@ -165,7 +166,7 @@ def _kurtosis_excluding_i(self, i: int) -> float:
- 3
)

def jackknife_mean(self) -> float:
def jackknife_mean(self) -> Real:
r"""Compute the statistical uncertainty of the mean using the remove-one jackknife.
If there is only one initial state (for example if $\mu = \infty$), zero uncertainty
is returned.
Expand All @@ -175,7 +176,7 @@ def jackknife_mean(self) -> float:
mean_i = [self._mean_excluding_i(i) for i in range(self.num_initial_states)]
return np.std(mean_i) * np.sqrt(self.num_initial_states - 1)

def jackknife_variance(self) -> float:
def jackknife_variance(self) -> Real:
r"""Compute the statistical uncertainty of the variance using the remove-one jackknife.
If there is only one initial state (for example if $\mu = \infty$), zero uncertainty
is returned.
Expand All @@ -187,7 +188,7 @@ def jackknife_variance(self) -> float:
]
return np.std(variance_i) * np.sqrt(self.num_initial_states - 1)

def jackknife_skew(self) -> float:
def jackknife_skew(self) -> Real:
r"""Compute the statistical uncertainty of the skewness using the remove-one jackknife.
If there is only one initial state (for example if $\mu = \infty$), zero uncertainty
is returned.
Expand All @@ -197,7 +198,7 @@ def jackknife_skew(self) -> float:
skew_i = [self._skew_excluding_i(i) for i in range(self.num_initial_states)]
return np.std(skew_i) * np.sqrt(self.num_initial_states - 1)

def jackknife_kurtosis(self) -> float:
def jackknife_kurtosis(self) -> Real:
r"""Compute the statistical uncertainty of the kurtosis using the remove-one jackknife.
If there is only one initial state (for example if $\mu = \infty$), zero uncertainty
is returned.
Expand Down Expand Up @@ -276,35 +277,35 @@ def _transferred_magnetization(self) -> np.ndarray:
initial = np.outer(self.num_right_initial, np.ones(num_reps, dtype=int))
return 2 * (final - initial)

def _mean(self) -> float:
def _mean(self) -> Real:
return np.mean(self.transferred_magnetization.flatten())

def _variance(self) -> float:
def _variance(self) -> Real:
return np.var(self.transferred_magnetization.flatten())

def _skewness(self) -> float:
def _skewness(self) -> Real:
return sstats.skew(self.transferred_magnetization.flatten())

def _kurtosis(self) -> float:
def _kurtosis(self) -> Real:
return sstats.kurtosis(self.transferred_magnetization.flatten(), fisher=True)

def _mean_excluding_i(self, i: int, axis: Optional[int] = 0) -> float:
def _mean_excluding_i(self, i: int, axis: Optional[int] = 0) -> Real:
tm = np.delete(self.transferred_magnetization, i, axis=axis)
return np.mean(tm.flatten())

def _variance_excluding_i(self, i: int, axis: Optional[int] = 0) -> float:
def _variance_excluding_i(self, i: int, axis: Optional[int] = 0) -> Real:
tm = np.delete(self.transferred_magnetization, i, axis=axis)
return np.var(tm.flatten())

def _skew_excluding_i(self, i: int, axis: Optional[int] = 0) -> float:
def _skew_excluding_i(self, i: int, axis: Optional[int] = 0) -> Real:
tm = np.delete(self.transferred_magnetization, i, axis=axis)
return sstats.skew(tm.flatten())

def _kurtosis_excluding_i(self, i: int, axis: Optional[int] = 0) -> float:
def _kurtosis_excluding_i(self, i: int, axis: Optional[int] = 0) -> Real:
tm = np.delete(self.transferred_magnetization, i, axis=axis)
return sstats.kurtosis(tm.flatten(), fisher=True)

def jackknife_mean(self) -> float:
def jackknife_mean(self) -> Real:
"""Compute the statistical uncertainty of the mean using the remove-one jackknife.
In the case that there is only one initial state, use the standard deviation of
the measured transferred magnetization to estimate the uncertainty instead.
Expand All @@ -315,7 +316,7 @@ def jackknife_mean(self) -> float:
mean_i = [self._mean_excluding_i(i) for i in range(self.num_initial_states)]
return np.std(mean_i) * np.sqrt(self.num_initial_states - 1)

def jackknife_variance(self) -> float:
def jackknife_variance(self) -> Real:
"""Compute the statistical uncertainty of the variance using the remove-one jackknife.
One initial state is removed, and the variation depending on which state is removed
is used to estimate the uncertainty. In the case that there is only one initial state,
Expand All @@ -330,7 +331,7 @@ def jackknife_variance(self) -> float:
variance_i = [self._variance_excluding_i(i, axis=axis) for i in range(tot)]
return np.std(variance_i) * np.sqrt(tot - 1)

def jackknife_skew(self) -> float:
def jackknife_skew(self) -> Real:
"""Compute the statistical uncertainty of the skewness using the remove-one jackknife.
One initial state is removed, and the variation depending on which state is removed
is used to estimate the uncertainty. In the case that there is only one initial state,
Expand All @@ -345,7 +346,7 @@ def jackknife_skew(self) -> float:
skew_i = [self._skew_excluding_i(i, axis=axis) for i in range(tot)]
return np.std(skew_i) * np.sqrt(tot - 1)

def jackknife_kurtosis(self) -> float:
def jackknife_kurtosis(self) -> Real:
"""Compute the statistical uncertainty of the kurtosis using the remove-one jackknife.
One initial state is removed, and the variation depending on which state is removed
is used to estimate the uncertainty. In the case that there is only one initial state,
Expand Down Expand Up @@ -409,10 +410,10 @@ class KPZExperiment:
def __init__(
self,
num_cycles: int,
mu: float,
mu: Real,
num_init_states: int,
theta: float,
phi: float,
theta: Real,
phi: Real,
num_qubits: Optional[Union[None, int]] = None,
):
"""
Expand Down
9 changes: 5 additions & 4 deletions recirq/lattice_gauge/lattice_gauge_experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# limitations under the License.

from collections.abc import Sequence
from numbers import Real
from typing import Any

import cirq
Expand All @@ -25,7 +26,7 @@
from recirq.lattice_gauge.lattice_gauge_grid import QubitNeighbor, LGTGrid

def variational_ground_state_minimal_qubits_cols(
grid: LGTGrid, x_ancillary_qubits_in_cols: list[set[cirq.GridQubit]], theta: float
grid: LGTGrid, x_ancillary_qubits_in_cols: list[set[cirq.GridQubit]], theta: Real
) -> list[cirq.Moment]:
"""Moments to prepare the state from the toric code variational ansatz for two columns.

Expand Down Expand Up @@ -63,7 +64,7 @@ def variational_ground_state_minimal_qubits_cols(


def variational_ground_state_minimal_qubits(
grid: LGTGrid, theta: float, extra_x_plaquette_indices: list[tuple[int, int]] = []
grid: LGTGrid, theta: Real, extra_x_plaquette_indices: list[tuple[int, int]] = []
) -> list[cirq.Moment]:
"""Moments to prepare the state from the toric code variation ansatz.

Expand Down Expand Up @@ -585,7 +586,7 @@ def x_plaquette_bitstrings(data: np.array, grid: LGTGrid) -> np.ndarray:

def cnot_on_layer(
pairs_list: Sequence[tuple[cirq.GridQubit, cirq.GridQubit]],
depolarization_probability: float | dict | None = None,
depolarization_probability: Real | dict | None = None,
) -> Sequence[cirq.Moment]:
"""Outputs a list of moments for CNOT between two lists, in terms of CZ gates.

Expand All @@ -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, 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),
Expand Down
Loading
Loading