5

मुझे आबादी में गैमेट की आवृत्तियों की गणना को अनुकूलित करने की आवश्यकता है।आबादी में गैमेट की आवृत्तियों की गणना को अनुकूलित करना

मेरे पास प्रत्येक जनसंख्या में 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 संभव तरीके से एक gamete उत्पन्न कर सकते हैं सरलता के लिए व्यक्तियों के साथ प्रारंभिक आबादी के रूप में दिया जा सकता है। ये गैमेट हैं: [email protected]@ind[[iPop, iInd]] (जहां iPop और iInd - आबादी की अनुक्रमणिका और उस आबादी में व्यक्तिगत)। मुझे प्रत्येक आबादी के लिए व्यक्तियों द्वारा उत्पन्न गैमेट की आवृत्तियों की गणना करने की आवश्यकता है।

इस समय मेरा समाधान निम्नानुसार है।

सबसे पहले, मैं युग्मक में प्रत्येक व्यक्ति के धर्मांतरण यह कर सकते हैं उत्पादन:

gamsInPop = Map[Sequence @@ [email protected]@# &, ind, {2}] 

लेकिन अधिक कुशल तरीका यह करने के लिए है:

gamsInPop = 
Table[Join @@ Table[[email protected]@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) 

दुर्भाग्यवश, कोड अभी भी बहुत धीमा है। क्या कोई मुझे गति देने में मदद कर सकता है?

+1

मैंने संयोजक टैग जोड़ा; मुझे लगता है कि यह मदद करेगा। मेरे पास अभी इस के लिए समय नहीं है। –

उत्तर

6

इस कोड:

Clear[getFrequencies]; 
Module[{t = 
    Developer`ToPackedArray[ 
    Table[FromDigits[#, 2] & /@ 
     Tuples[Transpose[{ 
      PadLeft[IntegerDigits[i, 2], 3], 
      PadLeft[IntegerDigits[j, 2], 3]}]], 
     {i, 0, 7}, {j, 0, 7}] 
    ]}, 
    getFrequencies[ind_] := 
    With[{extracted = 
     Partition[ 
      [email protected][t, Flatten[ind.(2^Range[0, 2]) + 1, 1]], 
      Ne*8]}, 
     Map[ 
     [email protected][#, Thread[{Complement[Range[0, 7], #[[All, 1]]], 0}]] &@Tally[#] &, 
     extracted 
     ][[All, All, 2]]/(Ne*8) 
    ] 
] 

संख्या और पैक सरणियों दशमलव में रूपांतरण का इस्तेमाल करता है, और मेरे मशीन पर 40 का एक पहलू से अपने कोड को गति। मानक:

In[372]:= Ne=300;np=3^7; 
(*This table may be arbitrary with the same shape*) 
inds=Table[{{0,0,0},{1,1,1}},{np},{Ne}]; 

In[374]:= 
getFrequencies[inds]//Short//Timing 
Out[374]= {0.282,{{1/8,1/8,1/8,1/8,1/8,1/8,1/8,1/8},<<2185>>, 
{1/8,1/8,1/8,1/8,1/8,1/8,1/8,1/8}}} 

In[375]:= 
Timing[ 
    gamsInPop=Table[[email protected]@Table[[email protected]@inds[[i,j]],{j,1,Ne}],{i,1,np}]; 
    gamFrq=Total[Developer`ToPackedArray[gamsInPop/.Table[allGam[[i]]-> 
     Insert[{0,0,0,0,0,0,0},1,i],{i,1,8}]],{2}]/(8 Ne)//Short] 

Out[375]= {10.563,{{1/8,1/8,1/8,1/8,1/8,1/8,1/8,1/8},<<2185>>, 
    {1/8,1/8,1/8,1/8,1/8,1/8,1/8,1/8}}} 

ध्यान दें कि सामान्य रूप में (यादृच्छिक आबादी के लिए), आवृत्तियों के आदेश अपने और मेरे समाधान में किसी कारण अलग के लिए हैं, और

In[393]:= fr[[All,{1,5,3,7,2,6,4,8}]] == gamFrq 
Out[393]= True 

अब, कुछ स्पष्टीकरण: पहला, हम एक टेबल t बनाते हैं, जिसे निम्नानुसार बनाया गया है: प्रत्येक गैमेटे को 0 से 7 तक एक संख्या सौंपी जाती है, जो शून्य और उसके बाइनरी अंकों के रूप में माना जाता है। तालिका में {i,j} स्थिति में संग्रहीत एक व्यक्ति द्वारा उत्पादित संभावित गैमेट होते हैं, जहां i माता की गामेट (कहें), और j के लिए एक दशमलव है - पिता के लिए, प्रत्येक व्यक्ति को अद्वितीय रूप से एक जोड़ी {i,j} द्वारा पहचाना जाता है) । व्यक्ति द्वारा उत्पादित गैमेट भी दशमलव में परिवर्तित हो जाते हैं।यह इस प्रकार से दिखाई देता है:

In[396]:= t//Short[#,5]& 
Out[396]//Short= {{{0,0,0,0,0,0,0,0},{0,1,0,1,0,1,0,1},{0,0,2,2,0,0,2,2}, 
{0,1,2,3,0,1,2,3},{0,0,0,0,4,4,4,4},{0,1,0,1,4,5,4,5},{0,0,2,2,4,4,6,6}, 
{0,1,2,3,4,5,6,7}},<<6>>,{{7,6,5,4,3,2,1,0},{7,7,5,5,3,3,1,1},{7,6,7,6,3,2,3,2}, 
<<2>>,{7,7,5,5,7,7,5,5},{7,6,7,6,7,6,7,6},{7,7,7,7,7,7,7,7}}} 

एक बहुत ही महत्वपूर्ण (महत्वपूर्ण) कदम एक पैक सरणी के लिए इस तालिका परिवर्तित करना है।

लाइन Flatten[ind.(2^Range[0, 2]) + 1, 1]] द्विआधारी से माता-पिता की युग्मक धर्मान्तरित एक ही बार में सभी व्यक्तियों के लिए दिया गया दशमलव में की आबादी में, और 1 इसलिए कहते हैं कि इन सूचकांकों जिस पर युग्मक निर्माण करने के लिए संभव की सूची एक के लिए एक मेज t में संग्रहीत किया जाता हो जाते हैं दिया गया व्यक्ति हम सभी जनसंख्या के लिए Extract सभी एक बार, और जनसंख्या संरचना को वापस पाने के लिए Flatten और Partition का उपयोग करते हैं। फिर, हम Tally के साथ आवृत्तियों की गणना करते हैं, आवृत्तियों शून्य (Join[#, Thread[{Complement[Range[0, 7], #[[All, 1]]], 0}]] लाइन द्वारा किया गया) के साथ लापता गैमेट संलग्न करें, और Sort एक निश्चित आबादी के लिए प्रत्येक आवृत्ति सूची। अंत में, हम आवृत्तियों को निकालते हैं और गैमेटे दशमलव सूचकांक को त्याग देते हैं।

पैक किए गए सरणी पर प्रदर्शन के बाद से सभी ऑपरेशन बहुत तेज हैं। गति समस्या के वेक्टरकृत फॉर्मूलेशन और पैक किए गए सरणी के उपयोग के कारण है। यह भी अधिक स्मृति - कुशल है।

+0

आपके कोड में यह अनिर्धारित 'छोटा' क्या कर रहा है? –

+0

@Sjoerd यह एक बग है, परीक्षण से बनी हुई है, मैंने बस इसे ठीक किया है। –

+0

क्या आप समझा सकते हैं कि आप इसे 'मॉड्यूल' में क्यों पैक करते हैं? क्या यह सिर्फ स्थानीयकृत टी $ 39833 9 चर है? –

संबंधित मुद्दे