Пример #1
0
// determine the next event
func (w *WFPopulation) nextEvent() (eventType int, eventTime float64) {
	k := float64(len(w.history.CurrentPool))
	p := 2.0 * w.TransferRate * float64(w.Size)
	l := (k*p + k*(k-1.0)) / 2.0
	v := randist.ExponentialRandomFloat64(w.rng, 1.0/l)
	eventTime = v
	r := randist.UniformRandomFloat64(w.rng)
	if r < p/(k-1.0+p) {
		eventType = TransferEvent
	} else {
		eventType = CoalescenceEvent
	}
	return
}
Пример #2
0
// evolutionary operators: mutation and transfer
func (pop *SeqPop) manipulate() {
	// calculate the number of events, which is poisson distribution
	lambda := float64(pop.Size) * float64(pop.Length) * (pop.Mutation + pop.Transfer)
	if pop.ExpTime {
		t := randist.ExponentialRandomFloat64(pop.rng, 1.0)
		lambda = t * lambda
	}
	k := randist.PoissonRandomInt(pop.rng, lambda)
	// given k, the number of mutations or transfers are following Binormial distribution.
	// therefore, we can do k times of Bernoulli test
	for i := 0; i < k; i++ {
		// determine whether this event is a mutation or transfer
		ratio := pop.Mutation / (pop.Mutation + pop.Transfer) // the ratio of mutation
		r := randist.UniformRandomFloat64(pop.rng)            // randomly produce a probability
		if r <= ratio {                                       // determin whether is a mutation or transfer
			pop.mutate()
		} else {
			pop.transfer()
		}
	}
}