Repository navigation
Support tuple and unordered node states - #19
Merged
Merged
Conversation
- HomogeneousProcess.Λ_inv returns a single infinity for a zero rate, rather than np.full_like(x, np.inf), which had one element per tuple element when the state was a tuple. With the default zero-rate death and mutation processes, this made evolve fail for any tuple state. - evolve compares only waiting times when choosing the next event, so states need not be orderable. Previously, ties between infinite waiting times compared the states themselves. Seeded results are unchanged, since the event chosen for an infinite waiting time is never used. - ConstantProcess returns one rate per state for a sequence of states, instead of one per tuple element. Closes #18 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #18.
Summary
Tuple-valued node states, and state types that can't be ordered, now work in
Tree.evolve.HomogeneousProcess.Λ_invreturns a single infinity for a zero rate. It used to returnnp.full_like(x, np.inf), which for a tuple state gives one infinity per tuple element, soevolvefailed when comparing waiting times. Because the default death and mutation processes have rate zero, every tuple-state simulation hit this. For scalar states, the return value is the same as before,array(inf).evolvecompares only waiting times when choosing the next event (min(..., key=...)). It used to compare(waiting_time, event, state)tuples, so two infinite waiting times led to comparing states, which raisedTypeErrorfor states without an ordering, such as a frozen dataclass withoutorder=True.ConstantProcess.λ_homogeneousreturns one rate per state for a sequence of states, matchingDiscreteProcess. For a list of three tuple states it used to return shape(3, 2). Numpy arrays keep their shape, as before.Seeded results don't change
The event chosen for an infinite waiting time is never used, because the simulation reaches its end time first. Two finite waiting times tie with probability zero, so comparing only waiting times picks the same event as before. As a check, the outputs of about 140 seeded simulations, covering every
capacity_method, time-inhomogeneous processes, a Gaussian mutator, and sampling and pruning, are identical to 1.0.0.Tests
Two new tests fail on 1.0.0 and pass with this change:
test_tuple_statesruns the reproducer from Tuple-valued states make evolve fail (zero-rate waiting time has the wrong shape) #18, which uses tuple states and the default processes. It checks that the resulting tree has the same node times as the same model with a scalar state, and thatConstantProcessreturns one rate per tuple state.test_unordered_statessimulates states that can't be ordered, two of which have zero birth rate, so their infinite birth waiting times tie.On Python 3.15 locally, all unit tests, doctests, and both notebooks pass, along with ruff, docformatter, and pyright. On Python 3.12, simulation speed is unchanged or slightly faster.
🤖 Generated with Claude Code