def prob_coal_counts(u, v, t, n): """ The probabiluty of going from 'u' lineages to 'v' lineages in time 't' with population size 'n' """ T = t / n s = 0.0 for k in xrange(v, u+1): a = exp(-k*(k-1)*T/2.0) * (2*k-1)*(-1)**(k-v) / stats.factorial(v) / \ stats.factorial(k-v) / (k+v-1) * \ stats.prod((v+y)*(u-y)/(u+y) for y in xrange(k)) s += a return s
def prob_coal_counts_slow(a, b, t, n): """ The probabiluty of going from 'a' lineages to 'b' lineages in time 't' with population size 'n' Implemented more directly, but slower. Good for testing against. """ s = 0.0 for k in range(b, a + 1): i = exp(-k*(k-1)*t/2.0/n) * \ float(2*k-1)*(-1)**(k-b) / stats.factorial(b) / \ stats.factorial(k-b) / (k+b-1) * \ stats.prod((b+y)*(a-y)/float(a+y) for y in range(k)) s += i return s
def prob_coal_counts(a, b, t, n): """ The probability of going from 'a' lineages to 'b' lineages in time 't' with population size 'n' """ try: terms = [] C = stats.prod((b + y) * (a - y) / float(a + y) for y in xrange(b)) / float(stats.factorial(b)) terms.append(exp(-b * (b - 1) * t / 2.0 / n) * C) for k in xrange(b + 1, a + 1): k1 = k - 1 C = (b + k1) * (a - k1) / float(a + k1) / float(b - k) * C terms.append(exp(-k * k1 * t / 2.0 / n) * (2 * k - 1) / float(k1 + b) * C) terms.sort(key=abs) return kahan_sum(terms) except: print a, b, t, n raise
def prob_coal_counts_slow(a, b, t, n): """ The probabiluty of going from 'a' lineages to 'b' lineages in time 't' with population size 'n' Implemented more directly, but slower. Good for testing against. """ s = 0.0 for k in xrange(b, a + 1): i = ( exp(-k * (k - 1) * t / 2.0 / n) * float(2 * k - 1) * (-1) ** (k - b) / stats.factorial(b) / stats.factorial(k - b) / (k + b - 1) * stats.prod((b + y) * (a - y) / float(a + y) for y in xrange(k)) ) s += i return s
def prob_coal_counts(a, b, t, n): """ The probability of going from 'a' lineages to 'b' lineages in time 't' with population size 'n' """ try: terms = [] C = stats.prod((b+y)*(a-y)/float(a+y) for y in range(b)) \ / float(stats.factorial(b)) terms.append(exp(-b * (b - 1) * t / 2.0 / n) * C) for k in range(b + 1, a + 1): k1 = k - 1 C = (b + k1) * (a - k1) / float(a + k1) / float(b - k) * C terms.append( exp(-k * k1 * t / 2.0 / n) * (2 * k - 1) / float(k1 + b) * C) terms.sort(key=abs) return kahan_sum(terms) except: print(a, b, t, n) raise