Implement bisection algorithm for finding the most recent state change.
This commit is contained in:
parent
43b9b864af
commit
0e71ace0d9
2 changed files with 14 additions and 8 deletions
|
|
@ -762,6 +762,7 @@ class ConcentrationModel:
|
|||
|
||||
return (self.infected.emission_rate(time)) / (IVRR * V)
|
||||
|
||||
@method_cache
|
||||
def state_change_times(self) -> typing.List[float]:
|
||||
"""
|
||||
All time dependent entities on this model must provide information about
|
||||
|
|
@ -777,11 +778,18 @@ class ConcentrationModel:
|
|||
"""
|
||||
Find the most recent/previous state change.
|
||||
|
||||
Find the nearest time less than the given one. If there is a state
|
||||
change exactly at ``time`` the previous state change is returned
|
||||
(except at ``time == 0``).
|
||||
|
||||
"""
|
||||
for change_time in self.state_change_times()[::-1]:
|
||||
if change_time < time:
|
||||
return change_time
|
||||
return 0.
|
||||
times = self.state_change_times()
|
||||
t_index = np.searchsorted(times, time)
|
||||
# Search sorted gives us the index to insert the given time. Instead we
|
||||
# want to get the index of the most recent time, so reduce the index by
|
||||
# one unless we are already at 0.
|
||||
t_index = max([t_index - 1, 0])
|
||||
return times[t_index]
|
||||
|
||||
def _next_state_change(self, time: float) -> float:
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ def simple_conc_model():
|
|||
|
||||
@pytest.mark.parametrize(
|
||||
"time, expected_last_state_change", [
|
||||
[-15., 0.], # Out of range goes to the last state.
|
||||
[0., 0],
|
||||
[1., 0],
|
||||
[1.05, 1.],
|
||||
|
|
@ -80,6 +81,7 @@ def simple_conc_model():
|
|||
[2., 1.999],
|
||||
[2.1, 2],
|
||||
[3., 2],
|
||||
[15., 3.], # Out of range goes to the last state.
|
||||
]
|
||||
)
|
||||
def test_last_state_change_time(
|
||||
|
|
@ -90,10 +92,6 @@ def test_last_state_change_time(
|
|||
assert simple_conc_model.last_state_change(float(time)) == expected_last_state_change
|
||||
|
||||
|
||||
def test_last_state_change_time_out_of_range(simple_conc_model: models.ConcentrationModel):
|
||||
assert simple_conc_model.last_state_change(3.1) == 3.0
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"time, expected_next_state_change", [
|
||||
[0, 0],
|
||||
|
|
|
|||
Loading…
Reference in a new issue