/// Check that any two present nodes are connected by a path of present nodes bool all_characters_connected(const Tree& T,dynamic_bitset<> present,const vector<int>& _ignore) { assert(present.size() == T.n_nodes()); //--------- set the ignored nodes to 'not present' -----------// dynamic_bitset<> ignore(present.size()); for(int i=0;i<_ignore.size();i++) { int n = _ignore[i]; present[n] = false; ignore[n] = true; } //---------- for each internal node... -------------// for(int n1=T.n_leaves(); n1<T.n_nodes(); n1++) { if (present[n1] or ignore[n1]) continue; //------- if it is '-' and not ignored ... -------// vector<const_nodeview> neighbors; append(T[n1].neighbors(),neighbors); assert(neighbors.size() == 3); //---- check the three attatched subtrees ... ----// int total=0; for(int i=0;i<neighbors.size();i++) { dynamic_bitset<> group = T.partition(n1,neighbors[i]); if (present.intersects(group)) total++; } //----- nodes should be present in only one. -----// if (total > 1) return false; } return true; }
static bool can_die_early(const NGHolder &g, const vector<StateInfo> &info, const dynamic_bitset<> &s, map<dynamic_bitset<>, u32> &visited, u32 age_limit) { if (contains(visited, s) && visited[s] >= age_limit) { /* we have already (or are in the process) of visiting here with a * looser limit. */ return false; } visited[s] = age_limit; if (s.none()) { DEBUG_PRINTF("dead\n"); return true; } if (age_limit == 0) { return false; } dynamic_bitset<> all_succ(s.size()); step(g, info, s, &all_succ); all_succ.reset(NODE_START_DOTSTAR); for (u32 i = 0; i < N_CHARS; i++) { dynamic_bitset<> next = all_succ; filter_by_reach(info, &next, CharReach(i)); if (can_die_early(g, info, next, visited, age_limit - 1)) { return true; } } return false; }
void connect_all_characters(const Tree& T,dynamic_bitset<>& present) { assert(present.size() == T.n_nodes()); //---------- for each internal node... -------------// for(int n1=T.n_leaves(); n1<T.n_nodes(); n1++) { if (present[n1]) continue; //------- if it is '-' and not ignored ... -------// vector<const_nodeview> neighbors; append(T[n1].neighbors(),neighbors); assert(neighbors.size() == 3); //---- check the three attatched subtrees ... ----// int total=0; for(int i=0;i<neighbors.size();i++) { dynamic_bitset<> group = T.partition(n1,neighbors[i]); if (present.intersects(group)) total++; } if (total > 1) present[n1] = true; } assert(all_characters_connected(T,present,vector<int>())); }
void print(const dynamic_bitset<>& items, ostream& out) { out << "{ "; for(dynamic_bitset<>::size_type i = items.find_first(); i != items.npos; i = items.find_next(i)){ out << i << " "; } out << "} -- " << items.count() << endl; }
uint32_t cFixedAlloc::findFirstOf(bool check, dynamic_bitset<>& bit) { for ( int i = 0; i < bit.size(); ++i ) { if ( bit[i] == check ) return i; } return bit.size() + 1; }
Partition::Partition(const vector<string>& n,const dynamic_bitset<>& g,const dynamic_bitset<>& mask) :names(n),group1((~ g) & mask),group2(g & mask) { assert(n.size() == g.size()); assert(g.size() == mask.size()); assert(not group1.intersects(group2)); }
vector<int> diffset_for_single_item(dynamic_bitset<> tids) { vector<int> diffset; dynamic_bitset<>::size_type size = tids.size(); for (dynamic_bitset<>::size_type i = 0; i < size; ++i) if ( ! tids.test(i)) diffset.push_back(i); return diffset; }
static std::string dumpStates(const dynamic_bitset<> &s) { std::ostringstream oss; for (size_t i = s.find_first(); i != s.npos; i = s.find_next(i)) { oss << i << " "; } return oss.str(); }
static flat_set<NFAVertex> getVertices(const dynamic_bitset<> &in, const vector<StateInfo> &info) { flat_set<NFAVertex> out; for (size_t i = in.find_first(); i != in.npos; i = in.find_next(i)) { out.insert(info[i].vertex); } return out; }
static void step(const NGHolder &g, const vector<StateInfo> &info, const dynamic_bitset<> &in, dynamic_bitset<> *out) { out->reset(); for (size_t i = in.find_first(); i != in.npos; i = in.find_next(i)) { NFAVertex u = info[i].vertex; for (auto v : adjacent_vertices_range(u, g)) { out->set(g[v].index); } } }
// functions /// \brief Size the wire usage according to the number of device tiles. void autosize(void) { // release any existing bitsets for(TileCount i; i < mBitsets.getSize(); i++) { if(mBitsets[i] != 0) { delete mBitsets[i]; mBitsets[i] = 0; } mTileDirty.reset(i); } // resize for the new dimensions TileCount tileCount = mTiles.getTileCount(); mBitsets.setSize(tileCount); for(TileCount i; i < tileCount; i++) mBitsets[i] = 0; mTileDirty.resize(tileCount); }
typename allocator<T>::dynamic_bitset allocator<T>::free_memory(const dynamic_bitset & memfree, dynamic_bitset && mask) { assert(memfree.size() == mask.size()); assert(memfree.count() + mask.count() <= memfree.size()); auto res = memfree | mask; # if DEBUG_SMA_TRACE_BITSET std::cout << "a=memfree: " << memfree << std::endl; std::cout << "b= mask: " << mask << std::endl; std::cout << "r= a | b: " << res << std::endl; # endif assert(memfree.count() + mask.count() == res.count()); return res; }
bool compare_complete_partitions::operator()(const dynamic_bitset<>& p1, const dynamic_bitset<>& p2) const { assert(p1.size() == p2.size()); for(int i=0;i<p1.size();i++) { if (p2[i] and not p1[i]) return true; if (p1[i] and not p2[i]) return false; } return false; }
/// \brief Marks the specified arc as being used. void use(const Tilewire& inTilewire1, const Tilewire& inTilewire2) { // extract the tile indexes TileIndex tileIndex1 = inTilewire1.getTileIndex(); TileIndex tileIndex2 = inTilewire2.getTileIndex(); // ensure that these tilewires belong to the same tile /// \todo Throw a meaningful exception. if(tileIndex1 != tileIndex2) throw InvalidArcException(Arc(inTilewire1, inTilewire2)); // make sure we have a bitset for this tile dynamic_bitset* bitset = mBitsets[tileIndex1]; if(bitset == 0) { // determine how many arcs are in this tile const TileInfo& tileInfo = mTiles.getTileInfo(tileIndex1); TileTypeIndex type = tileInfo.getTypeIndex(); const Array<const WireInfo>& wires = mTiles.getWireInfo(type); if(wires.getSize() == 0) return; const WireInfo& wireInfo = mTiles.getWireInfo(type, WireIndex(wires.getSize() - 1)); // caution: we have to add the regular and irregular sink count from the last wire size_t size = wireInfo.getArcOffset() + wireInfo.getSinks().getSize() + wireInfo.getIrregularSinks().getSize() + wireInfo.getRoutethroughSinks().getSize() + wireInfo.getTiedSinks().getSize(); bitset = mBitsets[tileIndex1] = new dynamic_bitset(size); // track the statistics mTileUsageCount++; mBitCount += size; } // set the bit and mark the tile dirty bitset->set(getArcOffset(inTilewire1, inTilewire2)); mTileDirty.set(tileIndex1, true); }
bool A_constant(alignment A1, alignment A2, const dynamic_bitset<>& ignore) { assert(A1.n_sequences() == A2.n_sequences()); // equality holds if we have internal node sequences -- otherwise ignore is larger assert(A1.n_sequences() <= ignore.size()); // convert to feature-number notation ublas::matrix<int> M1 = M(A1); ublas::matrix<int> M2 = M(A2); // lookup and cache the column each feature is in vector< vector< int> > column_indices = column_lookup(A2); //----- Check that the sequence lengths match ------// for(int i=0;i<M1.size2();i++) { if (ignore[i]) continue; if (A1.seqlength(i) != A2.seqlength(i)) return false; } //----- Check that each homology in A1 is in A2 -----// for(int column=0; column<A1.length(); column++) for(int s1=0; s1 < A1.n_sequences(); s1++) { if (ignore[s1]) continue; for(int s2=s1+1; s2 < A1.n_sequences(); s2++) { if (ignore[s2]) continue; if (not A_match(M1,column,s1,s2,M2,column_indices)) return false; } } return true; }
Partition::Partition(const Partition& p,const dynamic_bitset<>& mask) :names(p.names), group1(p.group1 & mask), group2(p.group2 & mask) { assert(mask.size() == p.group1.size()); assert(not group1.intersects(group2)); }
void StreamGenerator::setBitstreamBits(dynamic_bitset<>& bitStream, int num, size_t bitsetIndex, size_t numIndex) { unsigned int size = sizeof (unsigned int)*8; if (numIndex < size) { if (bitsetIndex < bitStream.size()) { bitStream[bitsetIndex] = (num >> numIndex) & 0x1; setBitstreamBits(bitStream, num, bitsetIndex + 1, numIndex + 1); } }
typename allocator<T>::size_type allocator<T>::find_free_memory(const dynamic_bitset & memfree, dynamic_bitset & mask) { /* search mask in memfree */ const size_type needed_mem_size = mask.count(); if (memfree.count() < needed_mem_size) { # if DEBUG_SMA_TRACE_FIND_FREE_MEM std::cout << "not enough free memory found" << std::endl; # endif return memfree.size(); } assert(needed_mem_size <= memfree.size()); const size_type asize = memfree.size() - needed_mem_size; size_type pos = 0; while (pos <= asize) { # if DEBUG_SMA_TRACE_FIND_FREE_MEM std::cout << "pos: " << pos << "/" << asize << std::endl; std::cout << "mask: " << mask << std::endl; std::cout << "memfree: " << memfree << std::endl; # endif /* check if enough memory is free in interval [pos, pos+needed_mem_size) */ if ((memfree & mask) == mask) { /* free memory found */ # if DEBUG_SMA_TRACE_FIND_FREE_MEM std::cout << "free memory found at pos=" << pos << std::endl; # endif return pos; } else { /* increment pos for next iteration */ # if DEBUG_SMA_TRACE_FIND_FREE_MEM std::cout << "memfree: " << memfree << " " << memfree << std::endl; std::cout << "inc mask: " << mask << " -> "; # endif const size_type oldpos = pos; pos = memfree.find_next(oldpos); assert(pos >= oldpos); mask <<= pos - oldpos; # if DEBUG_SMA_TRACE_FIND_FREE_MEM std::cout << mask << std::endl; std::cout << "pos: " << oldpos << " -> " << pos << std::endl; # endif assert(mask.count() == needed_mem_size); } } /* no free memory found */ # if DEBUG_SMA_TRACE_FIND_FREE_MEM std::cout << "not enough free memory found" << std::endl; # endif return memfree.size(); }
void add_unique(list<dynamic_bitset<> >& masks,const list<dynamic_bitset<> >& old_masks, const dynamic_bitset<>& mask) { // don't add the mask unless contains internal partitions (it could be all 0) if (mask.count() < 4) return; // don't add the mask if we already have that mask for(const auto& m: old_masks) if (m == mask) return; for(const auto& m: masks) if (m == mask) return; // otherwise, add the mask masks.push_front(mask); }
/// \brief Marks all arcs as being unused, without releasing the bitset objects. /// \details This capability allows the tracer to track the wires that it has visited while /// processing a particular net, and then to start again from scratch without incurring /// allocation and construction overheads. void clear(void) { // iterate over all of the tiles size_t tileCount = mBitsets.getSize(); for(TileIndex i; i < tileCount; i++) { // skip this tile if it isn't dirty if(!mTileDirty[i]) continue; // mark the tile clean mTileDirty.reset(i); // look up the bitset for this tile dynamic_bitset* bitset = mBitsets[i]; // skip tiles without an associated bitset (should never happen for dirty tiles) if(bitset == 0) continue; // clear the entire bitset bitset->reset(); } }
/// \brief Marks the specified arc as being unused. void release(const Tilewire& inTilewire1, const Tilewire& inTilewire2) { // extract the tile indexes TileIndex tileIndex1 = inTilewire1.getTileIndex(); TileIndex tileIndex2 = inTilewire2.getTileIndex(); // ensure that these tilewires belong to the same tile /// \todo Throw a meaningful exception. if(tileIndex1 != tileIndex2) throw -1; // if there is no entry for the tile, the arc is already implicitly unused. dynamic_bitset* bitset = mBitsets[tileIndex1]; if(bitset == 0) return; // otherwise clear the bit and mark the tile dirty bitset->set(getArcOffset(inTilewire1, inTilewire2), false); mTileDirty.set(tileIndex1, true); }
Partition::Partition(const vector<string>& n,const dynamic_bitset<>& g) :names(n),group1(g),group2(~g) { assert(n.size() == g.size()); assert(not group1.intersects(group2)); }
vector<pair<partition,unsigned> > get_Ml_partitions_and_counts(const tree_sample& sample,double l,const dynamic_bitset<>& mask) { // find the first bit int first = mask.find_first(); assert(first >= 0); if (l <= 0.0) throw myexception()<<"Consensus level must be > 0.0"; if (l > 1.0) throw myexception()<<"Consensus level must be <= 1.0"; // use a sorted list of <partition,count>, sorted by partition. typedef map<dynamic_bitset<>,p_count> container_t; container_t counts; // use a linked list of pointers to <partition,count> records. list<container_t::iterator> majority; vector<string> names = sample.names(); unsigned count = 0; for(int i=0;i<sample.trees.size();i++) { const vector<dynamic_bitset<> >& T = sample.trees[i].partitions; unsigned min_old = std::min(1+(unsigned)(l*count),count); count ++; unsigned min_new = std::min(1+(unsigned)(l*count),count); // for each partition in the next tree dynamic_bitset<> partition(names.size()); for(int b=0;b<T.size();b++) { partition = T[b]; if (not partition[first]) partition.flip(); partition &= mask; // Look up record for this partition container_t::iterator record = counts.find(partition); if (record == counts.end()) { counts.insert(container_t::value_type(partition,p_count())); record = counts.find(partition); assert(record != counts.end()); } // FIXME - we are doing the lookup twice p_count& pc = record->second; int& C2 = pc.count; int C1 = C2; if (pc.last_tree != i) { pc.last_tree=i; C2 ++; } // add the partition if it wasn't good before, but is now if ((C1==0 or C1<min_old) and C2 >= min_new) majority.push_back(record); } // for partition in the majority tree typedef list<container_t::iterator>::iterator iterator_t; for(iterator_t p = majority.begin();p != majority.end();) { if ((*p)->second.count < min_new) { iterator_t old = p; p++; majority.erase(old); } else p++; } } vector<pair<partition,unsigned> > partitions; partitions.reserve( 2*names.size() ); for(auto p : majority) { partition pi(p->first, mask); unsigned p_count = p->second.count; if (valid(pi)) partitions.push_back(pair<partition,unsigned>(pi,p_count)); } return partitions; }
int Tree::induce_partition(const dynamic_bitset<>& partition) { assert(partition.size() == n_leaves()); prepare_partitions(); dynamic_bitset<> partition1(n_nodes()); dynamic_bitset<> partition2(n_nodes()); // copy bits from smaller bitset on leaves to larger bitset on all nodes for(int i=0;i<partition.size();i++) { if (partition[i]) partition1.flip(i); else partition2.flip(i); } for(int i=n_leaves();i<n_nodes();i++) { vector<BranchNode*> group1; vector<BranchNode*> group2; // divide the branches out into two groups BranchNode * BN = nodes_[i]; do { if (not partition1.intersects(cached_partitions[BN->branch])) group2.push_back(BN); else if (not partition2.intersects(cached_partitions[BN->branch])) group1.push_back(BN); else { group1.clear(); group2.clear(); break; } BN = BN->next; } while (BN != nodes_[i]); // this node can't separate the groups if (not group1.size() and not group2.size()) continue; BranchNode* bn = NULL; // groups are already split! if (group1.size() == 1) bn = group1[0]; // groups are already split! else if (group2.size() == 1) bn = group2[0]; // split the node and note the name of the newly added branch else { bn = split_node(group1,group2); reanalyze(nodes_[0]); } if (not bn) return -1; else return std::min(bn->branch,bn->out->branch); } throw myexception()<<"induce_partition: partition conflicts with tree!"; }
Partition::Partition(const dynamic_bitset<>& g,const dynamic_bitset<>& mask) :group1((~g) & mask),group2(g & mask) { assert(g.size() == mask.size()); assert(not group1.intersects(group2)); }