static inline unsigned int evaluatePopcount(INT_TYPE v_N, char *precomputed) { #ifdef __AVX unsigned long int res[4] __attribute__ ((aligned (BYTE_ALIGNMENT))); unsigned int a, b; _mm256_store_pd((double*)res, v_N); a = __builtin_popcountl(res[0]) + __builtin_popcountl(res[1]); b = __builtin_popcountl(res[2]) + __builtin_popcountl(res[3]); return (a + b); #else unsigned int sum = 0, counts[INTS_PER_VECTOR] __attribute__ ((aligned (BYTE_ALIGNMENT))); VECTOR_STORE((CAST)counts, v_N); sum += BIT_COUNT(counts[0], precomputed) + BIT_COUNT(counts[1], precomputed); sum += BIT_COUNT(counts[2], precomputed) + BIT_COUNT(counts[3], precomputed); return sum; #endif }
namespace Flags { enum unit_control_flags : word_flags { _unit_control_crouch_bit, _unit_control_jump_bit, _unit_control_user1_bit, _unit_control_user2_bit, _unit_control_light_bit, _unit_control_exact_facing_bit, _unit_control_action_bit, _unit_control_melee_bit,//_unit_control_equipment_bit, // debug strings still list this as 'equipment', but usage is melee _unit_control_look_dont_turn_bit, _unit_control_force_alert_bit, _unit_control_reload_bit, _unit_control_primary_trigger_bit, _unit_control_secondary_trigger_bit, _unit_control_grenade_bit, _unit_control_swap_weapon_bit, k_number_of_unit_control_flags, // NUMBER_OF_UNIT_CONTROL_FLAGS // There's technically room left for one more control flag _unit_control_unused_bit = k_number_of_unit_control_flags, // If we in fact do use the above unused bit, editor code will need to have their VALID_FLAGS updated to test with this k_number_of_unit_control_flags_yelo, }; BOOST_STATIC_ASSERT( k_number_of_unit_control_flags_yelo <= BIT_COUNT(word_flags) ); };
static void VerifyFlagsFieldDefinition(const tag_field& field, const tag_block_definition* block_definition) { auto* definition = field.Definition<string_list>(); VerifyStringListDefinition(definition, block_definition, "flags"); YELO_ASSERT_DISPLAY(definition->count<=BIT_COUNT(TFlags), "invalid string list specified for '%s' in block %s.", field.name, block_definition->name); // NOTE: added owner block name to info }
namespace Flags { enum { _build_cache_file_begin_building_yelo_bit, _build_cache_file_begin_mod_sets_create_anew_bit, _build_cache_file_begin_mod_sets_store_scenario_resources_bit, _build_cache_file_begin_use_memory_upgrades_bit, _build_cache_file_begin_dump_tag_group_allocation_stats_bit, k_number_of_build_cache_file_begin_flags }; BOOST_STATIC_ASSERT(k_number_of_build_cache_file_begin_flags <= BIT_COUNT(byte)); }
void *init_and_intersection_leaf_node(root_node result_set, leaf_node base, leaf_node other) { unsigned long data; leaf_node leaf; data = base->data & other->data; if (!data) return (void*)NULL; leaf = (leaf_node)init_leaf_node(base->offset); leaf->data = data; result_set->size += BIT_COUNT(leaf->data); return (void*)leaf; }
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 void newviewParsimonyIterativeFast(tree *tr) { int model, *ti = tr->ti, count = ti[0], index; for(index = 4; index < count; index += 4) { unsigned int totalScore = 0; size_t pNumber = (size_t)ti[index], qNumber = (size_t)ti[index + 1], rNumber = (size_t)ti[index + 2]; for(model = 0; model < tr->NumberOfModels; model++) { size_t k, states = tr->partitionData[model].states, width = tr->partitionData[model].parsimonyLength; unsigned int i; switch(states) { case 2: { parsimonyNumber *left[2], *right[2], *this[2]; parsimonyNumber o_A, o_C, t_A, t_C, t_N; 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 * rNumber) + width * k]); this[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]; o_A = left[0][i] | right[0][i]; o_C = left[1][i] | right[1][i]; t_N = ~(t_A | t_C); this[0][i] = t_A | (t_N & o_A); this[1][i] = t_C | (t_N & o_C); totalScore += BIT_COUNT(t_N, tr->bits_in_16bits); } } break; case 4: { parsimonyNumber *left[4], *right[4], *this[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 * rNumber) + width * k]); this[k] = &(tr->partitionData[model].parsVect[(width * 4 * pNumber) + width * k]); } parsimonyNumber o_A, o_C, o_G, o_T, t_A, t_C, t_G, t_T, t_N; 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]; o_A = left[0][i] | right[0][i]; o_C = left[1][i] | right[1][i]; o_G = left[2][i] | right[2][i]; o_T = left[3][i] | right[3][i]; t_N = ~(t_A | t_C | t_G | t_T); this[0][i] = t_A | (t_N & o_A); this[1][i] = t_C | (t_N & o_C); this[2][i] = t_G | (t_N & o_G); this[3][i] = t_T | (t_N & o_T); totalScore += BIT_COUNT(t_N, tr->bits_in_16bits); } } break; case 20: { parsimonyNumber *left[20], *right[20], *this[20]; parsimonyNumber o_A[20], t_A[20], t_N; 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 * rNumber) + width * k]); this[k] = &(tr->partitionData[model].parsVect[(width * 20 * pNumber) + width * k]); } for(i = 0; i < width; i++) { size_t k; t_N = 0; for(k = 0; k < 20; k++) { t_A[k] = left[k][i] & right[k][i]; o_A[k] = left[k][i] | right[k][i]; t_N = t_N | t_A[k]; } t_N = ~t_N; for(k = 0; k < 20; k++) this[k][i] = t_A[k] | (t_N & o_A[k]); totalScore += BIT_COUNT(t_N, tr->bits_in_16bits); } } break; default: { parsimonyNumber *left[32], *right[32], *this[32]; parsimonyNumber o_A[32], t_A[32], t_N; 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 * rNumber) + width * k]); this[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[k] = left[k][i] & right[k][i]; o_A[k] = left[k][i] | right[k][i]; t_N = t_N | t_A[k]; } t_N = ~t_N; for(k = 0; k < states; k++) this[k][i] = t_A[k] | (t_N & o_A[k]); totalScore += BIT_COUNT(t_N, tr->bits_in_16bits); } } } } tr->parsimonyScore[pNumber] = totalScore + tr->parsimonyScore[rNumber] + tr->parsimonyScore[qNumber]; } }
static void pawn_comp_info(pawn_info_t * info, const board_t * board) { int colour; int file, rank; int me, opp; const sq_t * ptr; int sq; bool backward, candidate, doubled, isolated, open, passed; int t1, t2; int n; int bits; int opening[ColourNb], endgame[ColourNb]; int flags[ColourNb]; int file_bits[ColourNb]; int passed_bits[ColourNb]; int single_file[ColourNb]; ASSERT(info!=NULL); ASSERT(board!=NULL); // pawn_file[] #if DEBUG for (colour = 0; colour < ColourNb; colour++) { int pawn_file[FileNb]; me = colour; for (file = 0; file < FileNb; file++) { pawn_file[file] = 0; } for (ptr = &board->pawn[me][0]; (sq=*ptr) != SquareNone; ptr++) { file = SQUARE_FILE(sq); rank = PAWN_RANK(sq,me); ASSERT(file>=FileA&&file<=FileH); ASSERT(rank>=Rank2&&rank<=Rank7); pawn_file[file] |= BIT(rank); } for (file = 0; file < FileNb; file++) { if (board->pawn_file[colour][file] != pawn_file[file]) my_fatal("board->pawn_file[][]\n"); } } #endif // init for (colour = 0; colour < ColourNb; colour++) { opening[colour] = 0; endgame[colour] = 0; flags[colour] = 0; file_bits[colour] = 0; passed_bits[colour] = 0; single_file[colour] = SquareNone; } // features and scoring for (colour = 0; colour < ColourNb; colour++) { me = colour; opp = COLOUR_OPP(me); for (ptr = &board->pawn[me][0]; (sq=*ptr) != SquareNone; ptr++) { // init file = SQUARE_FILE(sq); rank = PAWN_RANK(sq,me); ASSERT(file>=FileA&&file<=FileH); ASSERT(rank>=Rank2&&rank<=Rank7); // flags file_bits[me] |= BIT(file); if (rank == Rank2) flags[me] |= BackRankFlag; // features backward = false; candidate = false; doubled = false; isolated = false; open = false; passed = false; t1 = board->pawn_file[me][file-1] | board->pawn_file[me][file+1]; t2 = board->pawn_file[me][file] | BitRev[board->pawn_file[opp][file]]; // doubled if ((board->pawn_file[me][file] & BitLT[rank]) != 0) { doubled = true; } // isolated and backward if (t1 == 0) { isolated = true; } else if ((t1 & BitLE[rank]) == 0) { backward = true; // really backward? if ((t1 & BitRank1[rank]) != 0) { ASSERT(rank+2<=Rank8); if (((t2 & BitRank1[rank]) | ((BitRev[board->pawn_file[opp][file-1]] | BitRev[board->pawn_file[opp][file+1]]) & BitRank2[rank])) == 0) { backward = false; } } else if (rank == Rank2 && ((t1 & BitEQ[rank+2]) != 0)) { ASSERT(rank+3<=Rank8); if (((t2 & BitRank2[rank]) | ((BitRev[board->pawn_file[opp][file-1]] | BitRev[board->pawn_file[opp][file+1]]) & BitRank3[rank])) == 0) { backward = false; } } } // open, candidate and passed if ((t2 & BitGT[rank]) == 0) { open = true; if (((BitRev[board->pawn_file[opp][file-1]] | BitRev[board->pawn_file[opp][file+1]]) & BitGT[rank]) == 0) { passed = true; passed_bits[me] |= BIT(file); } else { // candidate? n = 0; n += BIT_COUNT(board->pawn_file[me][file-1]&BitLE[rank]); n += BIT_COUNT(board->pawn_file[me][file+1]&BitLE[rank]); n -= BIT_COUNT(BitRev[board->pawn_file[opp][file-1]]&BitGT[rank]); n -= BIT_COUNT(BitRev[board->pawn_file[opp][file+1]]&BitGT[rank]); if (n >= 0) { // safe? n = 0; n += BIT_COUNT(board->pawn_file[me][file-1]&BitEQ[rank-1]); n += BIT_COUNT(board->pawn_file[me][file+1]&BitEQ[rank-1]); n -= BIT_COUNT(BitRev[board->pawn_file[opp][file-1]]&BitEQ[rank+1]); n -= BIT_COUNT(BitRev[board->pawn_file[opp][file+1]]&BitEQ[rank+1]); if (n >= 0) candidate = true; } } } // outposts if (me == White) { if (SQUARE_IS_OK(sq+15)) { if (WEAK_SQUARE_BLACK(sq+15)) opening[White] += OutpostMatrix[White][SQUARE_TO_64(sq+15)]; else opening[White] += (OutpostMatrix[White][SQUARE_TO_64(sq+15)]+1)/2; } if (SQUARE_IS_OK(sq+17)) { if (WEAK_SQUARE_BLACK(sq+17)) opening[White] += OutpostMatrix[White][SQUARE_TO_64(sq+17)]; else opening[White] += (OutpostMatrix[White][SQUARE_TO_64(sq+17)]+1)/2; } } else { if (SQUARE_IS_OK(sq-15)) { if (WEAK_SQUARE_WHITE(sq-15)) opening[Black] += OutpostMatrix[Black][SQUARE_TO_64(sq-15)]; else opening[Black] += (OutpostMatrix[Black][SQUARE_TO_64(sq-15)]+1)/2; } if (SQUARE_IS_OK(sq-17)) { if (WEAK_SQUARE_WHITE(sq-17)) opening[Black] += OutpostMatrix[Black][SQUARE_TO_64(sq-17)]; else opening[Black] += (OutpostMatrix[Black][SQUARE_TO_64(sq-17)]+1)/2; } } // score if (doubled) { opening[me] -= DoubledOpening; endgame[me] -= DoubledEndgame; } if (isolated) { if (open) { opening[me] -= IsolatedOpeningOpen; endgame[me] -= IsolatedEndgame; } else { opening[me] -= IsolatedOpening; endgame[me] -= IsolatedEndgame; } } if (backward) { if (open) { opening[me] -= BackwardOpeningOpen; endgame[me] -= BackwardEndgame; } else { opening[me] -= BackwardOpening; endgame[me] -= BackwardEndgame; } } if (candidate) { opening[me] += quad(CandidateOpeningMin,CandidateOpeningMax,rank); endgame[me] += quad(CandidateEndgameMin,CandidateEndgameMax,rank); } // this was moved to the dynamic evaluation /* if (passed) { opening[me] += quad(PassedOpeningMin,PassedOpeningMax,rank); endgame[me] += quad(PassedEndgameMin,PassedEndgameMax,rank); } */ } } // store info info->opening = ((opening[White] - opening[Black]) * PawnStructureWeight) / 256; info->endgame = ((endgame[White] - endgame[Black]) * PawnStructureWeight) / 256; for (colour = 0; colour < ColourNb; colour++) { me = colour; opp = COLOUR_OPP(me); // draw flags bits = file_bits[me]; if (bits != 0 && (bits & (bits-1)) == 0) { // one set bit file = BIT_FIRST(bits); rank = BIT_FIRST(board->pawn_file[me][file]); ASSERT(rank>=Rank2); if (((BitRev[board->pawn_file[opp][file-1]] | BitRev[board->pawn_file[opp][file+1]]) & BitGT[rank]) == 0) { rank = BIT_LAST(board->pawn_file[me][file]); single_file[me] = SQUARE_MAKE(file,rank); } } info->flags[colour] = flags[colour]; info->passed_bits[colour] = passed_bits[colour]; info->single_file[colour] = single_file[colour]; } }
void plausibilityChecker(tree *tr, analdef *adef) { FILE *treeFile, *rfFile; tree *smallTree = (tree *)rax_malloc(sizeof(tree)); char rfFileName[1024]; /* init hash table for big reference tree */ hashtable *h = initHashTable(tr->mxtips * 2 * 2); /* init the bit vectors we need for computing and storing bipartitions during the tree traversal */ unsigned int vLength, **bitVectors = initBitVector(tr, &vLength); int numberOfTreesAnalyzed = 0, branchCounter = 0, i; double avgRF = 0.0; /* set up an output file name */ strcpy(rfFileName, workdir); strcat(rfFileName, "RAxML_RF-Distances."); strcat(rfFileName, run_id); rfFile = myfopen(rfFileName, "wb"); assert(adef->mode == PLAUSIBILITY_CHECKER); /* open the big reference tree file and parse it */ treeFile = myfopen(tree_file, "r"); printBothOpen("Parsing reference tree %s\n", tree_file); treeReadLen(treeFile, tr, FALSE, TRUE, TRUE, adef, TRUE, FALSE); assert(tr->mxtips == tr->ntips); printBothOpen("The reference tree has %d tips\n", tr->ntips); fclose(treeFile); /* extract all induced bipartitions from the big tree and store them in the hastable */ bitVectorInitravSpecial(bitVectors, tr->nodep[1]->back, tr->mxtips, vLength, h, 0, BIPARTITIONS_RF, (branchInfo *)NULL, &branchCounter, 1, FALSE, FALSE); assert(branchCounter == tr->mxtips - 3); /* now see how many small trees we have */ treeFile = getNumberOfTrees(tr, bootStrapFile, adef); checkTreeNumber(tr->numberOfTrees, bootStrapFile); /* allocate a data structure for parsing the potentially mult-furcating tree */ allocateMultifurcations(tr, smallTree); /* loop over all small trees */ for(i = 0; i < tr->numberOfTrees; i++) { int numberOfSplits = readMultifurcatingTree(treeFile, smallTree, adef, TRUE); if(numberOfSplits > 0) { unsigned int entryCount = 0, k, j, *masked = (unsigned int *)rax_calloc(vLength, sizeof(unsigned int)), *smallTreeMask = (unsigned int *)rax_calloc(vLength, sizeof(unsigned int)); hashtable *rehash = initHashTable(tr->mxtips * 2 * 2); double rf, maxRF; int bCounter = 0, bips, firstTaxon, taxa = 0; if(numberOfTreesAnalyzed % 100 == 0) printBothOpen("Small tree %d has %d tips and %d bipartitions\n", i, smallTree->ntips, numberOfSplits); /* compute the maximum RF distance for computing the relative RF distance later-on */ /* note that here we need to pay attention, since the RF distance is not normalized by 2 * (n-3) but we need to account for the fact that the multifurcating small tree will potentially contain less bipartitions. Hence the normalization factor is obtained as 2 * numberOfSplits, where numberOfSplits is the number of bipartitions in the small tree. */ maxRF = (double)(2 * numberOfSplits); /* now set up a bit mask where only the bits are set to one for those taxa that are actually present in the small tree we just read */ /* note that I had to apply some small changes to this function to make it work for multi-furcating trees ! */ setupMask(smallTreeMask, smallTree->start, smallTree->mxtips); setupMask(smallTreeMask, smallTree->start->back, smallTree->mxtips); /* now get the index of the first taxon of the small tree. we will use this to unambiguously store the bipartitions */ firstTaxon = smallTree->start->number; /* make sure that this bit vector is set up correctly, i.e., that it contains as many non-zero bits as there are taxa in this small tree */ for(j = 0; j < vLength; j++) taxa += BIT_COUNT(smallTreeMask[j]); assert(taxa == smallTree->ntips); /* now re-hash the big tree by applying the above bit mask */ /* loop over hash table */ for(k = 0, entryCount = 0; k < h->tableSize; k++) { if(h->table[k] != NULL) { entry *e = h->table[k]; /* we resolve collisions by chaining, hence the loop here */ do { unsigned int *bitVector = e->bitVector; hashNumberType position; int count = 0; /* double check that our tree mask contains the first taxon of the small tree */ assert(smallTreeMask[(firstTaxon - 1) / MASK_LENGTH] & mask32[(firstTaxon - 1) % MASK_LENGTH]); /* if the first taxon is set then we will re-hash the bit-wise complement of the bit vector. The count variable is used for a small optimization */ if(bitVector[(firstTaxon - 1) / MASK_LENGTH] & mask32[(firstTaxon - 1) % MASK_LENGTH]) { //hash complement for(j = 0; j < vLength; j++) { masked[j] = (~bitVector[j]) & smallTreeMask[j]; count += BIT_COUNT(masked[j]); } } else { //hash this vector for(j = 0; j < vLength; j++) { masked[j] = bitVector[j] & smallTreeMask[j]; count += BIT_COUNT(masked[j]); } } /* note that padding the last bits is not required because they are set to 0 automatically by smallTreeMask */ /* make sure that we will re-hash the canonic representation of the bipartition where the bit for firstTaxon is set to 0! */ assert(!(masked[(firstTaxon - 1) / MASK_LENGTH] & mask32[(firstTaxon - 1) % MASK_LENGTH])); /* only if the masked bipartition of the large tree is a non-trivial bipartition (two or more bits set to 1 will we re-hash it */ if(count > 1) { /* compute hash */ position = oat_hash((unsigned char *)masked, sizeof(unsigned int) * vLength); position = position % rehash->tableSize; /* re-hash to the new hash table that contains the bips of the large tree, pruned down to the taxa contained in the small tree */ insertHashPlausibility(masked, rehash, vLength, position); } entryCount++; e = e->next; } while(e != NULL); } } /* make sure that we tried to re-hash all bipartitions of the original tree */ assert(entryCount == (unsigned int)(tr->mxtips - 3)); /* now traverse the small tree and count how many bipartitions it shares with the corresponding induced tree from the large tree */ /* the following function also had to be modified to account for multi-furcating trees ! */ bips = bitVectorTraversePlausibility(bitVectors, smallTree->start->back, smallTree->mxtips, vLength, rehash, &bCounter, firstTaxon, smallTree, TRUE); /* compute the relative RF */ rf = (double)(2 * (numberOfSplits - bips)) / maxRF; assert(numberOfSplits >= bips); assert(rf <= 1.0); avgRF += rf; if(numberOfTreesAnalyzed % 100 == 0) printBothOpen("Relative RF tree %d: %f\n\n", i, rf); fprintf(rfFile, "%d %f\n", i, rf); /* I also modified this assertion, we nee to make sure here that we checked all non-trivial splits/bipartitions in the multi-furcating tree whech can be less than n - 3 ! */ assert(bCounter == numberOfSplits); /* free masks and hast table for this iteration */ rax_free(smallTreeMask); rax_free(masked); freeHashTable(rehash); rax_free(rehash); numberOfTreesAnalyzed++; } } printBothOpen("Number of small trees skipped: %d\n\n", tr->numberOfTrees - numberOfTreesAnalyzed); printBothOpen("Average RF distance %f\n\n", avgRF / (double)numberOfTreesAnalyzed); printBothOpen("Total execution time: %f secs\n\n", gettime() - masterTime); printBothOpen("\nFile containing all %d pair-wise RF distances written to file %s\n\n", numberOfTreesAnalyzed, rfFileName); fclose(treeFile); fclose(rfFile); /* free the data structure used for parsing the potentially multi-furcating tree */ freeMultifurcations(smallTree); rax_free(smallTree); freeBitVectors(bitVectors, 2 * tr->mxtips); rax_free(bitVectors); freeHashTable(h); rax_free(h); }