void bitVectorInitravSpecial(unsigned int **bitVectors, nodeptr p, int numsp, unsigned int vectorLength, hashtable *h, int treeNumber, int function, branchInfo *bInf, int *countBranches, int treeVectorLength, boolean traverseOnly, boolean computeWRF) { if(isTip(p->number, numsp)) return; else { nodeptr q = p->next; do { bitVectorInitravSpecial(bitVectors, q->back, numsp, vectorLength, h, treeNumber, function, bInf, countBranches, treeVectorLength, traverseOnly, computeWRF); q = q->next; } while(q != p); newviewBipartitions(bitVectors, p, numsp, vectorLength); assert(p->xBips); assert(!traverseOnly); if(!(isTip(p->back->number, numsp))) { unsigned int *toInsert = bitVectors[p->number]; hashNumberType position = p->hash % h->tableSize; assert(!(toInsert[0] & 1)); assert(!computeWRF); switch(function) { case BIPARTITIONS_RF: insertHashRF(toInsert, h, vectorLength, treeNumber, treeVectorLength, position, 0, computeWRF); *countBranches = *countBranches + 1; break; default: assert(0); } } } }
static void newviewBipartitions(unsigned int **bitVectors, nodeptr p, int numsp, unsigned int vectorLength) { if(isTip(p->number, numsp)) return; { nodeptr q = p->next->back, r = p->next->next->back; unsigned int *vector = bitVectors[p->number], *left = bitVectors[q->number], *right = bitVectors[r->number]; unsigned int i; assert(processID == 0); while(!p->xBips) { if(!p->xBips) getxnodeBips(p); } p->hash = q->hash ^ r->hash; if(isTip(q->number, numsp) && isTip(r->number, numsp)) { for(i = 0; i < vectorLength; i++) vector[i] = left[i] | right[i]; } else { if(isTip(q->number, numsp) || isTip(r->number, numsp)) { if(isTip(r->number, numsp)) { nodeptr tmp = r; r = q; q = tmp; } while(!r->xBips) { if(!r->xBips) newviewBipartitions(bitVectors, r, numsp, vectorLength); } for(i = 0; i < vectorLength; i++) vector[i] = left[i] | right[i]; } else { while((!r->xBips) || (!q->xBips)) { if(!q->xBips) newviewBipartitions(bitVectors, q, numsp, vectorLength); if(!r->xBips) newviewBipartitions(bitVectors, r, numsp, vectorLength); } for(i = 0; i < vectorLength; i++) vector[i] = left[i] | right[i]; } } } }
static int bitVectorTraversePlausibility(unsigned int **bitVectors, nodeptr p, int numsp, unsigned int vectorLength, hashtable *h, int *countBranches, int firstTaxon, tree *tr, boolean multifurcating) { /* trivial bipartition */ if(isTip(p->number, numsp)) return 0; else { int found = 0; nodeptr q = p->next; /* recursively descend into the tree and get the bips of all subtrees first */ do { found = found + bitVectorTraversePlausibility(bitVectors, q->back, numsp, vectorLength, h, countBranches, firstTaxon, tr, multifurcating); q = q->next; } while(q != p); /* compute the bipartition induced by the current branch p, p->back, here we invoke two different functions, depending on whether we are dealing with a multi-furcating or bifurcating tree. */ if(multifurcating) newviewBipartitionsMultifurcating(bitVectors, p, numsp, vectorLength); else newviewBipartitions(bitVectors, p, numsp, vectorLength); assert(p->x); /* if p->back does not lead to a tip this is an inner branch that induces a non-trivial bipartition. in this case we need to lookup if the induced bipartition is already contained in the hash table */ if(!(isTip(p->back->number, numsp))) { /* this is the bit vector to insert into the hash table */ unsigned int *toInsert = bitVectors[p->number]; /* compute the hash number on that bit vector */ hashNumberType position = oat_hash((unsigned char *)toInsert, sizeof(unsigned int) * vectorLength) % h->tableSize; /* each bipartition can be stored in two forms (the two bit-wise complements we always canonically store that version of the bit-vector that does not contain the first taxon of the small tree, we use an assertion to make sure that all is correct */ assert(!(toInsert[(firstTaxon - 1) / MASK_LENGTH] & mask32[(firstTaxon - 1) % MASK_LENGTH])); /* increment the branch counter to assure that all inner branches are traversed */ *countBranches = *countBranches + 1; /* now look up this bipartition in the hash table, If it is present the number of shared bipartitions between the small and the big tree is incremented by 1 */ found = found + findHash(toInsert, h, vectorLength, position); } return found; } }