static void restoreTreeParsimony(tree *tr, nodeptr p, nodeptr q) { nodeptr r = q->back; int counter = 4; hookupDefault(p->next, q, tr->numBranches); hookupDefault(p->next->next, r, tr->numBranches); computeTraversalInfoParsimony(p, tr->ti, &counter, tr->mxtips, FALSE); tr->ti[0] = counter; newviewParsimonyIterativeFast(tr); }
static void newviewParsimony(tree *tr, nodeptr p) { if(p->number <= tr->mxtips) return; { int counter = 4; computeTraversalInfoParsimony(p, tr->ti, &counter, tr->mxtips, FALSE); tr->ti[0] = counter; newviewParsimonyIterativeFast(tr); } }
static unsigned int evaluateParsimonyIterativeFast(tree *tr) { size_t pNumber = (size_t)tr->ti[1], qNumber = (size_t)tr->ti[2]; int model; unsigned int bestScore = tr->bestParsimony, sum; if(tr->ti[0] > 4) newviewParsimonyIterativeFast(tr); sum = tr->parsimonyScore[pNumber] + tr->parsimonyScore[qNumber]; for(model = 0; model < tr->NumberOfModels; model++) { size_t k, states = tr->partitionData[model].states, width = tr->partitionData[model].parsimonyLength, i; switch(states) { case 2: { parsimonyNumber t_A, t_C, t_N, *left[2], *right[2]; for(k = 0; k < 2; k++) { left[k] = &(tr->partitionData[model].parsVect[(width * 2 * qNumber) + width * k]); right[k] = &(tr->partitionData[model].parsVect[(width * 2 * pNumber) + width * k]); } for(i = 0; i < width; i++) { t_A = left[0][i] & right[0][i]; t_C = left[1][i] & right[1][i]; t_N = ~(t_A | t_C); sum += BIT_COUNT(t_N, tr->bits_in_16bits); if(sum >= bestScore) return sum; } } break; case 4: { parsimonyNumber t_A, t_C, t_G, t_T, t_N, *left[4], *right[4]; for(k = 0; k < 4; k++) { left[k] = &(tr->partitionData[model].parsVect[(width * 4 * qNumber) + width * k]); right[k] = &(tr->partitionData[model].parsVect[(width * 4 * pNumber) + width * k]); } for(i = 0; i < width; i++) { t_A = left[0][i] & right[0][i]; t_C = left[1][i] & right[1][i]; t_G = left[2][i] & right[2][i]; t_T = left[3][i] & right[3][i]; t_N = ~(t_A | t_C | t_G | t_T); sum += BIT_COUNT(t_N, tr->bits_in_16bits); if(sum >= bestScore) return sum; } } break; case 20: { parsimonyNumber t_A, t_N, *left[20], *right[20]; for(k = 0; k < 20; k++) { left[k] = &(tr->partitionData[model].parsVect[(width * 20 * qNumber) + width * k]); right[k] = &(tr->partitionData[model].parsVect[(width * 20 * pNumber) + width * k]); } for(i = 0; i < width; i++) { t_N = 0; for(k = 0; k < 20; k++) { t_A = left[k][i] & right[k][i]; t_N = t_N | t_A; } t_N = ~t_N; sum += BIT_COUNT(t_N, tr->bits_in_16bits); if(sum >= bestScore) return sum; } } break; default: { parsimonyNumber t_A, t_N, *left[32], *right[32]; assert(states <= 32); for(k = 0; k < states; k++) { left[k] = &(tr->partitionData[model].parsVect[(width * states * qNumber) + width * k]); right[k] = &(tr->partitionData[model].parsVect[(width * states * pNumber) + width * k]); } for(i = 0; i < width; i++) { t_N = 0; for(k = 0; k < states; k++) { t_A = left[k][i] & right[k][i]; t_N = t_N | t_A; } t_N = ~t_N; sum += BIT_COUNT(t_N, tr->bits_in_16bits); if(sum >= bestScore) return sum; } } } } return sum; }
static unsigned int evaluateParsimonyIterativeFast(tree *tr) { INT_TYPE allOne = SET_ALL_BITS_ONE; size_t pNumber = (size_t)tr->ti[1], qNumber = (size_t)tr->ti[2]; int model; unsigned int bestScore = tr->bestParsimony, sum; if(tr->ti[0] > 4) newviewParsimonyIterativeFast(tr); sum = tr->parsimonyScore[pNumber] + tr->parsimonyScore[qNumber]; for(model = 0; model < tr->NumberOfModels; model++) { size_t k, states = tr->partitionData[model].states, width = tr->partitionData[model].parsimonyLength, i; switch(states) { case 2: { parsimonyNumber *left[2], *right[2]; for(k = 0; k < 2; k++) { left[k] = &(tr->partitionData[model].parsVect[(width * 2 * qNumber) + width * k]); right[k] = &(tr->partitionData[model].parsVect[(width * 2 * pNumber) + width * k]); } for(i = 0; i < width; i += INTS_PER_VECTOR) { INT_TYPE l_A = VECTOR_BIT_AND(VECTOR_LOAD((CAST)(&left[0][i])), VECTOR_LOAD((CAST)(&right[0][i]))), l_C = VECTOR_BIT_AND(VECTOR_LOAD((CAST)(&left[1][i])), VECTOR_LOAD((CAST)(&right[1][i]))), v_N = VECTOR_BIT_OR(l_A, l_C); v_N = VECTOR_AND_NOT(v_N, allOne); sum += evaluatePopcount(v_N, tr->bits_in_16bits); if(sum >= bestScore) return sum; } } break; case 4: { parsimonyNumber *left[4], *right[4]; for(k = 0; k < 4; k++) { left[k] = &(tr->partitionData[model].parsVect[(width * 4 * qNumber) + width * k]); right[k] = &(tr->partitionData[model].parsVect[(width * 4 * pNumber) + width * k]); } for(i = 0; i < width; i += INTS_PER_VECTOR) { INT_TYPE l_A = VECTOR_BIT_AND(VECTOR_LOAD((CAST)(&left[0][i])), VECTOR_LOAD((CAST)(&right[0][i]))), l_C = VECTOR_BIT_AND(VECTOR_LOAD((CAST)(&left[1][i])), VECTOR_LOAD((CAST)(&right[1][i]))), l_G = VECTOR_BIT_AND(VECTOR_LOAD((CAST)(&left[2][i])), VECTOR_LOAD((CAST)(&right[2][i]))), l_T = VECTOR_BIT_AND(VECTOR_LOAD((CAST)(&left[3][i])), VECTOR_LOAD((CAST)(&right[3][i]))), v_N = VECTOR_BIT_OR(VECTOR_BIT_OR(l_A, l_C), VECTOR_BIT_OR(l_G, l_T)); v_N = VECTOR_AND_NOT(v_N, allOne); sum += evaluatePopcount(v_N, tr->bits_in_16bits); if(sum >= bestScore) return sum; } } break; case 20: { parsimonyNumber *left[20], *right[20]; for(k = 0; k < 20; k++) { left[k] = &(tr->partitionData[model].parsVect[(width * 20 * qNumber) + width * k]); right[k] = &(tr->partitionData[model].parsVect[(width * 20 * pNumber) + width * k]); } for(i = 0; i < width; i += INTS_PER_VECTOR) { int j; INT_TYPE l_A, v_N = SET_ALL_BITS_ZERO; for(j = 0; j < 20; j++) { l_A = VECTOR_BIT_AND(VECTOR_LOAD((CAST)(&left[j][i])), VECTOR_LOAD((CAST)(&right[j][i]))); v_N = VECTOR_BIT_OR(l_A, v_N); } v_N = VECTOR_AND_NOT(v_N, allOne); sum += evaluatePopcount(v_N, tr->bits_in_16bits); if(sum >= bestScore) return sum; } } break; default: { parsimonyNumber *left[32], *right[32]; assert(states <= 32); for(k = 0; k < states; k++) { left[k] = &(tr->partitionData[model].parsVect[(width * states * qNumber) + width * k]); right[k] = &(tr->partitionData[model].parsVect[(width * states * pNumber) + width * k]); } for(i = 0; i < width; i += INTS_PER_VECTOR) { size_t j; INT_TYPE l_A, v_N = SET_ALL_BITS_ZERO; for(j = 0; j < states; j++) { l_A = VECTOR_BIT_AND(VECTOR_LOAD((CAST)(&left[j][i])), VECTOR_LOAD((CAST)(&right[j][i]))); v_N = VECTOR_BIT_OR(l_A, v_N); } v_N = VECTOR_AND_NOT(v_N, allOne); sum += evaluatePopcount(v_N, tr->bits_in_16bits); if(sum >= bestScore) return sum; } } } } return sum; }
void pllMakeParsimonyTreeFast(tree *tr) { nodeptr p, f; int i, nextsp, *perm = (int *)malloc((size_t)(tr->mxtips + 1) * sizeof(int)); unsigned int randomMP, startMP; assert(!tr->constrained); makePermutationFast(perm, tr->mxtips, tr); tr->ntips = 0; tr->nextnode = tr->mxtips + 1; buildSimpleTree(tr, perm[1], perm[2], perm[3]); f = tr->start; while(tr->ntips < tr->mxtips) { nodeptr q; tr->bestParsimony = INT_MAX; nextsp = ++(tr->ntips); p = tr->nodep[perm[nextsp]]; q = tr->nodep[(tr->nextnode)++]; p->back = q; q->back = p; if(tr->grouped) { int number = p->back->number; tr->constraintVector[number] = -9; } stepwiseAddition(tr, q, f->back); { nodeptr r = tr->insertNode->back; int counter = 4; hookupDefault(q->next, tr->insertNode, tr->numBranches); hookupDefault(q->next->next, r, tr->numBranches); computeTraversalInfoParsimony(q, tr->ti, &counter, tr->mxtips, FALSE); tr->ti[0] = counter; newviewParsimonyIterativeFast(tr); } } printf("ADD: %d\n", tr->bestParsimony); nodeRectifierPars(tr); randomMP = tr->bestParsimony; do { startMP = randomMP; nodeRectifierPars(tr); for(i = 1; i <= tr->mxtips + tr->mxtips - 2; i++) { rearrangeParsimony(tr, tr->nodep[i], 1, 20, FALSE); if(tr->bestParsimony < randomMP) { restoreTreeRearrangeParsimony(tr); randomMP = tr->bestParsimony; } } } while(randomMP < startMP); printf("OPT: %d\n", tr->bestParsimony); }
void TreeRandomizer::createStepwiseAdditionParsimonyTree(TreeAln &traln, ParallelSetup& pl ) { auto *tr = &(traln.getTrHandle()); auto *pr = &(traln.getPartitionsHandle()); assert(tr->fastParsimony == PLL_FALSE); nodeptr p, f; int nextsp; auto perm = std::vector<int>(tr->mxtips+1, 0); assert(!tr->constrained); makePermutationFast(perm.data(), tr->mxtips, tr); tr->ntips = 0; tr->nextnode = tr->mxtips + 1; buildSimpleTree(tr, pr, perm[1], perm[2], perm[3]); f = tr->start; while(tr->ntips < tr->mxtips) { nodeptr q; tr->bestParsimony = std::numeric_limits<nat>::max(); nextsp = ++(tr->ntips); p = tr->nodep[perm[nextsp]]; q = tr->nodep[(tr->nextnode)++]; p->back = q; q->back = p; if(tr->grouped) { int number = p->back->number; tr->constraintVector[number] = -9; } stepwiseAddition(tr, pr, q, f->back, pl); // std::cout << SyncOut() << "bestPars: "<< tr->bestParsimony << std::endl; { nodeptr r = tr->insertNode->back; int counter = 4; hookupDefault(q->next, tr->insertNode); hookupDefault(q->next->next, r); computeTraversalInfoParsimony(q, tr->ti, &counter, tr->mxtips, PLL_FALSE); tr->ti[0] = counter; newviewParsimonyIterativeFast(tr, pr); } } }