def fels(ov, v_to_children, pattern, de_to_P, root_prior): """ The P matrices and the root prior may be algopy objects. @param ov: ordered vertices with child vertices before parent vertices @param v_to_children: map from a vertex to a sequence of child vertices @param pattern: an array that maps vertex to state, or to -1 if internal @param de_to_P: map from a directed edge to a transition matrix @param root_prior: equilibrium distribution at the root @return: log likelihood """ nvertices = len(ov) nstates = len(root_prior) states = range(nstates) root = ov[-1] # Initialize the map from vertices to subtree likelihoods. likelihoods = algopy.ones( (nvertices, nstates), dtype=de_to_P.values()[0], ) # Compute the subtree likelihoods using dynamic programming. for v in ov: for pstate in range(nstates): for c in v_to_children.get(v, []): P = de_to_P[v, c] likelihoods[v, pstate] *= algopy.dot(P[pstate], likelihoods[c]) state = pattern[v] if state >= 0: for s in range(nstates): if s != state: likelihoods[v, s] = 0 # Get the log likelihood by summing over equilibrium states at the root. return algopy.log(algopy.dot(root_prior, likelihoods[root]))
def ratios_to_distn(ratios): """ @param ratios: n-1 ratios of leading prob to the trailing prob @return: a finite distribution over n states """ n = ratios.shape[0] + 1 expanded_ratios = algopy.ones(n, dtype=ratios) expanded_ratios[:-1] = ratios distn = expanded_ratios / algopy.sum(expanded_ratios) return distn
def get_distn(genetic_code, kappa, omega, A, C, G, T): """ """ # initialize the unweighted distribution nstates = len(genetic_code) weights = algopy.ones(nstates, dtype=kappa) nt_distn = { 'A' : A, 'C' : C, 'G' : G, 'T' : T, } # construct the unnormalized distribution for i, (state, residue, codon) in enumerate(genetic_code): for nt in codon: weights[i] = weights[i] * nt_distn[nt] # return the normalized distribution distn = weights / weights.sum() return distn