Feature extended asym div - #385
Open
drbergman wants to merge 9 commits into
Open
Conversation
more robust macro to check for windows
1.14.2 release
- Thanks @davidlzhou for development and testing!! - subsumes standard asymmetric division - old syntax still works: "asymmetric division to <cell_type>" - note: this syntax relies implicitly on the cell type the rule is being assigned to - hence, we need to an int to index these distinctly from the extended asym div rules - but they will still access the new extended asym div hash maps to get/set probabilities - uses pairs of ints (cell types) as keys into hash map for asym div probabilities - behaviors implemented - "extended asymmetric division to <cell_type_1> and <cell_type_2>" - sample project added: `make extended-asym-div-sample` - get and set functions for safe access to asymmetric_division_probabilities - asymmetric_division_probability functions to give robust getter access - set_asymmetric_division_probability functions to provide safe setter access - reorganize so asym div functionality is inside phenotype.cpp and standard_models.cpp - simplify write with new getters
Collaborator
Author
|
Note, when merging into dev, this block will be needed to make the resume addition work in multicell ds: if (create_cells)
{
pCell->phenotype.cycle.asymmetric_division.asymmetric_division_probabilities.clear();
pCell->phenotype.cycle.asymmetric_division.asymmetric_division_probabilities.reserve(n_cell_types * (n_cell_types + 1) / 2);
}
for ( int i1 = 0; i1 < n_cell_types; i1++ )
{
for ( int i2 = i1; i2 < n_cell_types; i2++ )
{
fread(&dTemp, sizeof(double), 1, fp);
if (debug_print)
{ std::cout << " phenotype.cycle.asymmetric_division.set_asymmetric_division_probability(" << i1 << "," << i2 << ", " << dTemp << ")" << std::endl; }
if (create_cells)
{ pCell->phenotype.cycle.asymmetric_division.set_asymmetric_division_probability(i1, i2, dTemp); }
}
} |
select_daughter_types() never formed a cumulative distribution. It drew one UniformRandom() and compared it against each entry's own probability, so the first entry whose probability happened to exceed r won, and realised daughter type frequencies did not match the configured ones. It now walks a running sum. The outcome also depended on std::unordered_map iteration order, which is unspecified and varies with the standard library, insertion history, and rehashing -- so two runs with the same seed could pick different daughter types on different platforms. asymmetric_division_probabilities is now a std::map ordered by the (min,max) form of the type pair, which depends only on the cell type indices. pair_hash and equality_function are replaced by a single pair_compare. exit(-1) fired on correctly configured models. Probabilities meant to sum to exactly 1 routinely sum to a hair over it in double precision -- 0.11 + 0.33 + 0.56 is 1.000000000000000222 -- which tripped the "cannot be normalized" branch on models that were fine. A 1e-12 tolerance on both the entry test and the negative-probability test fixes that; the arithmetic is otherwise unchanged, and a genuinely over-specified model still reports and exits rather than being quietly rescaled. The diagnostic now prints the CELL's current probabilities instead of iterating every cell type pair from the definitions, since a rule or custom function may have changed them since setup. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
It was the branch's only change to this file, and development has since restructured .gitignore, so the two sides conflict on every merge. Dropping it makes the branch's .gitignore identical to the merge base, which lets development's version apply cleanly. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
asymmetric_division_function tolerates a small excess when checking that the probabilities sum to at most 1, because probabilities meant to sum to exactly 1 land a hair over it in double precision. That tolerance was hard-coded at 1e-12, which is the right default but not right for every model: how much slack is needed depends on how many probabilities are summed and how they are produced. A model whose probabilities come out of rules rather than literals can exceed 1 by far more than 1e-12 -- excesses around 8e-3 have been observed in practice -- and such a model currently exits with no way to say that is acceptable. Adds <asymmetric_division_probability_tolerance> to the <options> block. Absent, the default 1e-12 applies and nothing is printed, so existing configs are unaffected. Present, the value is used and echoed at startup. A negative value is rejected at parse time rather than silently inverting both comparisons. Co-Authored-By: Claude Opus 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.
extended asym div that allows for any combo of cell types for both daughter cells. Thank you @davidlzhou for contributing!
See the new sample project for how to use.
Config
Note: Order of
name1andname2attributes does not matter. An ordered map on unordered pairs of integers is used to get/set the relevant probabilities.Behaviors
Note: Order does not matter. An ordered map on unordered pairs of integers is used to get/set the relevant probabilities.
Tolerance on the probability sum
The check that the probabilities sum to at most 1 allows a small excess, because probabilities meant to sum to exactly 1 land a hair over it in double precision —
0.11 + 0.33 + 0.56is1.000000000000000222. That tolerance defaults to1e-12and is configurable, since how much slack a model needs depends on how many probabilities it sums and how they are produced. Probabilities driven by rules rather than XML literals have been seen to exceed 1 by around8e-3.Absent, the default applies and nothing is printed. Present, the value is used and echoed at startup. A negative value is rejected at parse time rather than silently inverting the comparison. This only widens the band in which an over-specified distribution is accepted and absorbed — one that exceeds 1 beyond the tolerance still reports and exits, and nothing is rescaled.