SplitState filterGraph(PartitionStack* ps, const GraphType& points, const CellList& cells, int path_length) { // Would not normally go this low level, but it is important this is fast memset(&(mset.front()), 0, mset.size() * sizeof(mset[0])); edgesconsidered = 0; MonoSet monoset(ps->cellCount()); debug_out(3, "EdgeGraph", "filtering: " << cells.size() << " cells out of " << ps->cellCount()); if(path_length == 1) { for(int c : cells) { hashCellSimple(ps, points, monoset, c); } } else { MonoSet hitvertices(ps->domainSize()); for(int c : cells) { hashRangeDeep(ps, points, monoset, hitvertices, ps->cellRange(c)); } memset(&(msetspare.front()), 0, msetspare.size() * sizeof(msetspare[0])); hashRangeDeep2(ps, points, monoset, hitvertices.getMembers()); for(int i : range1(mset.size())) { mset[i] += msetspare[i] * 71; } } debug_out(3, "EdgeGraph", "filtering " << mset << " : " << monoset); return filterPartitionStackByFunctionWithCells(ps, SquareBrackToFunction(&mset), monoset); }
SplitState fix_buildingRBase(const vec1<int>& fixed_values, bool useOrbits, bool useBlocks, bool useOrbitals, bool rootCall = false) { debug_out(3, "scpg", "last depth " << last_depth.get() << " new depth " << fixed_values.size()); D_ASSERT(fixed_values.size() > last_depth.get()); last_depth.set(fixed_values.size()); if(useOrbits) { doCacheCheck(config.useOrbits, tracking_first_found_orbits, [this](const vec1<int>& v){ return this->fillRBaseOrbitPartitionCache(v); }, fixed_values, "orbits"); } if(useBlocks) { doCacheCheck(config.useBlocks, tracking_first_found_blocks, [this](const vec1<int>& v){ return this->fillRBaseBlocksCache(v); }, fixed_values, "blocks"); } if(useOrbitals) { doCacheCheck(config.useOrbitals, tracking_first_found_orbitals, [this](const vec1<int>& v){ return this->fillRBaseOrbitalsCache(v); }, fixed_values, "orbitals"); } SplitState ss(true); int fixed_size = fixed_values.size(); if(useOrbits) { const vec1<int>* part = 0; if(tracking_first_found_orbits.get() >= 0) part = this->getRBaseOrbitPartition_cached(tracking_first_found_orbits.get()); else part = this->getRBaseOrbitPartition_cached(fixed_size); debug_out(3, "scpg", "fix_rBase:orbits"); if(!part->empty()) ss = filterPartitionStackByFunction(ps, SquareBrackToFunction(part)); if(ss.hasFailed()) return ss; } if( ( StabChainConfig::doConsiderIfNonTrivial(config.useOrbitals) && fixed_size == tracking_first_found_orbitals.get() ) || ( config.useOrbitals == StabChainConfig::always ) || ( rootCall ) ) { return signal_changed_generic(range1(ps->cellCount()), identityPermutation()); } return ss; }
void orderCell(It begin, It end, SearchHeuristic sh, RBase* rbase) { switch(sh) { case SearchBranch_RBase: std::sort(begin, end, IndirectSorter(SquareBrackToFunction(&rbase->inv_value_ordering))); return; case SearchBranch_InvRBase: std::sort(begin, end, ReverseSorter(IndirectSorter(SquareBrackToFunction(&rbase->inv_value_ordering)))); return; case SearchBranch_Random: std::random_shuffle(begin, end); return; case SearchBranch_Sorted: std::sort(begin, end); return; case SearchBranch_Nosort: return; default: abort(); } }
SplitState signal_start() { return filterPartitionStackByFunction(ps, SquareBrackToFunction(&inv_points)); }
virtual SplitState signal_fix() { debug_out(3, "scpg", "signal_fix"); const vec1<int>& new_fix_cells = ps->fixed_values(); Permutation perm(last_permutation.back()); int old_depth = last_depth.get(); // We have to do this, as new_fix_cells changes as the function progresses int new_depth = new_fix_cells.size(); D_ASSERT(new_depth > old_depth); #ifndef NO_DEBUG for(int i : range1(old_depth)) { (void)i; D_ASSERT(perm[new_fix_cells[i]] == (rb->value_ordering)[i]); } #endif PermutationStack perm_stack(perm); for(int i = old_depth + 1; i <= new_depth; ++i) { if(scc.hasUnpackedLevel(i)) { StabChainLevel& scl = scc.getUnpackedLevel(i); D_ASSERT(scl.base_value == (rb->value_ordering)[i]); debug_out(3, "scpg", "Trying to map "<<new_fix_cells[i]<<" to "<<(rb->value_ordering)[i]); int image = perm_stack[new_fix_cells[i]]; debug_out(3, "scpg", "Pre-image of "<<new_fix_cells[i]<<" is "<<image); if(!scl.exists_perm_to(image)) { debug_out(3, "scpg", "No perm exists to map to image"); return SplitState(false); } const optional<Permutation>& p = scl.perm_mapping_from(image); if(!p) { debug_out(3, "scpg", "No perm mapping from image?"); return SplitState(false); } D_ASSERT((*p)[image] == (rb->value_ordering)[i]); debug_out(3, "scpg", "Old stack: " << perm_stack.getPerm()); perm_stack.addPerm((*p)); debug_out(3, "scpg", "New perm: " << *p << " added to stack gives " << perm_stack.getPerm()); D_ASSERT(perm_stack[new_fix_cells[i]] == (rb->value_ordering)[i]); } else { if(perm_stack[new_fix_cells[i]] != (rb->value_ordering)[i]) return SplitState(false); } } perm = perm_stack.getPerm(); last_permutation.push_back(perm); last_depth.set(new_depth); // Check our permutation maps known points in the right way. #ifndef NO_DEBUG for(int i : range1(new_depth)) { (void)i; D_ASSERT(perm[new_fix_cells[i]] == (rb->value_ordering)[i]); } #endif SplitState ss(true); if(StabChainConfig::doConsiderEveryNode(config.useOrbits)) { auto level = getDepthLevel(new_depth, tracking_first_found_orbits.get(), config.useOrbits); if(!level.skip) { const vec1<int>* part = getRBaseOrbitPartition_cached(level.depth); debug_out(3, "scpg", "fix:orbits" << part << " by " << perm); if(!part->empty()) ss = filterPartitionStackByFunction(ps, FunctionByPerm(SquareBrackToFunction(part), perm)); if(ss.hasFailed()) return ss; } } if( ( StabChainConfig::doConsiderIfNonTrivial(config.useOrbitals) && new_depth == tracking_first_found_orbitals.get() ) || ( config.useOrbitals == StabChainConfig::always ) ) { return signal_changed_generic(range1(ps->cellCount()), perm); } return ss; }