This chapter was mostly about applying techniques from the previous chapter to derive and to understand important ecological and evolutionary models. That said, one important tool that is introduced is the mating table. Here we will run through a short example of how to produce a mating table programmatically, using symbolic computing. Then we’ll get the governing equations of our system from the mating table and visualise the results for a specific set of parameter values.
First we declare the variables we will use and create two Dicts, one linking allele type to allele frequency, and the other linking genotype to fitness function.
Next we need to create vectors of values that we will use to populate the mating table. self and other are just String representations of the different alleles.
4-element Vector{String}:
"A × A"
"A × a"
"a × A"
"a × a"
For the next columns we will use vector comprehensions to build vectors of expressions by multiplying symbolic variables, which we look up in the Dicts we made before.
freq_before = [freq[self[i]] * freq[other[i]] for i in1:4]freq_weighted = freq_before .* [W[self[i]*other[i]] for i in1:4]freq_after = freq_before .* [W[self[i]*other[i]]/W̄ for i in1:4]
Lastly, we combine and name our columns in a DataFrame.
We only need to convert uniting to LaTeXStrings because otherwise when we latexifymatingTable, an attempt is made to actually multiply self by other.
matingTable =DataFrame([LaTeXString.(uniting),freq_before,freq_weighted,freq_after,A,a], ["Uniting Gametes","Freq. before selection","Freq. weighted by fitness", "Freq. after selection","A","a"])
4 rows × 6 columns (omitted printing of 2 columns)
Uniting Gametes
Freq. before selection
Freq. weighted by fitness
Freq. after selection
LaTeXStr…
Num
Num
Num
1
A × A
p^2
Wᴬᴬ*(p^2)
(Wᴬᴬ*(p^2)) / W̄
2
A × a
p*q
Wᴬᵃ*p*q
(Wᴬᵃ*p*q) / W̄
3
a × A
p*q
Wᴬᵃ*p*q
(Wᴬᵃ*p*q) / W̄
4
a × a
q^2
Wᵃᵃ*(q^2)
(Wᵃᵃ*(q^2)) / W̄
Hmmm… Could be bit prettier…
latexify(matingTable)
Uniting Gametes
Freq. before selection
Freq. weighted by fitness
Freq. after selection
A
a
\(A × A\)
\(p^{2}\)
\(p^{2} W^{A A}\)
\(\frac{p^{2} W^{A A}}{\textnormal{\={W}}}\)
\(1\)
\(0\)
\(A × a\)
\(p q\)
\(W^{A a} p q\)
\(\frac{W^{A a} p q}{\textnormal{\={W}}}\)
\(\frac{1}{2}\)
\(\frac{1}{2}\)
\(a × A\)
\(p q\)
\(W^{A a} p q\)
\(\frac{W^{A a} p q}{\textnormal{\={W}}}\)
\(\frac{1}{2}\)
\(\frac{1}{2}\)
\(a × a\)
\(q^{2}\)
\(q^{2} W^{a a}\)
\(\frac{q^{2} W^{a a}}{\textnormal{\={W}}}\)
\(0\)
\(1\)
Nice. So now lets use the table to generate a model of the dynamics of alleles \(p\) and \(q\). First we multiply the the frequencies after selection by the proportions of A gametes produced and sum over rows.
pₜ₊₁ =sum(matingTable[:,"A"] .* matingTable[:,"Freq. after selection"])
Okay, so now we need to pick initial values for \(p\) and \(q\) and define a W̄ function. We will do the latter inside of a let block as we cant otherwise redefine the variable W̄ as a function. Then we just run through a loop repeatedly solving the recursion equation, and plot the results.