We can parameterize the edges to easily update the weights of the edge. We do this by assigning a coefficient vector to the edge instead of a rate.
Once we have built the graph, we set the can set the model parameters using a vector of scalars with the same length as those assigned to the graph edges. This changes the weight of each edge to the inner sum of the edge vector and the parameter vector. E.g. if the state is x1, x2 and the parameters are p1, p2, then the weight of the edge become x1*p1+x2*p2.
Continuous phase-type distributions
To parameterize the ARG model above, we remove the keyword arguments N and R, assume their values are 1 so that the the coalescent rate is no longer a fixed rate
state[i]*(state[j]-same)/(1+same) / N
but the a coefficient vector:
[[state[i]*(state[j]-same)/(1+same), 0]
Similarly the recombination rate is no longer R but [0, 1].
A parameter vector of [1/N, R] will then produce the appropriate edge weights.
from phasic import Graph, with_ipv, StateIndexer, Property, set_log_level # ALWAYS import phasic first to set jax backend correctlyimport sysimport numpy as npimport matplotlib.pyplot as pltimport seaborn as snsfrom vscodenb import set_vscode_themenp.random.seed(42)set_vscode_theme()sns.set_palette('tab10')
Overriding theme from NOTEBOOK_THEME environment variable. <phasic._DeviceListFilter object at 0x175d0edd0>
If you forget, you can get the number of parameters by calling:
# graph.param_length()
Having defined the graph with edge coefficients rather than fixed weights, we can now update the weights with specific parameter values and compute expectations. Here, we set the coalescence rate to (1/N) and the recombination rate to (R) and compute the expectation:
graph.update_weights([1/3, 5])graph.expectation()
8.73842953970774
The new weights are computed as the the dot product of the edge coefficients and the vector of parameters passed to update_weights (parameters*coefficients). This covers most use cases, but for full flexibility you can pass a callback function callback(parameters, coefficients) -> weight. The example below is the same as the default behaviour:
When using the callback argument, the parameter vector can be shorter than the coefficient vectors. Just pass the param_length keyword argument to the Graph constructor. Allowing for more coefficients s handy if you need to pass more information to the callback function in order to update edge weights.
Discrete phase-type distributions
Let us go back to the simpler coalescent model as an example of a discrete parameterized model.