// // Helper/debug function to quickly print out a set of assignments. // Later if we change how we implement assignment sets, we will have to update // this function. // void DataFlowUtil::print(const Assignments& assignments) { cerr << "{ "; for (Assignments::const_iterator I = assignments.begin(), IE = assignments.end(); I != IE; ++I) { cerr << (*I).pointer->getName().data() << " "; } cerr << "}"; }
void generate_rows ( const protobuf::Config::Generate & config, CrossCat & cross_cat, Assignments & assignments, const char * rows_out, rng_t & rng) { const size_t kind_count = cross_cat.kinds.size(); const size_t row_count = config.row_count(); const float density = config.density(); LOOM_ASSERT_LE(0.0, density); LOOM_ASSERT_LE(density, 1.0); VectorFloat scores; std::vector<ProductModel::Value> partial_values(kind_count); protobuf::Row row; protobuf::OutFile rows(rows_out); for (auto & kind : cross_cat.kinds) { kind.model.realize(rng); } cross_cat.schema.clear(* row.mutable_diff()); ProductValue & full_value = * row.mutable_diff()->mutable_pos(); for (size_t id = 0; id < row_count; ++id) { assignments.rowids().try_push(id); for (size_t k = 0; k < kind_count; ++k) { auto & kind = cross_cat.kinds[k]; ProductModel & model = kind.model; auto & mixture = kind.mixture; ProductValue & value = partial_values[k]; auto & groupids = assignments.groupids(k); scores.resize(mixture.clustering.counts().size()); mixture.clustering.score_value(model.clustering, scores); distributions::scores_to_probs(scores); const VectorFloat & probs = scores; auto & observed = * value.mutable_observed(); ValueSchema::clear(observed); observed.set_sparsity(ProductModel::Value::Observed::DENSE); const size_t feature_count = kind.featureids.size(); for (size_t f = 0; f < feature_count; ++f) { observed.add_dense( distributions::sample_bernoulli(rng, density)); } size_t groupid = mixture.sample_value(model, probs, value, rng); model.add_value(value, rng); mixture.add_value(model, groupid, value, rng); groupids.push(groupid); } row.set_id(id); cross_cat.splitter.join(full_value, partial_values); rows.write_stream(row); } }
// // For a given BasicBlock, compute which variables are defined. // Assignments DataFlowUtil::defines(const BasicBlock& block) { Assignments defSet; for (BasicBlock::const_iterator it = block.begin(); it != block.end(); ++it) { // there's no result area for an instr, every instruction is actually a definition const Instruction& instr = *it; defSet.insert(Assignment(&instr)); } return defSet; }
void XMLConverter::setAssignments(Assignments & assignments) { for (Assignments::iterator i = assignments.begin(), e = assignments.end(); i != e; i++) { Assignment * assignment = *i; RequestOverseer * overseer = getOverseerByRequest(assignment->getRequest()); overseer->assign(assignment, *networkOverseer); } }
static void assignmentsSetCode(QString prefix, const Assignments& assignments, const Exceptions& exceptions, TextStreamIndent& s) { for (auto it = assignments.cbegin(); it != assignments.cend(); ++it) { if (!exceptions.contains(it.key())) assignmentSetCode(prefix, it, s); } }
static QString valueByName(const Assignments& assignments, const QString& name, const QString& defaultValue) { auto it = assignments.find(name); if (it == assignments.end()) return defaultValue; if (!it->member.isEmpty()) return defaultValue; return it->value; }
// // Determine if 2 sets contain the same elements. // bool DataFlowUtil::setEquals(const Assignments& a, const Assignments& b) { // make sure sets are the same length if (a.size() != b.size()) { return false; } // ensure they contain the same elements for (Assignments::const_iterator i = a.begin(); i != a.end(); ++i) { const Assignment& test = *i; if (b.count(test) < 1) { return false; } } return true; }
// // For a given BasicBlock, compute which variables are used. // Assignments DataFlowUtil::uses(const BasicBlock& block) { Assignments useSet; for (BasicBlock::const_reverse_iterator it = block.rbegin(); it != block.rend(); ++it) { const Instruction& instr = *it; const User* user = &instr; // iterate through all operands User::const_op_iterator OI, OE; for(OI = user->op_begin(), OE = user->op_end(); OI != OE; ++OI) { Value* val = *OI; // check if the operand is used if ((isa<Instruction>(val) || isa<Argument>(val)) && (!isa<PHINode>(val))) { useSet.insert(Assignment(val)); } } useSet.erase(Assignment(&instr)); } return useSet; }
bool ExhaustiveSearcher::makeAttempt() { if ( isExhausted() ) return false; Elements cortege = getNextCortege(); Assignments cache = getAssignmentsCache(cortege); Elements assignmentPack = getAssignmentPack(cache); Operation::forEach(assignmentPack, Operation::unassign); assignmentPack.insert(target); if ( performGreedyAssignment(assignmentPack, cortege) ) { if ( updatePathes(assignmentPack) ) return true; } for(Assignments::iterator i = cache.begin(); i != cache.end(); i++ ) i->second->assign(i->first); return false; }
Assignments DataFlowUtil::kills(const BasicBlock& block) { Assignments killSet; const Function& function = *block.getParent(); for (BasicBlock::const_iterator it = block.begin(); it != block.end(); ++it) { const Instruction& inst = *it; for(Function::const_iterator itrF = function.begin(); itrF != function.end(); ++itrF) { const BasicBlock& bb = *itrF; if (&bb == &block) { for(BasicBlock::const_iterator itrB = bb.begin(); itrB != bb.end(); ++itrB) { const Instruction& instr = *itrB; if (&inst == &instr) { killSet.insert(Assignment(&instr)); } } } } } return killSet; }
Assignments get_state_clusters(const Subset &subset, const Assignments &states, ParticleStatesTable *pst, double resolution) { Vector<Ints> rotated(subset.size(), Ints(states.size(), -1)); for (unsigned int i = 0; i < states.size(); ++i) { for (unsigned int j = 0; j < states[i].size(); ++j) { rotated[j][i] = states[i][j]; } } for (unsigned int i = 0; i < rotated.size(); ++i) { std::sort(rotated[i].begin(), rotated[i].end()); rotated[i].erase(std::unique(rotated[i].begin(), rotated[i].end()), rotated[i].end()); } Vector<Ints> clustering(states.size()); for (unsigned int i = 0; i < subset.size(); ++i) { IMP::PointerMember<ParticleStates> ps = pst->get_particle_states(subset[i]); Ints c = get_state_clusters(subset[i], ps, rotated[i], resolution); clustering[i] = c; } return filter_states(subset, states, clustering); }
Assignments DataFlowUtil::all(const Function& fn) { Assignments all; // Function arguments are values too. for (Function::const_arg_iterator I = fn.arg_begin(), IE = fn.arg_end(); I != IE; ++I) { const Argument* arg = &(*I); Assignment assign(arg); all.insert(assign); } // Populate with all instructions. // TODO: What do we do with loads and stores? Treat the same for now. for (Function::const_iterator I = fn.begin(), IE = fn.end(); I != IE; ++I) { const BasicBlock& block = *I; for (BasicBlock::const_iterator J = block.begin(), JE = block.end(); J != JE; ++J) { const Instruction* instr = &(*J); Assignment assign(instr); all.insert(assign); } } return all; }
void DataFlowUtil::setIntersect(Assignments& dest, const Assignments& src) { Assignments result; for (Assignments::const_iterator i = src.begin(); i != src.end(); ++i) { const Assignment& test = *i; if (src.count(test) > 0 && dest.count(test) > 0) { result.insert(test); } } // rewrite the destination dest = result; }
Paths CorrespondenceGenerator::generate() { Paths result; auto boxA = a->bbox(), boxB = b->bbox(); QStringList nodesA, nodesB; for (auto n : a->nodes) nodesA << n->id; for (auto n : b->nodes) nodesB << n->id; for (auto g : a->groups) for (auto nid : g) nodesA.removeAll(nid); for (auto g : b->groups) for (auto nid : g) nodesB.removeAll(nid); Structure::NodeGroups tmpA, tmpB; for (auto nid : nodesA) tmpA.push_back( QVector<QString>() << nid ); for (auto nid : nodesB) tmpB.push_back( QVector<QString>() << nid ); for (auto g : a->groups) tmpA.push_back(g); for (auto g : b->groups) tmpB.push_back(g); a->groups = tmpA; b->groups = tmpB; /// Build similarity matrix of groups: Eigen::MatrixXd similiarity = Eigen::MatrixXd::Ones(a->groups.size(), b->groups.size() + 1); for (size_t i = 0; i < similiarity.rows(); i++){ double minVal = DBL_MAX; for (size_t j = 0; j < similiarity.cols(); j++){ double val = 0; if (j < b->groups.size()) { Eigen::AlignedBox3d groupBoxA, groupBoxB; for (auto sid : a->groups[i]) groupBoxA.extend(a->getNode(sid)->bbox(1.01)); for (auto sid : b->groups[j]) groupBoxB.extend(b->getNode(sid)->bbox(1.01)); Vector3 relativeCenterA = (groupBoxA.center() - boxA.min()).array() / boxA.sizes().array(); Vector3 relativeCenterB = (groupBoxB.center() - boxB.min()).array() / boxB.sizes().array(); val = (relativeCenterA - relativeCenterB).norm(); minVal = std::min(minVal, val); } similiarity(i, j) = val; } double maxVal = similiarity.row(i).maxCoeff(); if (maxVal == 0) maxVal = 1.0; for (size_t j = 0; j < b->groups.size(); j++) similiarity(i, j) = (similiarity(i, j) - minVal) / maxVal; } std::vector< std::vector<float> > data; for (int i = 0; i < similiarity.rows(); i++){ std::vector<float> dataRow; for (int j = 0; j < similiarity.cols(); j++) dataRow.push_back(similiarity(i, j)); data.push_back(dataRow); } //if (false) showTableColorMap(data, true); // DEBUG // Parameters: double similarity_threshold = 0.4; if (similiarity.rows() < 4) similarity_threshold = 1.0; // Collect good candidates Assignments candidates; for (size_t i = 0; i < similiarity.rows(); i++){ QVector<size_t> candidate; for (size_t j = 0; j < similiarity.cols(); j++){ if (similiarity(i, j) < similarity_threshold) candidate << j; } candidates << candidate; } int count_threshold = 1; Assignments assignments; if (candidates.size() > 7) { debugBox(QString("%1 candidates. Too complex (lower similairty?)").arg(candidates.size())); similarity_threshold = 0.1; Assignments candidates; for (size_t i = 0; i < similiarity.rows(); i++){ QVector<size_t> candidate; for (size_t j = 0; j < similiarity.cols(); j++){ if (similiarity(i, j) < similarity_threshold) candidate << j; } candidates << candidate; } cart_product(assignments, candidates, 10000); count_threshold = 12; } else { cart_product(assignments, candidates); } // Filter assignments Assignments filtered; for (auto & a : assignments) { QMap<size_t, size_t> counts; bool accept = true; auto NOTHING_SEGMENT = similiarity.cols() - 1; for (auto i : a) counts[i]++; for (auto k : counts.keys()) { if (k != NOTHING_SEGMENT && counts[k] > count_threshold){ accept = false; break; } } if (accept) filtered << a; } for (auto & assignment : filtered) { QVector < QStringList > landmarksA, landmarksB; for (size_t i = 0; i < assignment.size(); i++) { if (assignment[i] == b->groups.size()) continue; auto grpA = a->groups[i]; auto grpB = b->groups[assignment[i]]; // Resolve many-to-many if (grpA.size() > 1 && grpB.size() > 1) { QVector<QString> tmpA, tmpB; Eigen::AlignedBox3d groupBoxA, groupBoxB; for (auto sid : grpA) groupBoxA.extend(a->getNode(sid)->bbox(1.01)); for (auto sid : grpB) groupBoxB.extend(b->getNode(sid)->bbox(1.01)); for (auto nodeid_i : grpA){ auto nodeA = a->getNode(nodeid_i); QMap < QString, double > dists; for (auto nodeid_j : grpB){ auto nodeB = b->getNode(nodeid_j); Vector3 posA = (nodeA->position(Eigen::Vector4d(0.5, 0.5, 0, 0)) - boxA.min()).array() / boxA.sizes().array(); Vector3 posB = (nodeB->position(Eigen::Vector4d(0.5, 0.5, 0, 0)) - boxB.min()).array() / boxB.sizes().array(); dists[nodeid_j] = (posA - posB).norm(); } auto nodeid_j = sortQMapByValue(dists).first().second; landmarksA << (QStringList() << nodeid_i); landmarksB << (QStringList() << nodeid_j); } } else { landmarksA << QStringList::fromVector(grpA); landmarksB << QStringList::fromVector(grpB); } } result.push_back( qMakePair(landmarksA, landmarksB) ); } return result; }
void DataFlowUtil::setUnion(Assignments& dest, const Assignments& src) { for (Assignments::const_iterator i = src.begin(); i != src.end(); ++i) { const Assignment& add = *i; dest.insert(add); } }
// // The following functions perform basic set operations in O(n*log(m)) time, // where m and n are the sizes of the sets. For our purposes, this is fast // enough. // // The result of these operations is stored back into the 1st argument. // void DataFlowUtil::setSubtract(Assignments& dest, const Assignments& src) { for (Assignments::const_iterator i = src.begin(); i != src.end(); ++i) { const Assignment& sub = *i; dest.erase(sub); } }