Exemple #1
0
// do coalescent
func (w *WFPopulation) coalescent() int {
	// randomly choose two nodes
	a := w.history.CurrentPool[randist.UniformRandomInt(w.rng, len(w.history.CurrentPool))]
	b := w.history.CurrentPool[randist.UniformRandomInt(w.rng, len(w.history.CurrentPool))]
	for a == b {
		b = w.history.CurrentPool[randist.UniformRandomInt(w.rng, len(w.history.CurrentPool))]
	}

	aTreeNode := w.history.Tree[a]
	bTreeNode := w.history.Tree[b]

	// create their ancestor tree node and add it into the tree
	genome := Merge(aTreeNode.Genome, bTreeNode.Genome)
	children := []int{a, b}
	w.history.Tree = append(w.history.Tree, TreeNode{Genome: genome, Children: children})

	// update the current pool
	pool := []int{}
	for _, pos := range w.history.CurrentPool {
		if pos != a && pos != b {
			pool = append(pool, pos)
		}
	}
	ancestorID := len(w.history.Tree) - 1
	pool = append(pool, ancestorID)
	w.history.CurrentPool = pool

	return ancestorID
}
Exemple #2
0
// mutation operator
// parameters: g is genome idx.
func (pop *SeqPop) mutate() {
	g := randist.UniformRandomInt(pop.rng, pop.Size)   // randomly choose a genome
	l := randist.UniformRandomInt(pop.rng, pop.Length) // randomly determine a position
	s := randist.UniformRandomInt(pop.rng, pop.states) // randomly find a idx of the mutated character in pop.states
	for byte(s) == pop.Genomes[g][l] {
		s = randist.UniformRandomInt(pop.rng, pop.states)
	}

	// update the character.
	pop.Genomes[g][l] = byte(s)
}
Exemple #3
0
// do transfer
func (w *WFPopulation) transfer() (parents []int) {
	// randomly choose a node
	c := w.history.CurrentPool[randist.UniformRandomInt(w.rng, len(w.history.CurrentPool))]
	// tranferring fragment
	begin := randist.UniformRandomInt(w.rng, w.GenomeLength)
	end := begin + w.TransferLength
	if end < w.GenomeLength {
		amA, amB := Split(w.history.Tree[c].Genome, begin, end)
		if len(amA) != 0 {
			genome := amA
			children := []int{c}
			w.history.Tree = append(w.history.Tree, TreeNode{Genome: genome, Children: children})
			parents = append(parents, len(w.history.Tree)-1)
		}

		if len(amB) != 0 {
			genome := amB
			children := []int{c}
			w.history.Tree = append(w.history.Tree, TreeNode{Genome: genome, Children: children})
			parents = append(parents, len(w.history.Tree)-1)
		}
	} else {
		amB, amA := Split(w.history.Tree[c].Genome, end-w.GenomeLength+1, begin-1)
		if len(amA) != 0 {
			genome := amA
			children := []int{c}
			w.history.Tree = append(w.history.Tree, TreeNode{Genome: genome, Children: children})
			parents = append(parents, len(w.history.Tree)-1)
		}

		if len(amB) != 0 {
			genome := amB
			children := []int{c}
			w.history.Tree = append(w.history.Tree, TreeNode{Genome: genome, Children: children})
			parents = append(parents, len(w.history.Tree)-1)
		}
	}

	// update the current pool
	pool := []int{}
	for _, pos := range w.history.CurrentPool {
		if pos != c {
			pool = append(pool, pos)
		}
	}
	for _, pos := range parents {
		pool = append(pool, pos)
	}
	w.history.CurrentPool = pool

	return
}
Exemple #4
0
func mutateAll(seqMap map[int][]byte, lambda float64, l int, rng *randist.RNG) {
	for _, seq := range seqMap {
		count := randist.PoissonRandomInt(rng, lambda)
		for i := 0; i < count; i++ {
			idx := randist.UniformRandomInt(rng, l)
			a := NucleicAcids[randist.UniformRandomInt(rng, len(NucleicAcids))]
			for a == seq[idx] {
				a = NucleicAcids[randist.UniformRandomInt(rng, len(NucleicAcids))]
			}
			seq[idx] = a
		}
	}
}
Exemple #5
0
func randomGenerateSequence(length int, rng *randist.RNG) (seq []byte) {
	seq = make([]byte, length)
	for i, _ := range seq {
		seq[i] = NucleicAcids[randist.UniformRandomInt(rng, len(NucleicAcids))]
	}
	return
}
Exemple #6
0
// transfer operator
// parameter: g is genome idx.
func (pop *SeqPop) transfer() {
	g := randist.UniformRandomInt(pop.rng, pop.Size) // randomly choose a receiver
	d := randist.UniformRandomInt(pop.rng, pop.Size) // randomly choose a donor
	for g == d {
		d = randist.UniformRandomInt(pop.rng, pop.Size)
	}

	l := randist.UniformRandomInt(pop.rng, pop.Length) // randomly choose a left index
	r := l + pop.Fragment                              // fragment right index

	if r < pop.Length {
		copy(pop.Genomes[g][l:r], pop.Genomes[d][l:r])
	} else {
		copy(pop.Genomes[g][l:pop.Length], pop.Genomes[d][l:pop.Length])
		copy(pop.Genomes[g][0:r-pop.Length], pop.Genomes[d][0:r-pop.Length])
	}
}
Exemple #7
0
// Wright-Fisher generation
func (pop *SeqPop) reproduce() {
	newGenomes := make([]Sequence, pop.Size)
	used := make([]bool, pop.Size) // records used genomes
	for n := 0; n < pop.Size; n++ {
		o := randist.UniformRandomInt(pop.rng, pop.Size) // randomly select a parent
		if used[o] {
			// do hard copy
			newGenomes[n] = make(Sequence, pop.Length)
			copy(newGenomes[n], pop.Genomes[o])
		} else {
			// just pass the pointer of the genome
			newGenomes[n] = pop.Genomes[o]
			used[o] = true
		}
	}

	// update genomes
	pop.Genomes = newGenomes
}
Exemple #8
0
// NewSeqPop returns a population with full sequence genomes
func NewSeqPop(size, length int, mutation, transfer float64, fragment int) *SeqPop {
	// verify population size and genome length
	if size <= 0 || length <= 0 {
		log.Panic("Population size or genome length should be positive!")
	}
	// verify transfer rate and transferred fragment
	if transfer > 0 && fragment <= 0 {
		log.Panic("Transferred fragment should be positive when transfer rate > 0!")
	}

	// construct a population with parameters
	pop := SeqPop{
		Size:     size,
		Length:   length,
		Mutation: mutation,
		Transfer: transfer,
		Fragment: fragment,
	}

	// create random sources
	pop.rng = randist.NewRNG(randist.MT19937)

	// create genomes
	// randomly create a parent sequence
	pop.states = 4 // typical nucleotides, "ATGC"
	refseq := make(Sequence, pop.Length)
	for i := 0; i < len(refseq); i++ {
		refseq[i] = byte(randist.UniformRandomInt(pop.rng, pop.states)) // randomly assign a character
	}
	// copy the parent sequence to every genomes
	pop.Genomes = make([]Sequence, pop.Size)
	for i := 0; i < len(pop.Genomes); i++ {
		pop.Genomes[i] = make(Sequence, pop.Length)
		copy(pop.Genomes[i], refseq)
	}

	return &pop
}