// RogueViz -- SAG embedder: data manager // Copyright (C) 2011-24 Zeno Rogue, see 'hyper.cpp' for details #include "../rogueviz.h" #include "../embeddings/embeddings.h" namespace rogueviz { namespace sag { using namespace cells; edgetype *sag_edge; /** if this is true, no nodes are allowed to be on the same subcell */ bool allow_doubles = false; /** node i is on sagcells[sagid[i]] */ vector sagid; /** what node is on sagcells[i] (need loglik_repeat to be off) */ vector sagnode; /* separate hubs -- only for smClosest */ ld hub_penalty; string hub_filename; vector hubval; vector> edges_yes, edges_no; vector>> edge_weights; vector fixed_position; ld edgepower=1, edgemul=1; void init(); void compute_cost(); bool colorpartite; bool take(int i, int j) { if(colorpartite) return vdata[i].cp != vdata[j].cp; return i != j; } edgetype *ensure_sag_edge() { if(!sag_edge) sag_edge = add_edgetype("SAG edge"); return sag_edge; } vector qon, qsf; void save_sag_solution(const fhstream& f); struct sag_embedding : public rogueviz::embeddings::tiled_embedding { virtual string name() override { return "SAG"; } pair as_location(int id) override { ld rad = .25 * cgi.scalefactor; if(isize(subcell_points) > 1) rad /= pow(isize(subcell_points), WDIM); int ci = sag::sagid[id]; hyperpoint h = C0; if(allow_doubles && qon.size() && qon[ci] > 1) h = spin(TAU*qsf[ci] / qon[ci]) * xpush0(rad * (qon[ci]-1) / qon[ci]); if(isize(subcell_points) > 1) h = rgpushxto0(subcell_points[sagcells[ci].second]) * h; return { sagcells[ci].first, h }; } ld distance(int i, int j) override { return sagdist[sagid[i]][sagid[j]]; } ld zero_distance(int i) override { return sagdist[sagid[i]][0]; } void save(fhstream& f) override { if(!(state & SS_DATA)) throw hr_exception("save_sag_solution with no data"); for(int i=0; i= SN || err < 1) sid = -1; if(!labeler.count(lab)) { printf("unknown vertex: %s\n", lab.c_str()); } else { int id = getid(lab); sagid[id] = sid; } } afterload: if(sf) fclose(sf); prepare_graph(); create_viz(); } void load_sag_solution_basic(const string& fname) { if(!(state & SS_DATA)) throw hr_exception("load_sag_solution_basic with no data"); DEBBI(debug_init_sag, ("Loading the sag solution (basic) from: ", fname)); FILE *f = fopen(fname.c_str(), "rt"); if(!f) return file_error(fname); for(auto& i: sagid) if(fscanf(f, "%d", &i) < 1) return file_format_error(fname); fclose(f); if(debug_init_sag) println(hlog, "loaded sagid = ", sagid); prepare_graph(); create_viz(); } void after_data() { state |= SS_DATA; init_snake_if_needed(); int DN = isize(vdata); int SN = isize(sagcells); if(SN < DN) { println(hlog, "SN = ", SN, " DN = ", DN); throw hr_exception("not enough cells for SAG"); } sagid.resize(DN); for(int i=0; i n || m < 0) throw hr_exception("generate_fake_data parameters incorrect"); sagid.resize(m); int DN = isize(sagid); resize_vertices(DN); for(int i=0; i first */ void generate_unweighted(int DN) { if(state & SS_DATA) return; init_cells(); int N = isize(sagcells); sagid.resize(DN); for(int i=0; i colors; if(colorpartite) { colors.resize(DN); for(int i=0; i= isize(sagid)) throw hr_exception("bad id in -sag-fix"); fixed_position[id] = true; } else if(argis("-sag-move-to")) { shift(); int sid1 = getid(args()); if(sid1 < 0 || sid1 >= isize(sagid)) throw hr_exception("bad id in -sag-move-to"); shift(); int t2 = argi(); if(t2 < 0 || t2 >= isize(sagnode)) throw hr_exception("bad id in -sag-move-to"); int sid2 = sagid[t2]; int t1 = allow_doubles ? -1 : sagnode[sid1]; sagnode[sid1] = t2; sagid[t2] = sid1; if(sid2 >= 0) sagnode[sid2] = t1; sagid[t1] = sid2; compute_cost(); create_viz(); } else if(argis("-sag-colorpartite")) { colorpartite = true; if(state & SS_DATA) prepare_graph(); } else return 1; #endif return 0; } int ahdata = addHook(hooks_args, 100, data_read_args); } }