Мне нужно оптимизировать расчет частот гамет в популяциях.
У меня есть np
популяции и Ne
особей в каждой популяции. Каждая особь состоит из двух гамет (мужской и женской). Каждая гамета содержит три гена. Каждое поколение может быть 0
или 1
. Таким образом, каждый человек представляет собой матрицу 2x3. Каждая строка матрицы - это гамета, данная одним из родителей. Набор особей в каждой популяции может быть произвольным (но всегда длиной Ne
). Для простоты начальные популяции с особями могут быть представлены как:
Ne = 300; np = 3^7;
(*This table may be arbitrary with the same shape*)
ind = Table[{{0, 0, 0}, {1, 1, 1}}, {np}, {Ne}]
Полный набор всех возможных гамет:
allGam = Tuples[{0, 1}, 3]
Каждый индивид может генерировать гамету 8 возможными способами с равной вероятностью. Вот эти гаметы: Tuples @ Transpose @ ind [[iPop, iInd]]
(где iPop
и iInd
- индексы населения и отдельных лиц в этой популяции) . Мне нужно рассчитать частоту гамет, генерируемых индивидуумами для каждой популяции.
На данный момент мое решение таково.
СначалаЯ конвертирую каждую особь в гаметы, которые она может произвести:
gamsInPop = Map[Sequence @@ Tuples@Transpose@# &, ind, {2}]
Но более эффективный способ сделать это:
gamsInPop =
Table[Join @@ Table[Tuples@Transpose@ind[[i, j]], {j, 1, Ne}], {i, 1, np}]
Во-вторых, я вычисляю частоты произведенных гамет, включая нулевые частоты для гамет, которые возможны, но отсутствуют в популяции:
gamFrq = Table[Count[pop, gam]/(8 Ne), {pop, gamInPop}, {gam, allGam}]
Более эффективная версия этого кода:
gamFrq = Total[
Developer`ToPackedArray[
gamInPop /. Table[
allGam[[i]] -> Insert[{0, 0, 0, 0, 0, 0, 0}, 1, i], {i, 1,
8}]], {2}]/(8 Ne)
К сожалению, код все еще слишком медленный. Может ли кто-нибудь помочь мне ускорить это?