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
8 changes: 2 additions & 6 deletions src/pyrecest/_backend/jax/random/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,7 @@ def _validate_multivariate_normal_tol(tol):
return tol_value


def _validate_and_classify_multivariate_normal_cov(
cov, mean_dim, *, check_valid, tol
):
def _validate_and_classify_multivariate_normal_cov(cov, mean_dim, *, check_valid, tol):
"""Validate a covariance and identify numerically rank-deficient inputs."""

cov = _LEGACY._validate_normal_parameter(cov, "cov")
Expand All @@ -77,9 +75,7 @@ def _validate_and_classify_multivariate_normal_cov(
_warnings.warn(message, RuntimeWarning, stacklevel=3)

scale = _LEGACY._jnp.max(_LEGACY._jnp.abs(eigenvalues))
rank_tolerance = (
_LEGACY._jnp.finfo(cov_float.dtype).eps * max(mean_dim, 1) * scale
)
rank_tolerance = _LEGACY._jnp.finfo(cov_float.dtype).eps * max(mean_dim, 1) * scale
requires_svd = bool(_LEGACY._jnp.any(eigenvalues <= rank_tolerance))
return cov, requires_svd

Expand Down
10 changes: 7 additions & 3 deletions src/pyrecest/_backend/numpy/linalg.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,20 @@

from .._shared_numpy.linalg import (
_normalize_fractional_matrix_power_exponent,
fractional_matrix_power as _fractional_matrix_power,
)
from .._shared_numpy.linalg import fractional_matrix_power as _fractional_matrix_power
from .._shared_numpy.linalg import (
is_single_matrix_pd,
logm as _logm,
)
from .._shared_numpy.linalg import logm as _logm
from .._shared_numpy.linalg import (
polar,
qr,
quadratic_assignment,
solve,
solve_sylvester,
sqrtm as _sqrtm,
)
from .._shared_numpy.linalg import sqrtm as _sqrtm


def _empty_zero_by_zero_matrix_result(value):
Expand Down
4 changes: 1 addition & 3 deletions src/pyrecest/_backend/pytorch/random.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,7 @@ def _validate_randint_array_dtype_bounds(low, high, dtype):
# representable by the output dtype, as in randint(255, 256, dtype=uint8).
# For int64, input tensors cannot represent max + 1, so every accepted high
# value is already within the valid endpoint range.
if dtype != _torch.int64 and bool(
_torch.any(high_int64 > dtype_info.max + 1)
):
if dtype != _torch.int64 and bool(_torch.any(high_int64 > dtype_info.max + 1)):
raise ValueError(f"high is out of bounds for {dtype_name}")


Expand Down
32 changes: 8 additions & 24 deletions src/pyrecest/_backend/pytorch/random/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,7 @@ def _sample_array_randint_exactly(low, high, dtype, generator):
bounds = torch.stack((flat_low, flat_high), dim=1)
unique_bounds, inverse = torch.unique(bounds, dim=0, return_inverse=True)
order = torch.argsort(inverse)
counts = torch.bincount(
inverse, minlength=unique_bounds.shape[0]
).tolist()
counts = torch.bincount(inverse, minlength=unique_bounds.shape[0]).tolist()

offset = 0
for bound_pair, count in zip(unique_bounds, counts):
Expand Down Expand Up @@ -234,9 +232,7 @@ def _randint_array_with_wide_arithmetic(low, high, size, *args, **kwargs):
unexpected = ", ".join(sorted(sampling_kwargs))
raise TypeError(f"Unexpected keyword argument(s): {unexpected}")

result = _sample_array_randint_exactly(
low, high, requested_dtype, generator
)
result = _sample_array_randint_exactly(low, high, requested_dtype, generator)
if out is not None:
out.copy_(result)
return out
Expand Down Expand Up @@ -284,9 +280,7 @@ def uniform(low=0.0, high=1.0, size=None, dtype=None):
span = high - low
if bool(torch.any(~torch.isfinite(span))):
raise OverflowError(_UNIFORM_RANGE_ERROR)
return span * torch.rand(
size, dtype=arithmetic_dtype, device=device
) + low
return span * torch.rand(size, dtype=arithmetic_dtype, device=device) + low


def _singular_multivariate_normal_factor(mean, cov, tol):
Expand Down Expand Up @@ -321,15 +315,11 @@ def _singular_multivariate_normal_factor(mean, cov, tol):
return None

scale = torch.max(torch.abs(eigenvalues))
rank_tolerance = (
torch.finfo(cov.dtype).eps * max(mean.shape[0], 1) * scale
)
rank_tolerance = torch.finfo(cov.dtype).eps * max(mean.shape[0], 1) * scale
if bool(torch.all(eigenvalues > rank_tolerance)):
return None

factor = eigenvectors * torch.sqrt(
torch.clamp(eigenvalues, min=0.0)
).unsqueeze(0)
factor = eigenvectors * torch.sqrt(torch.clamp(eigenvalues, min=0.0)).unsqueeze(0)
return mean, factor


Expand All @@ -355,21 +345,15 @@ def multivariate_normal(mean, cov, size=None, *args, **kwargs):
tol = _validate_multivariate_normal_tol(tol)

try:
return _LEGACY.multivariate_normal(
mean, cov, size=size, *args, **kwargs
)
return _LEGACY.multivariate_normal(mean, cov, size=size, *args, **kwargs)
except ValueError:
if args or kwargs:
raise
singular_parameters = _singular_multivariate_normal_factor(
mean, cov, tol
)
singular_parameters = _singular_multivariate_normal_factor(mean, cov, tol)
if singular_parameters is None:
raise
singular_mean, factor = singular_parameters
return _sample_singular_multivariate_normal(
singular_mean, factor, size
)
return _sample_singular_multivariate_normal(singular_mean, factor, size)


__all__ = sorted(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,7 @@ def gamma(a, out=None):
)
reflection_sine = torch_module.sin(torch_module.pi * reflection_values)
reflected_log_abs = (
torch_module.log(
torch_module.full_like(reflection_values, torch_module.pi)
)
torch_module.log(torch_module.full_like(reflection_values, torch_module.pi))
- torch_module.log(torch_module.abs(reflection_sine))
- torch_module.special.gammaln(1 - reflection_values)
)
Expand Down Expand Up @@ -284,9 +282,7 @@ def array_equal(a, b, equal_nan=False):

comparison = torch_module.eq(a, b)
if dtype.is_floating_point or dtype.is_complex:
comparison = comparison | (
torch_module.isnan(a) & torch_module.isnan(b)
)
comparison = comparison | (torch_module.isnan(a) & torch_module.isnan(b))
return bool(torch_module.all(comparison))

array_equal.__name__ = getattr(original_array_equal, "__name__", "array_equal")
Expand Down
10 changes: 2 additions & 8 deletions src/pyrecest/calibration/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@
"times_s",
}
)
_ORIGINAL_AGGREGATE_SUMMARY_METRIC_ATTR = (
"_pyrecest_original_aggregate_summary_metric"
)
_ORIGINAL_AGGREGATE_SUMMARY_METRIC_ATTR = "_pyrecest_original_aggregate_summary_metric"
_ORIGINAL_AGGREGATE_TIME_OFFSET_SWEEPS_ATTR = (
"_pyrecest_original_aggregate_time_offset_sweeps"
)
Expand Down Expand Up @@ -190,9 +188,7 @@ def _aggregate_summary_metric(
_bias_module._as_nonnegative_finite_float,
)

_base_bias_as_numeric_array = getattr(
_bias_module, _ORIGINAL_BIAS_NUMERIC_ARRAY_ATTR
)
_base_bias_as_numeric_array = getattr(_bias_module, _ORIGINAL_BIAS_NUMERIC_ARRAY_ATTR)
_base_bias_as_nonnegative_int = getattr(
_bias_module, _ORIGINAL_BIAS_NONNEGATIVE_INT_ATTR
)
Expand Down Expand Up @@ -244,8 +240,6 @@ def _as_numeric_vector(value: Any, name: str) -> np.ndarray:
TimeOffsetFitResult,
_aggregate_std_metric,
_validate_error_metric,
)
from .time_offset import ( # noqa: E402
apply_time_offset,
fit_time_offset,
interpolate_reference_values,
Expand Down
4 changes: 1 addition & 3 deletions src/pyrecest/calibration/_time_offset_grid_extreme_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@
_ORIGINAL_ATTR = "_pyrecest_original_make_offset_grid"


def _extreme_range_grid(
min_s: float, max_s: float, step_s: float
) -> np.ndarray:
def _extreme_range_grid(min_s: float, max_s: float, step_s: float) -> np.ndarray:
original = getattr(_time_offset, _ORIGINAL_ATTR)
min_s = _time_offset._as_finite_float(min_s, "min_s")
max_s = _time_offset._as_finite_float(max_s, "max_s")
Expand Down
7 changes: 2 additions & 5 deletions src/pyrecest/calibration/_time_offset_stable_statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ def _scaled_weighted_average(values: np.ndarray, weights: np.ndarray) -> float:
weight_scale = float(np.max(weights, initial=0.0))
normalized_weights = weights / weight_scale
return float(
value_scale
* np.average(values / value_scale, weights=normalized_weights)
value_scale * np.average(values / value_scale, weights=normalized_weights)
)


Expand Down Expand Up @@ -87,9 +86,7 @@ def _stable_aggregate_summary_metric(
normalized_weights = weights / np.max(weights)
return float(
scale
* np.sqrt(
np.average((values / scale) ** 2, weights=normalized_weights)
)
* np.sqrt(np.average((values / scale) ** 2, weights=normalized_weights))
)
return _scaled_weighted_average(values, weights)

Expand Down
1 change: 0 additions & 1 deletion src/pyrecest/distributions/abstract_custom_distribution.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

from .abstract_distribution_type import AbstractDistributionType


_INVALID_INTEGRAL_TYPES = (
bool,
np.bool_,
Expand Down
8 changes: 6 additions & 2 deletions src/pyrecest/distributions/abstract_dirac_distribution.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,25 @@
# pylint: disable=redefined-builtin,no-name-in-module,no-member
from pyrecest.backend import (
all,
)
from pyrecest.backend import any as backend_any
from pyrecest.backend import (
apply_along_axis,
arange,
argmax,
asarray,
)
from pyrecest.backend import any as backend_any
from pyrecest.backend import copy as backend_copy
from pyrecest.backend import max as backend_max
from pyrecest.backend import (
exp,
int32,
int64,
isclose,
isfinite,
log,
)
from pyrecest.backend import max as backend_max
from pyrecest.backend import (
ones,
random,
reshape,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
from ..nonperiodic.gaussian_distribution import GaussianDistribution
from .abstract_hypercylindrical_distribution import AbstractHypercylindricalDistribution


_INVALID_SCALAR_TYPES = (
str,
bytes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@
from pyrecest.distributions.nonperiodic.custom_linear_distribution import (
CustomLinearDistribution,
)
from pyrecest.distributions.nonperiodic.gaussian_distribution import GaussianDistribution
from pyrecest.distributions.nonperiodic.gaussian_distribution import (
GaussianDistribution,
)
from pyrecest.distributions.nonperiodic.linear_mixture import LinearMixture


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,9 @@ def pdf(self, xs, m: Union[int, int32, int64] = 3):
)

# Evaluate the Gaussian factor without leaving the active backend.
evals = GaussianDistribution(
self.mu, self.C, check_validity=False
).pdf(xs_wrapped)
evals = GaussianDistribution(self.mu, self.C, check_validity=False).pdf(
xs_wrapped
)

# sum evaluations for the wrapped dimensions
summed_evals = sum(evals.reshape(-1, (2 * m + 1) ** self.bound_dim), axis=1)
Expand Down
12 changes: 3 additions & 9 deletions src/pyrecest/distributions/cart_prod/se2_pwn_distribution.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,7 @@ def covariance4D_numerical(self, n_samples=10000):
array of shape (4, 4)
"""
s = _np.asarray(self.sample(n_samples))
big_s = _np.column_stack(
[_np.cos(s[:, 0]), _np.sin(s[:, 0]), s[:, 1], s[:, 2]]
)
big_s = _np.column_stack([_np.cos(s[:, 0]), _np.sin(s[:, 0]), s[:, 1], s[:, 2]])
return array(_np.cov(big_s.T))

@staticmethod
Expand Down Expand Up @@ -186,12 +184,8 @@ def from_samples(samples):
c = _np.zeros((3, 3))
c[0, 0] = -2.0 * _np.log(m1abs)
factor = _np.exp(0.5 * c[0, 0])
c[0, 1] = (
-c4[0, 2] * _np.sin(mu[0]) + c4[1, 2] * _np.cos(mu[0])
) * factor
c[0, 2] = (
-c4[0, 3] * _np.sin(mu[0]) + c4[1, 3] * _np.cos(mu[0])
) * factor
c[0, 1] = (-c4[0, 2] * _np.sin(mu[0]) + c4[1, 2] * _np.cos(mu[0])) * factor
c[0, 2] = (-c4[0, 3] * _np.sin(mu[0]) + c4[1, 3] * _np.cos(mu[0])) * factor
c[1, 0] = c[0, 1]
c[2, 0] = c[0, 2]
c[1:3, 1:3] = c4[2:4, 2:4]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
from numbers import Integral

import numpy as np
from pyrecest.backend import abs as backend_abs
from pyrecest.backend import (
abs as backend_abs,
all,
arctan2,
array,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,7 @@ def pdf(self, xs):
positive_rate = self.lambda_ * self.kappa
negative_rate = self.lambda_ / self.kappa
positive_component = _wrapped_exponential_density(positive_rate, xs)
negative_component = _wrapped_exponential_density(
negative_rate, 2.0 * pi - xs
)
negative_component = _wrapped_exponential_density(negative_rate, 2.0 * pi - xs)
return _mix_skew_components(
positive_component,
negative_component,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,7 @@ def sample(self, n: Union[int, int32, int64]):
safe_direction_norms = where(direction_norms > 0.0, direction_norms, 1.0)
random_points = random_points / safe_direction_norms
canonical_direction = eye(self.dim)[0].reshape(1, -1)
random_points = where(
direction_norms > 0.0, random_points, canonical_direction
)
random_points = where(direction_norms > 0.0, random_points, canonical_direction)

random_radii = random.uniform(size=(n, 1)) # So that broadcasting works below
random_radii = random_radii ** (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@

from .abstract_hyperspherical_distribution import AbstractHypersphericalDistribution


_INVALID_REAL_SCALAR_TYPES = (
bool,
np.bool_,
Expand Down Expand Up @@ -143,9 +142,7 @@ def _scaled_log_normalization(input_dim: int, kappa: float) -> float:
+ kappa
)
if not math.isfinite(result):
raise ValueError(
"Could not compute a finite high-order vMF log normalization."
)
raise ValueError("Could not compute a finite high-order vMF log normalization.")
return result


Expand Down Expand Up @@ -204,9 +201,7 @@ def __init__(self, mu, kappa):
self._log_scaled_normalization = _scaled_log_normalization(
self.input_dim, kappa_scalar
)
self.C = array(
_exp_from_log(self._log_scaled_normalization - kappa_scalar)
)
self.C = array(_exp_from_log(self._log_scaled_normalization - kappa_scalar))

def pdf(self, xs):
"""Evaluate the density at unit vectors.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
from .abstract_hyperspherical_distribution import AbstractHypersphericalDistribution
from .bingham_distribution import BinghamDistribution


_INVALID_REAL_SCALAR_TYPES = (
bool,
np.bool_,
Expand Down
Loading