//--------------------------------------------------------------------------- // Helpers //--------------------------------------------------------------------------- Matrix *BezierSurface::getN(int n) { Matrix *N = new Matrix(n + 1, n + 1); for(int i = 0; i <= n; ++i) { for(int j = 0; j <= n; ++j) { N->values[i][j] = (0 <= i + j && i + j <= n) ? Binom(n, j) * Binom(n - j, n - i - j) * pow(-1, n - i - j) : 0; } } return N; }
//initialize paternal and maternal haplotype arrays in one founder randomly void AnimalClass::initFounderHaps() { unsigned numChromosomePair = G.get_num_chrom(); for(unsigned i=0;i<numChromosomePair;i++){ unsigned numLoci=G[i].get_num_loci(); GenomePat[i].haplotype.resize(numLoci); GenomeMat[i].haplotype.resize(numLoci); for(unsigned j=0;j<numLoci;j++){ binomial_distribution<int> Binom(1,G[i][j].allele_freq(0)); GenomePat[i].haplotype[j]= Binom(randGen); GenomeMat[i].haplotype[j]= Binom(randGen); } } }
//get and save mutation loci for this individual void AnimalClass::sampleMyMutation() { if(!G.mapPosDone) G.mkMapPos(); unsigned numChromosomePair = G.get_num_chrom(); ///paternal chromsome for(unsigned i=0;i<numChromosomePair;i++){ vector<float> mutPos; unsigned nLoci=G[i].get_num_loci();//num of loci is euqal to num of mapPos binomial_distribution<int> Binom(nLoci,G.mutRate); int nMut=Binom(randGen); if(nMut){ uniform_real_distribution<float> u(0,1); for (unsigned k=0; k<nMut; k++) { unsigned which = unsigned(nLoci*u(randGen)); if(which!=nLoci){ mutPos.push_back(G[i].MapPos(which)); //get map position of mutation loci } } for(unsigned j=0;j<nMut;j++){ if(mutPos[j]!=G[i].chr_length){ //unsigned count =(GenomePat[i].pos < mutPos[j]).count(); unsigned count =(GenomePat[i].pos <= mutPos[j]).count(); float startPos =GenomePat[i].pos(count-1); float endPos; if(count!=GenomePat[i].pos.size()){ endPos =GenomePat[i].pos(count); }else{ endPos =G[i].chr_length; } int myOri=GenomePat[i].ori(count-1); GenomePat[i].ori(count-1)=countChromosome; countChromosome++; mutantInfo *mutant = new mutantInfo();//'new' return the address mutant->whichOri =myOri; mutant->whichStartPos =startPos; mutant->whichEndPos =endPos; mutant->mutPos =mutPos[j]; AnimalClass::mutants.push_back(mutant); } } } } ///maternal for(unsigned i=0;i<numChromosomePair;i++){ vector<float> mutPos; unsigned nLoci=G[i].get_num_loci(); binomial_distribution<int> Binom(nLoci,G.mutRate); int nMut=Binom(randGen); if(nMut){ uniform_real_distribution<float> u(0,1); for (unsigned k=0; k<nMut; k++) { unsigned which = unsigned(nLoci*u(randGen)); if(which!=nLoci){ mutPos.push_back(G[i].MapPos(which)); //get map position of mutation loci } } for(unsigned j=0;j<nMut;j++){ if(mutPos[j]!=G[i].chr_length){ unsigned count =(GenomeMat[i].pos <= mutPos[j]).count(); float startPos =GenomeMat[i].pos(count-1); float endPos; if(count!=GenomeMat[i].pos.size()){ endPos =GenomeMat[i].pos(count); }else{ endPos =G[i].chr_length; } int myOri=GenomeMat[i].ori(count-1); GenomeMat[i].ori(count-1)=countChromosome; //change this mutated ori to a new one after previous 2*nFounders ori countChromosome++; mutantInfo *mutant = new mutantInfo();//'new' return the address mutant->whichOri =myOri; mutant->whichStartPos =startPos; mutant->whichEndPos =endPos; mutant->mutPos =mutPos[j]; AnimalClass::mutants.push_back(mutant); } } } } }
//get new Ori and Pos arrays for the child after recombination void AnimalClass::sampleMyPosOri(AnimalClass& father, AnimalClass& mother) { sireId = father.myId; damId = mother.myId; chromosome *currentFatherChrom; chromosome *currentMotherChrom; unsigned numChromosomePair = G.get_num_chrom(); //construct paternal chromosome for myId ArrayXf tempPos; ArrayXi tempOri; tempPos.resize(100000); tempOri.resize(100000); for(unsigned i=0;i<numChromosomePair;i++){ double chrLength = G[i].chr_length; unsigned binomialN = chrLength*3 + 1; vector<float> rPos; binomial_distribution<int> Binom(binomialN,chrLength/binomialN); int numCrossover = Binom(randGen); uniform_real_distribution<float> u(0,1); for (unsigned k=0; k<numCrossover; k++) { rPos.push_back(chrLength*u(randGen)); } rPos.push_back(chrLength); sort(rPos.begin(),rPos.end()); unsigned startPosParent=0; unsigned startPosMe=0; currentFatherChrom = (u(randGen)<0.5)?&father.GenomePat[i]:&father.GenomeMat[i]; for(unsigned j=0;j<rPos.size();j++){ unsigned numCopy=(currentFatherChrom->pos < rPos[j]).count()-startPosParent; tempPos.block(startPosMe,0,numCopy,1)=currentFatherChrom->pos.block(startPosParent,0,numCopy,1); tempOri.block(startPosMe,0,numCopy,1)=currentFatherChrom->ori.block(startPosParent,0,numCopy,1); currentFatherChrom= (currentFatherChrom==&father.GenomePat[i])?&father.GenomeMat[i]:&father.GenomePat[i]; startPosParent=(currentFatherChrom->pos < rPos[j]).count(); startPosMe+=numCopy; tempPos(startPosMe)=rPos[j]; tempOri(startPosMe)=currentFatherChrom->ori(startPosParent-1); startPosMe++; } //the length of tempPos should be startPosMe now. Tricky here. // unsigned posLengthMinusOne=startPosMe-1; // unsigned nonzero=(tempPos.block(1,0,posLengthMinusOne,1)-tempPos.block(0,0,posLengthMinusOne,1)).count()+1; // GenomePat[i].pos.resize(nonzero-1); // GenomePat[i].ori.resize(nonzero-1); unsigned keep=0; GenomePat[i].pos.resize(startPosMe); GenomePat[i].ori.resize(startPosMe); GenomePat[i].pos[0]=tempPos[0]; GenomePat[i].ori[0]=tempOri[0]; for(unsigned m=1;m < startPosMe-1; m++){ if(tempOri[m]!=tempOri[m-1]){ keep=keep+1; GenomePat[i].pos[keep]=tempPos[m]; GenomePat[i].ori[keep]=tempOri[m]; } } unsigned PosOriSize=keep+1; GenomePat[i].pos.conservativeResize(PosOriSize); GenomePat[i].ori.conservativeResize(PosOriSize); } /// ///construct maternal chromosome for myId for(unsigned i=0;i<numChromosomePair;i++){ double chrLength = G[i].chr_length; unsigned binomialN = chrLength*3 + 1; vector<float> rPos; binomial_distribution<int> Binom(binomialN,chrLength/binomialN); int numCrossover = Binom(randGen); uniform_real_distribution<float> u(0,1); for (unsigned k=0; k<numCrossover; k++) { float rPos_Hao=chrLength*u(randGen); rPos.push_back(rPos_Hao); } rPos.push_back(chrLength); sort(rPos.begin(),rPos.end()); unsigned startPosParent=0; unsigned startPosMe=0; currentMotherChrom = (u(randGen)<0.5)?&mother.GenomePat[i]:&mother.GenomeMat[i]; for(unsigned j=0;j<rPos.size();j++){ unsigned numCopy=(currentMotherChrom->pos < rPos[j]).count()-startPosParent; tempPos.block(startPosMe,0,numCopy,1)=currentMotherChrom->pos.block(startPosParent,0,numCopy,1); tempOri.block(startPosMe,0,numCopy,1)=currentMotherChrom->ori.block(startPosParent,0,numCopy,1); currentMotherChrom= (currentMotherChrom==&mother.GenomePat[i])?&mother.GenomeMat[i]:&mother.GenomePat[i]; startPosParent=(currentMotherChrom->pos < rPos[j]).count(); startPosMe+=numCopy; tempPos(startPosMe)=rPos[j]; tempOri(startPosMe)=currentMotherChrom->ori(startPosParent-1); startPosMe++; } // unsigned posLengthMinusOne=startPosMe-1; // unsigned nonzero=(tempPos.block(1,0,posLengthMinusOne,1)-tempPos.block(0,0,posLengthMinusOne,1)).count()+1; // GenomeMat[i].pos.resize(nonzero-1); // GenomeMat[i].ori.resize(nonzero-1); unsigned keep=0; GenomeMat[i].pos.resize(startPosMe); GenomeMat[i].ori.resize(startPosMe); GenomeMat[i].pos[0]=tempPos[0]; GenomeMat[i].ori[0]=tempOri[0]; for(unsigned m=1;m < startPosMe-1; m++){ if(tempOri[m]!=tempOri[m-1]){ keep=keep+1; GenomeMat[i].pos[keep]=tempPos[m]; GenomeMat[i].ori[keep]=tempOri[m]; } } unsigned PosOriSize=keep+1; GenomeMat[i].pos.conservativeResize(PosOriSize); GenomeMat[i].ori.conservativeResize(PosOriSize); } }
unsigned long int kNN_pondere_Weights::NumComb_GeneralWeightsGeneralComparison(int NumPoint, bool GreaterThan, bool strict) { if (!GreaterThan) return Binom(m, k) - NumComb_GeneralWeightsGeneralComparison(NumPoint, !GreaterThan, !strict); // Terminal Cases if (k == 1) { unsigned long int Answer = m; if (strict) { for (int i = 0; i < m; i++) if (W[NumPoint][i] <= s) Answer--; } else for (int i = 0; i < m; i++) if (W[NumPoint][i] < s) Answer--; return Answer; } if (m == k) { long double TotalWeight = 0; for (int i = 0; i < m; i++) TotalWeight += W[NumPoint][i]; if (strict) if (TotalWeight <= s) return 0; else return 1; else if (TotalWeight < s) return 0; else return 1; } // General Cases if (unsorted<double>(W[NumPoint], W[NumPoint] + m)) std::sort(W[NumPoint], W[NumPoint] + m); if (W[NumPoint][0] >= 0) // All weights are non negative return NumComb_positiveWeightsGeneralComparison(NumPoint, GreaterThan, strict); if (W[NumPoint][m - 1] <= 0) // All weights are negatice { unsigned long int Result; s = -s; for (int i = 0; i < m; i++) W[NumPoint][i] = -W[NumPoint][i]; Result = Binom(m, k) - NumComb_positiveWeightsGeneralComparison(NumPoint, GreaterThan, !strict); for (int i = 0; i < m; i++) W[NumPoint][i] = -W[NumPoint][i]; s = -s; return Result; } unsigned long int Result = 0; s -= W[NumPoint][m - 1]; m--; k--; Result += NumComb_GeneralWeightsGeneralComparison(NumPoint, GreaterThan, strict); k++; s += W[NumPoint][m]; Result += NumComb_GeneralWeightsGeneralComparison(NumPoint, GreaterThan, strict); m++; return Result; }
unsigned long int kNN_pondere_Weights::NumComb_positiveWeightsGeneralComparison(int NumPoint, bool GreaterThan, bool strict) { if (!GreaterThan) return Binom(m, k) - NumComb_positiveWeightsGeneralComparison(NumPoint, !GreaterThan, !strict); if (unsorted<double>(W[NumPoint], W[NumPoint] + m)) std::sort(W[NumPoint], W[NumPoint] + m); // Terminal cases if (k == 1) { unsigned long int Answer = m; for (int i = 0; i < m; i++) if (strict) { if (W[NumPoint][i] <= s) Answer--; } else if (W[NumPoint][i] < s) Answer--; return Answer; } if (m == k) { long double TotalW = 0; for (int i = 0; i < m; i++) TotalW += W[NumPoint][i]; if (strict) if (TotalW <= s) return 0; else return 1; else if (TotalW < s) return 0; else return 1; } int BreakIndex = -1; double PartialWeight = 0; if (!strict) while ((BreakIndex < m) && (PartialWeight < s)) { BreakIndex++; PartialWeight += W[NumPoint][BreakIndex]; } else while ((BreakIndex < m) && (PartialWeight <= s)) { BreakIndex++; PartialWeight += W[NumPoint][BreakIndex]; } if (BreakIndex < k) return Binom(m, k); if (BreakIndex == m) return 0; // Non terminal Cases unsigned long int Result = 0; for (int i = BreakIndex; i < m; i++) { k--; s -= W[NumPoint][i]; int Ex_m = m; m = i; Result += NumComb_positiveWeightsGeneralComparison(NumPoint, GreaterThan, strict); m = Ex_m; s += W[NumPoint][i]; k++; } return Result; }