Skip to content

Feature extended asym div - #385

Open
drbergman wants to merge 8 commits into
MathCancer:developmentfrom
drbergman:feature-extended-asym-div
Open

Feature extended asym div#385
drbergman wants to merge 8 commits into
MathCancer:developmentfrom
drbergman:feature-extended-asym-div

Conversation

@drbergman

Copy link
Copy Markdown
Collaborator

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

<cycle code="5" name="live">
  <phase_transition_rates units="1/min">
    <rate start_index="0" end_index="0" fixed_duration="true">0.005</rate>
  </phase_transition_rates>
  <extended_asymmetric_division enabled="True">
    <extended_asymmetric_division_probability name1="type0" name2="type0" units="dimensionless">1.0</extended_asymmetric_division_probability>
  </extended_asymmetric_division>
</cycle>

Note: Order of name1 and name2 attributes does not matter. A hash map on unordered pairs of integers is used to get/set the relevant probabilities.

Behaviors

extended asymmetric division to <type1> and <type2>

Note: Order does not matter. A hash map on unordered pairs of integers is used to get/set the relevant probabilities.

drbergman and others added 6 commits January 15, 2025 13:41
- 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
@drbergman

drbergman commented Feb 11, 2026

Copy link
Copy Markdown
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); }
			}
		}

drbergman and others added 2 commits August 7, 2026 09:30
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>
Copilot AI lite review requested due to automatic review settings August 7, 2026 14:11

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants