Skip to content
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
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,15 @@ and `rbd._sensitivity`'s `levers` and `Lever` are gone (use `levers()`,

### Fixed

- **A fixed maintenance duration is fixed whatever numpy's rounding.** A
duration known exactly (an `ExactEventTime`) is followed as a fixed
time, where a spread one is convolved; it was told from its variance,
a difference of two numbers about the duration squared, against a
tolerance a few units of rounding wide: on numpy 2.0 the variance came
out at 1e-15, and the exact and numerical analyses of a component
maintained for a fixed time refused ("its later age replacements ...
are too many ... to follow exactly"). The tolerance is a millionth of
the duration.
- **A shut at an offset off the grid keeps its period (#319).** The
grid's step for `NonRepairable.optimal_calendar_policy` was sized to
put every period, offset and date on it, and fell back to the
Expand Down
5 changes: 4 additions & 1 deletion repyability/rbd/_point_availability.py
Original file line number Diff line number Diff line change
Expand Up @@ -831,7 +831,10 @@ def __init__(
mean, variance = _moments(
sf, np.linspace(0.0, self.top, 4097), self.splits
)
if variance <= (1e-9 * self.top) ** 2:
# A fixed time, to rounding: the variance is a difference of two
# numbers about ``top ** 2``, so it is uncertain by a few units of
# rounding in them (numpy 2.0 sums them to 1e-15 at a top of 5).
if variance <= (1e-6 * self.top) ** 2:
self.fixed = mean
return
from scipy.signal import fftconvolve
Expand Down
4 changes: 3 additions & 1 deletion repyability/tests/test_point_availability.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,9 @@ def test_matches_the_simulation(name):
def test_instant_repair_is_always_up():
rbd = alone(unit(W([100.0, 2.0]), "instant"))
assert rbd.point_availability([0.0, 10.0, 1e4]).tolist() == [1, 1, 1]
assert rbd.mission_availability(100.0) == 1.0
# To rounding: the integral of a constant 1 sums the quadrature's
# weights, exact to a few units of rounding in some numpy versions.
assert rbd.mission_availability(100.0) == pytest.approx(1.0, abs=1e-15)


def test_units_dead_on_arrival_and_units_that_never_fail():
Expand Down
Loading