BipartitionList::BipartitionList(const BipartitionList& bipL) : bitBipartitionList_(), elements_(bipL.elements_), sorted_(bipL.sorted_) { size_t lword = static_cast<size_t>(BipartitionTools::LWORD); size_t nbword = (bipL.getNumberOfElements() + lword - 1) / lword; size_t nbint = nbword * lword / (CHAR_BIT * sizeof(int)); bitBipartitionList_.resize(bipL.getNumberOfBipartitions()); vector<int*> bitBipL = bipL.getBitBipartitionList(); for (size_t i = 0; i < bipL.getNumberOfBipartitions(); i++) { bitBipartitionList_[i] = new int[nbint]; for (size_t j = 0; j < nbint; j++) { bitBipartitionList_[i][j] = bitBipL[i][j]; } } }
BipartitionList::BipartitionList(const BipartitionList & bipL) { unsigned int lword = BipartitionTools::LWORD; unsigned int nbword = (bipL.getNumberOfElements() + lword - 1) / lword; unsigned int nbint = nbword * lword / (CHAR_BIT * sizeof(int)); _bitBipartitionList.resize(bipL.getNumberOfBipartitions()); vector<int*> bitBipL = bipL.getBitBipartitionList(); for(unsigned int i = 0; i < bipL.getNumberOfBipartitions(); i++) { _bitBipartitionList[i] = new int[nbint]; for(unsigned int j = 0; j < nbint; j++) { _bitBipartitionList[i][j] = bitBipL[i][j]; } } _elements = bipL._elements; _sorted = bipL._sorted; }
TreeTemplate<Node>* BipartitionList::toTree() const throw (Exception) { BipartitionList* sortedBipL; vector<int*> sortedBitBipL; int* bip; vector<Node*> vecNd, sonNd; vector<bool> alive; size_t lword, nbword, nbint, ii; /* check, copy and prepare bipartition list */ if (!BipartitionList::areAllCompatible()) throw Exception("Trying to build a tree from incompatible bipartitions"); sortedBipL = dynamic_cast<BipartitionList*>(clone()); for (size_t i = 0; i < sortedBipL->getNumberOfBipartitions(); i++) { if (sortedBipL->getPartitionSize(i) > sortedBipL->getNumberOfElements() / 2) sortedBipL->flip(i); } sortedBipL->sortByPartitionSize(); sortedBipL->removeRedundantBipartitions(); sortedBitBipL = sortedBipL->getBitBipartitionList(); for (size_t i = 0; i < sortedBipL->getNumberOfBipartitions(); i++) { alive.push_back(true); } vecNd.resize(sortedBipL->getNumberOfBipartitions() + 1); lword = static_cast<size_t>(BipartitionTools::LWORD); nbword = (elements_.size() + lword - 1) / lword; nbint = nbword * lword / (CHAR_BIT * sizeof(int)); bip = new int[1]; bip[0] = 0; /* main loop: create one node per bipartition */ for (size_t i = 0; i < sortedBipL->getNumberOfBipartitions(); i++) { if (sortedBipL->getPartitionSize(i) == 1) { // terminal for (size_t j = 0; j < sortedBipL->getNumberOfElements(); j++) { if (BipartitionTools::testBit(sortedBitBipL[i], static_cast<int>(j))) { vecNd[i] = new Node(elements_[j]); break; } } } else { // internal sonNd.clear(); for (size_t j = 0; j < i; j++) { if (alive[j]) { for (ii = 0; ii < nbint; ii++) { BipartitionTools::bitOr(bip, sortedBitBipL[j] + ii, sortedBitBipL[i] + ii, 1); if (bip[0] != sortedBitBipL[i][ii]) break; } if (ii == nbint) { sonNd.push_back(vecNd[j]); alive[j] = false; } } } vecNd[i] = new Node(); for (size_t k = 0; k < sonNd.size(); k++) { vecNd[i]->addSon(sonNd[k]); } } } /* create last node, which joins alive bipartitions = fatherless nodes */ Node* rootNd = new Node(); for (size_t i = 0; i < sortedBipL->getNumberOfBipartitions(); i++) { if (alive[i]) rootNd->addSon(vecNd[i]); } /* construct tree and return */ TreeTemplate<Node>* tr = new TreeTemplate<Node>(rootNd); tr->resetNodesId(); delete sortedBipL; return tr; }
BipartitionList* TreeTools::bipartitionOccurrences(const vector<Tree*>& vecTr, vector<size_t>& bipScore) { vector<BipartitionList*> vecBipL; BipartitionList* mergedBipL; vector<size_t> bipSize; size_t nbBip; /* build and merge bipartitions */ for (size_t i = 0; i < vecTr.size(); i++) { vecBipL.push_back(new BipartitionList(*vecTr[i])); } mergedBipL = BipartitionTools::mergeBipartitionLists(vecBipL); for (size_t i = 0; i < vecTr.size(); i++) { delete vecBipL[i]; } mergedBipL->removeTrivialBipartitions(); nbBip = mergedBipL->getNumberOfBipartitions(); bipScore.clear(); for (size_t i = 0; i < nbBip; i++) { bipSize.push_back(mergedBipL->getPartitionSize(i)); bipScore.push_back(1); } /* compare bipartitions */ for (size_t i = nbBip; i > 0; i--) { if (bipScore[i - 1] == 0) continue; for (size_t j = i - 1; j > 0; j--) { if (bipScore[j - 1] && bipSize[i - 1] == bipSize[j - 1] && mergedBipL->areIdentical(i - 1, j - 1)) { bipScore[i - 1]++; bipScore[j - 1] = 0; } } } /* keep only distinct bipartitions */ for (size_t i = nbBip; i > 0; i--) { if (bipScore[i - 1] == 0) { bipScore.erase(bipScore.begin() + static_cast<ptrdiff_t>(i - 1)); mergedBipL->deleteBipartition(i - 1); } } /* add terminal branches */ mergedBipL->addTrivialBipartitions(false); for (size_t i = 0; i < mergedBipL->getNumberOfElements(); i++) { bipScore.push_back(vecTr.size()); } return mergedBipL; }