I need to optimize calculation of the frequencies of gametes in populations.
I have np
populations and Ne
individuals in each population. Each individual is formed by two gametes (male and female). Each gamete contains three genes. Each gen may be 0
or 1
. So each individual is a 2x3 matrix. Each row of the matrix is a gamete given by one of the parents. The set of individuals in each population may be arbitrary (but always of Ne
length). For simplicity initial populations with individuals may be given as:
Ne = 300; np = 3^7;
(*This table may be arbitrary with the same shape*)
ind = Table[{{0, 0, 0}, {1, 1, 1}}, {np}, {Ne}]
Full set of all possible gametes:
allGam = Tuples[{0, 1}, 3]
Each individual can generate a gamete by 8 possible ways with equal probability. These gametes are: Tuples@Transpose@ind[[iPop, iInd]]
(where iPop
and iInd
- indexes of population and of individual in that population). I need to calculate the frequencies of gametes generated by individuals for each population.
At this moment my solution is as follows.
At first, I convert each individual into gametes it can produce:
gamsInPop = Map[Sequence @@ Tuples@Transpose@# &, ind, {2}]
But more efficient way to do this is:
gamsInPop =
Table[Join @@ Table[Tuples@Transpose@ind[[i, j]], {j, 1, Ne}], {i, 1, np}]
Secondly, I calculate the frequencies of gametes produced including zero frequencies for gametes that are possible but absent in population:
gamFrq = Table[Count[pop, gam]/(8 Ne), {pop, gamInPop}, {gam, allGam}]
More efficient version of this code:
gamFrq = Total[
Developer`ToPackedArray[
gamInPop /. Table[
allGam[[i]] -> Insert[{0, 0, 0, 0, 0, 0, 0}, 1, i], {i, 1,
8}]], {2}]/(8 Ne)
Unfortunately, the code is still too slow. Can anybody help me to speed-up it?