1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2026-03-26 14:39:42 +00:00

rogueviz:: improved the graph subsystem

This commit is contained in:
Zeno Rogue
2025-12-04 19:44:39 +01:00
parent d101495e2a
commit 422593c17c
16 changed files with 313 additions and 359 deletions

View File

@@ -1780,6 +1780,7 @@ MONSTER( '?', 0xE06000, "Energy Sword", moEnergySword, ZERO | CF_TECHNICAL, RESE
MONSTER( '!', 0xFF0000, "Warning", moWarning, ZERO | CF_TECHNICAL, RESERVED, moNone, warningdesc)
MONSTER( '!', 0xFF0000, "arrow trap", moArrowTrap, ZERO | CF_BULLET | CF_TECHNICAL, RESERVED, moNone, arrowtrapdesc)
MONSTER( '*', 0, "vertex", moRogueviz, ZERO | CF_TECHNICAL, RESERVED, moNone, "A vertex from rogueviz.")
MONSTER( '*', 0, "edge", moRoguevizExtender, ZERO | CF_TECHNICAL, RESERVED, moNone, "An edge extender from rogueviz.")
#undef MONSTER
#undef LAND

View File

@@ -19,15 +19,13 @@ namespace collatz {
init(RV_GRAPH);
collatz1 = add_edgetype("1");
collatz2 = add_edgetype("2");
vdata.resize(1);
vertexdata& vd = vdata[0];
createViz(0, cwt.at, xpush(cshift));
vertexdata& vd = add_vertex();
vd.be(cwt.at, xpush(cshift));
virtualRebase(vd.m);
vd.cp = dftcolor;
vd.data = 0;
addedge(0, 0, 1, false, collatz::collatz1);
addedge(0, 0, 1, collatz::collatz1);
vd.name = "1";
storeall();
T2 = spin(collatz::s2) * xpush(collatz::p2);
T3 = spin(collatz::s3) * xpush(collatz::p3);
@@ -108,16 +106,12 @@ namespace collatz {
string s = vd.name;
colorpair cp = vd.cp;
vd.data = 20;
int i0 = isize(vdata);
vdata.resize(i0+1);
vertexdata& vdn = vdata[i0];
createViz(i0, m->base, m->at * collatz::T2);
vertexdata& vdn = add_vertex();
vdn.be(m->base, m->at * collatz::T2);
virtualRebase(vdn.m);
vdn.cp = perturb(cp);
vdn.data = 0;
addedge(i, i0, 1, false, collatz::collatz1);
vdn.m->store();
addedge(i, vdn.id, 1, collatz::collatz1);
int carry = 0;
string s2 = s;
for(int i=isize(s2)-1; i>=0; i--) {
@@ -133,14 +127,12 @@ namespace collatz {
for(int i=0; i<isize(s); i++) m3 += s[i] - '0';
if(m3 % 3 == 2 && s != "2" && s != "1") {
vdata.resize(i0+2);
vertexdata& vdn = vdata[i0+1];
createViz(i0+1, m->base, m->at * collatz::T3);
vertexdata& vdn = add_vertex();
vdn.be(m->base, m->at * collatz::T3);
virtualRebase(vdn.m);
vdn.cp = perturb(cp);
vdn.data = 0;
addedge(i, i0+1, 1, false, collatz::collatz2);
vdn.m->store();
addedge(i, vdn.id, 1, collatz::collatz2);
int carry = -1;
string s2 = s;
for(int i=isize(s2)-1; i>=0; i--) {

View File

@@ -8,7 +8,6 @@ namespace dhrg {
extern double graph_R;
extern int N;
extern int iterations;
void fixedges();
void unsnap();
bool dhrg_animate(int sym, int uni);
void rvcoords();
@@ -192,7 +191,7 @@ void graph_visuals(presmode mode) {
void swap_snap() {
snapped = !snapped;
if(snapped) { for(auto& v: rogueviz::vdata) v.m->at = Id; dhrg::fixedges(); }
if(snapped) { for(auto& v: rogueviz::vdata) v.be(v.m->base, Id); }
if(!snapped) dhrg::unsnap();
}

View File

@@ -53,11 +53,7 @@ void place_rogueviz_vertices() {
progressbar pb(N, "place_rogueviz_vertices");
// transmatrix In = inverse(ggmatrix(currentmap->gamestart()));
using namespace rogueviz;
/* for(int i=0; i<N; i++) vdata[i].m->base = currentmap->gamestart();
for(int i=0; i<N; i++) vdata[i].m->at = In * shmup::ggmatrix(vertices[i]->ascell()); */
for(int i=0; i<N; i++) vdata[i].m->base = vertices[i]->ascell();
for(int i=0; i<N; i++) vdata[i].m->at = Id;
fixedges();
for(int i=0; i<N; i++) vdata[i].be(vertices[i]->ascell(), Id);
}
int destroy;
@@ -96,7 +92,7 @@ int ts_vertices;
bool stored;
void graphv(string s) {
dhrg_init(); read_graph(s, true, true, true);
dhrg_init(); read_graph(s);
next_timestamp++;
ts_rogueviz = next_timestamp;
ts_rbase = next_timestamp;
@@ -114,7 +110,7 @@ int dhrgArgs() {
}
else if(argis("-graph")) {
PHASE(3); shift(); dhrg_init(); read_graph(args(), false, false, false);
PHASE(3); shift(); dhrg_init(); read_graph(args());
next_timestamp++;
ts_rogueviz = next_timestamp;
// stored = true;
@@ -163,8 +159,6 @@ int dhrgArgs() {
place_rogueviz_vertices();
ts_rbase = ts_vertices;
}
if(!stored) rogueviz::storeall(), stored = true;
else shmup::fixStorage();
mainloop(); quitmainloop = false;
}

View File

@@ -219,7 +219,7 @@ void read_graph_full(const string& fname) {
// N = isize(vdata);
read_graph(fname, false, false, false);
read_graph(fname);
vertices.resize(N);
progressbar pb(N, "Translating to cells");
@@ -303,7 +303,7 @@ void save_embedding(const string s) {
void load_embedded(const string s) {
if(true) {
read_graph(s, false, false, false);
read_graph(s);
indenter_finish im("Read graph");
}

View File

@@ -6,21 +6,9 @@ namespace dhrg {
int N;
void fixedges() {
using namespace rogueviz;
for(int i=N; i<isize(vdata); i++) if(vdata[i].m) vdata[i].m->dead = true;
for(int i=0; i<isize(vdata); i++) vdata[i].edges.clear();
vdata.resize(N);
for(auto e: edgeinfos) {
e->orig = NULL;
addedge(e->i, e->j, e);
}
storeall(N);
}
void tst() {}
void read_graph(string fn, bool subdiv, bool doRebase, bool doStore) {
void read_graph(string fn) {
any = rogueviz::add_edgetype("embedded edges");
rogueviz::fname = fn;
@@ -49,8 +37,8 @@ namespace dhrg {
coords.push_back(make_pair(r, alpha));
transmatrix h = spin(alpha * degree) * xpush(r);
rogueviz::createViz(id, currentmap->gamestart(), h);
vd.be(currentmap->gamestart(), h);
}
fhstream g(fn + "-links.txt", "rt");
@@ -63,30 +51,16 @@ namespace dhrg {
while(true) {
int i = rogueviz::readLabel(g), j = rogueviz::readLabel(g);
if(i == -1 || j == -1) break;
addedge(i, j, 1, subdiv, any);
addedge(i, j, 1, any);
qlink++;
}
if(doRebase) {
printf("Rebasing...\n");
for(int i=0; i<isize(rogueviz::vdata); i++) {
if(i % 10000 == 0) printf("%d/%d\n", i, isize(rogueviz::vdata));
if(rogueviz::vdata[i].m) virtualRebase(rogueviz::vdata[i].m);
}
printf("Done.\n");
}
if(doStore) rogueviz::storeall();
}
void unsnap() {
for(int i=0; i<N; i++) {
using rogueviz::vdata;
transmatrix h = spin(coords[i].second * degree) * xpush(coords[i].first);
vdata[i].m->base = currentmap->gamestart();
vdata[i].m->at = h;
virtualRebase(vdata[i].m);
vdata[i].be(currentmap->gamestart(), h);
}
fixedges();
}
}

View File

@@ -55,8 +55,6 @@ void show_likelihood() {
embedder_loop(1);
ts_vertices = ts_rbase;
place_rogueviz_vertices();
if(!stored) rogueviz::storeall(), stored = true;
else shmup::fixStorage();
});
dialog::addBack();
@@ -65,9 +63,8 @@ void show_likelihood() {
if(held_id >= 0) {
if(!mousepressed) held_id = -1;
else if(mouseover) {
rogueviz::vdata[held_id].m->base = mouseover;
shmup::fixStorage();
dhrg::fixedges();
auto& vd = rogueviz::vdata[held_id];
vd.be(mouseover, vd.m->at);
auto& mc = vertices[held_id];
tallyedgesof(held_id, -1, mc);
@@ -104,8 +101,6 @@ bool dhrg_animate(int sym, int uni) {
dhrg_init(); graph_from_rv();
ts_vertices = ts_rbase;
place_rogueviz_vertices();
if(!stored) rogueviz::storeall(), stored = true;
else shmup::fixStorage();
}
pushScreen(show_likelihood);

View File

@@ -488,7 +488,7 @@ bool drawVertex(const shiftmatrix &V, cell *c, shmup::monster *m) {
rv_hook(hooks_o_key, 80, o_key);
rv_hook(shmup::hooks_draw, 90, drawVertex);
vdata.resize(N);
resize_vertices(N);
const auto v = currentmap->allcells();
@@ -516,8 +516,7 @@ bool drawVertex(const shiftmatrix &V, cell *c, shmup::monster *m) {
vertexdata& vd = vdata[i];
// set initial base and at to random cell and random position there
createViz(i, v[swarm ? 0 : hrand(isize(v))], Id);
vd.be(v[swarm ? 0 : hrand(isize(v))], Id);
vd.m->pat.T = Id;
if(swarm) {
@@ -545,7 +544,6 @@ bool drawVertex(const shiftmatrix &V, cell *c, shmup::monster *m) {
vd.m->at = vd.m->pat.T;
}
storeall();
printf("done\n");
}

View File

@@ -147,6 +147,19 @@ colorpair parse(string s) {
vector<vertexdata> vdata;
vertexdata& add_vertex() {
int id = isize(vdata);
vdata.emplace_back();
auto& vd = vdata.back();
vd.id = id;
return vd;
}
void resize_vertices(int N) {
while(isize(vdata) > N) { vdata.back().be_nowhere(); vdata.pop_back(); }
while(isize(vdata) < N) add_vertex();
}
map<string, int> labeler;
bool id_known(const string& s) {
@@ -155,12 +168,9 @@ bool id_known(const string& s) {
int getid(const string& s) {
if(labeler.count(s)) return labeler[s];
else {
int id = isize(vdata);
vdata.resize(isize(vdata) + 1);
vdata[id].name = s;
return labeler[s] = id;
}
auto& vd = add_vertex();
vd.name = s;
return labeler[s] = vd.id;
}
int getnewid(string s) {
@@ -168,19 +178,31 @@ int getnewid(string s) {
return getid(s);
}
void addedge0(int i, int j, edgeinfo *ei) {
vdata[i].edges.push_back(make_pair(j, ei));
vdata[j].edges.push_back(make_pair(i, ei));
void clear_extenders(edgeinfo *ei);
void redo_extenders(edgeinfo *ei);
void vertexdata::be_nowhere() {
if(m) m->dead = true;
m = nullptr;
for(auto& ei: edges)
clear_extenders(ei.second);
}
void createViz(int id, cell *c, transmatrix at) {
vertexdata& vd(vdata[id]);
vd.m = new shmup::monster;
vd.m->pid = id;
vd.m->type = moRogueviz;
vd.m->base = c;
vd.m->at = at;
vd.m->isVirtual = false;
ld extenders_over = 4;
int extender_levels = 3;
int rv_quality = 3;
void vertexdata::be(cell *c, transmatrix at) {
be_nowhere();
m = new shmup::monster;
m->pid = id;
m->type = moRogueviz;
m->base = c;
m->at = at;
m->isVirtual = false;
if(rv_quality >= 2) virtualRebase(m);
if(rv_quality >= 1) m->store();
if(rv_quality >= 3) for(auto& ei: edges) redo_extenders(ei.second);
}
void notimpl() {
@@ -199,46 +221,56 @@ hyperpoint where(int i, cell *base) {
}
}
void addedge(int i, int j, edgeinfo *ei) {
cell *base =
confusingGeometry() ? vdata[i].m->base : currentmap->gamestart();
hyperpoint hi = where(i, base);
hyperpoint hj = where(j, base);
void add_extenders(edgeinfo *ei, cell *base, hyperpoint hi, hyperpoint hj, int lev) {
if(lev <= 0) return;
double d = hdist(hi, hj);
if(d >= 4) {
hyperpoint h = mid(hi, hj);
int id = isize(vdata);
vdata.resize(id+1);
vertexdata& vd(vdata[id]);
vd.cp = colorpair(0x400000FF);
vd.virt = ei;
createViz(id, base, rgpushxto0(h));
vd.m->no_targetting = true;
addedge(i, id, ei);
addedge(id, j, ei);
virtualRebase(vdata[i].m);
}
else addedge0(i, j, ei);
if(d < extenders_over) return;
hyperpoint h = mid(hi, hj);
add_extenders(ei, base, hi, h, lev - 1);
auto m = new shmup::monster;
m->pid = ei->edge_id;
m->type = moRoguevizExtender;
m->base = base; m->at = rgpushxto0(h);
m->no_targetting = true;
virtualRebase(m);
m->store();
ei->extenders.push_back(m);
add_extenders(ei, base, h, hj, lev - 1);
}
void clear_extenders(edgeinfo *ei) {
for(auto e: ei->extenders) e->dead = true;
ei->extenders.clear();
}
void redo_extenders(edgeinfo *ei) {
clear_extenders(ei);
if(rv_quality < 3 || !vdata[ei->i].m || !vdata[ei->j].m) return;
int i = ei->i, j = ei->j;
cell *base = confusingGeometry() ? vdata[i].m->base : currentmap->gamestart();
add_extenders(ei, base, where(i, base), where(j, base), extender_levels);
}
vector<edgeinfo*> edgeinfos;
void addedge(int i, int j, double wei, bool subdiv, edgetype *t) {
void addedge(int i, int j, double wei, edgetype *t) {
int eid = isize(edgeinfos);
edgeinfo *ei = new edgeinfo(t);
edgeinfos.push_back(ei);
ei->i = i;
ei->j = j;
ei->j = j;
ei->weight = wei;
if(subdiv) addedge(i, j, ei);
else addedge0(i, j, ei);
}
void storeall(int from) {
for(int i=from; i<isize(vdata); i++)
if(vdata[i].m)
vdata[i].m->store();
ei->edge_id = eid;
vdata[i].edges.push_back(make_pair(j, ei));
vdata[j].edges.push_back(make_pair(i, ei));
redo_extenders(ei);
}
colorpair dftcolor = 0x282828FF;
@@ -504,181 +536,166 @@ ld edgewidth = 1;
bool highlight_target = true;
void draw_edge(const shiftmatrix &V, cell *c, edgeinfo *ei) {
bool multidraw = quotient;
if(ei->lastdraw >= frameid && !multidraw) return;
ei->lastdraw = frameid;
vertexdata& vd1 = vdata[ei->i];
vertexdata& vd2 = vdata[ei->j];
int oi = ei->i, oj = ei->j;
bool hilite = false;
if(vdata[oi].special && vdata[oj].special && specialmark) hilite = true;
else if(svg::in || inHighQual || !highlight_target) hilite = false;
else if(vd1.m == shmup::mousetarget) hilite = true;
else if(vd2.m == shmup::mousetarget) hilite = true;
else if(shmup::lmousetarget && shmup::lmousetarget->pid == oi) hilite = true;
else if(shmup::lmousetarget && shmup::lmousetarget->pid == oj) hilite = true;
if(ei->weight < (hilite ? ei->type->visible_from_hi : ei->type->visible_from)) return;
dynamicval<ld> w(vid.linewidth, vid.linewidth * edgewidth);
color_t col = (hilite ? ei->type->color_hi : ei->type->color);
auto& alpha = part(col, 0);
if(vizflags & RV_AUTO_MAXWEIGHT) {
if(ei->weight2 > maxweight) maxweight = ei->weight2;
alpha *= pow(ei->weight2 / maxweight, ggamma);
}
if(svg::in && alpha < 16) return;
if(ISWEB) {
if(alpha >= 128) alpha |= 15;
else if(alpha >= 64) alpha |= 7;
else if(alpha >= 32) alpha |= 3;
else if(alpha >= 16) alpha |= 1;
}
alpha >>= darken;
shiftmatrix gm1, gm2;
bool use_brm = closed_manifold && isize(currentmap->allcells()) <= brm_limit;
if(use_brm) {
gm1 = V * memo_relative_matrix(vd1.m->base, c);
gm2 = gm1 * brm_get(vd1.m->base, tC0(vd1.m->at), vd2.m->base, tC0(vd2.m->at));
}
else if(multidraw || elliptic) {
gm1 = V * memo_relative_matrix(vd1.m->base, c);
gm2 = V * memo_relative_matrix(vd2.m->base, c);
}
else {
gm1 = ggmatrix(vd1.m->base);
gm2 = ggmatrix(vd2.m->base);
}
shiftpoint h1 = gm1 * vd1.m->at * C0;
shiftpoint h2 = gm2 * vd2.m->at * C0;
if(elliptic && hdist(h1, h2) > hdist(h1.h, centralsym * h2.h))
h2.h = centralsym * h2.h;
if(multidraw) {
int code = int(h1[0]) + int(h1[1]) * 12789117 + int(h2[0]) * 126081253 + int(h2[1]) * 126891531;
int& lastdraw = drawn_edges[make_pair(ei, code)];
if(lastdraw == frameid) return;
lastdraw = frameid;
}
if((col >> 8) == (DEFAULT_COLOR >> 8)) {
col &= 0xFF;
col |= (forecolor << 8);
}
if(callhandlers(false, hooks_alt_edges, ei, false)) ;
else if(sl2)
twist::queueline_correct(h1, h2, col, 2 + vid.linequality, PPR::STRUCT0);
else if(sol && !fat_edges)
sn::queueline_lie(h1, h2, col, 2 + vid.linequality, PPR::STRUCT0);
else if(pmodel && !fat_edges && !sol) {
queueline(h1, h2, col, 2 + vid.linequality).prio = PPR::STRUCT0;
}
else {
cell *center = multidraw ? c : centerover;
if(!multidraw && ei->orig && ei->orig != center && celldistance(ei->orig, center) > 3)
ei->orig = NULL;
if(!ei->orig) {
ei->orig = center; // cwt.at;
ei->prec.clear();
const shiftmatrix& T = multidraw ? V : ggmatrix(ei->orig);
if(callhandlers(false, hooks_alt_edges, ei, true)) ;
else if(fat_edges) {
ei->tinf.tvertices.clear();
shiftmatrix T1 = gm1 * vd1.m->at;
hyperpoint goal = inverse_shift(T1, h2);
transmatrix S = inverse_shift(T, gm1) * vd1.m->at * rspintox(goal);
ld d = hdist0(goal);
for(int a=0; a<360; a+=30) {
auto store = [&] (ld a, ld b) {
storevertex(ei->prec, S * cpush(0, b) * hr::cspin(1, 2, a * degree) * cpush(1, fat_edges) * C0);
ei->tinf.tvertices.push_back(glhr::makevertex(0,(3+cos(a * degree))/4,0));
};
store(a, 0);
store(a+30, 0);
store(a, d);
store(a+30, 0);
store(a, d);
store(a+30, d);
}
}
else
storeline(ei->prec, inverse_shift(T, h1), inverse_shift(T, h2));
}
const shiftmatrix& T = multidraw ? V : ggmatrix(ei->orig);
queue_prec(T, ei, col);
if(elliptic) queue_prec(ggmatrix(ei->orig) * centralsym, ei, col);
}
}
bool drawVertex(const shiftmatrix &V, cell *c, shmup::monster *m) {
if(m->dead) return true;
if(m->type == moRoguevizExtender) {
draw_edge(V, c, edgeinfos[m->pid]);
return true;
}
if(m->type != moRogueviz) return false;
int i = m->pid;
vertexdata& vd = vdata[i];
if(vd.spillcolor != DEFAULT_COLOR) c->landparam = vd.spillcolor >> 8;
// bool ghilite = false;
// if(vd.special && specialmark) ghilite = true;
if(!gmatrix.count(m->base)) printf("base not in gmatrix\n");
int lid = shmup::lmousetarget ? shmup::lmousetarget->pid : -2;
bool multidraw = quotient;
bool use_brm = closed_manifold && isize(currentmap->allcells()) <= brm_limit;
ld hi_weight = 0;
if(!lshiftclick) for(int j=0; j<isize(vd.edges); j++) {
edgeinfo *ei = vd.edges[j].second;
if(multidraw && ei->i != i) continue;
vertexdata& vd1 = vdata[ei->i];
vertexdata& vd2 = vdata[ei->j];
int oi = ei->i, oj = ei->j;
bool hilite = false;
if(vdata[oi].special && vdata[oj].special && specialmark) hilite = true;
else if(svg::in || inHighQual || !highlight_target) hilite = false;
else if(vd1.m == shmup::mousetarget) hilite = true;
else if(vd2.m == shmup::mousetarget) hilite = true;
else if(oi == lid || oj == lid) hilite = true;
if(ei->weight < (hilite ? ei->type->visible_from_hi : ei->type->visible_from)) continue;
if((vd1.m == shmup::mousetarget || vd2.m == shmup::mousetarget) && m != shmup::mousetarget)
hi_weight = ei->weight;
// if(hilite) ghilite = true;
if(ei->lastdraw < frameid || multidraw) {
ei->lastdraw = frameid;
dynamicval<ld> w(vid.linewidth, vid.linewidth * edgewidth);
color_t col = (hilite ? ei->type->color_hi : ei->type->color);
auto& alpha = part(col, 0);
if(vizflags & RV_AUTO_MAXWEIGHT) {
if(ei->weight2 > maxweight) maxweight = ei->weight2;
alpha *= pow(ei->weight2 / maxweight, ggamma);
}
// if(hilite || hiliteclick) alpha = (alpha + 256) / 2;
if(svg::in && alpha < 16) continue;
if(ISWEB) {
if(alpha >= 128) alpha |= 15;
else if(alpha >= 64) alpha |= 7;
else if(alpha >= 32) alpha |= 3;
else if(alpha >= 16) alpha |= 1;
}
alpha >>= darken;
shiftmatrix gm1, gm2;
if(use_brm) {
gm1 = V * memo_relative_matrix(vd1.m->base, c);
gm2 = gm1 * brm_get(vd1.m->base, tC0(vd1.m->at), vd2.m->base, tC0(vd2.m->at));
}
else if(multidraw || elliptic) {
gm1 = V * memo_relative_matrix(vd1.m->base, c);
gm2 = V * memo_relative_matrix(vd2.m->base, c);
}
else {
gm1 = ggmatrix(vd1.m->base);
gm2 = ggmatrix(vd2.m->base);
}
shiftpoint h1 = gm1 * vd1.m->at * C0;
shiftpoint h2 = gm2 * vd2.m->at * C0;
if(elliptic && hdist(h1, h2) > hdist(h1.h, centralsym * h2.h))
h2.h = centralsym * h2.h;
if(multidraw) {
int code = int(h1[0]) + int(h1[1]) * 12789117 + int(h2[0]) * 126081253 + int(h2[1]) * 126891531;
int& lastdraw = drawn_edges[make_pair(ei, code)];
if(lastdraw == frameid) continue;
lastdraw = frameid;
}
/* if(hdist0(h1) < .001 || hdist0(h2) < .001) {
printf("h1 = %s\n", display(h1));
printf("h2 = %s\n", display(h2));
display(m->at);
display(vd2.m->at);
display(V);
display(gmatrix[vd2.m->base]);
display(shmup::calc_gmatrix(vd2.m->base));
} */
if((col >> 8) == (DEFAULT_COLOR >> 8)) {
col &= 0xFF;
col |= (forecolor << 8);
}
if(callhandlers(false, hooks_alt_edges, ei, false)) ;
else if(sl2)
twist::queueline_correct(h1, h2, col, 2 + vid.linequality, PPR::STRUCT0);
else if(sol && !fat_edges)
sn::queueline_lie(h1, h2, col, 2 + vid.linequality, PPR::STRUCT0);
else if(pmodel && !fat_edges && !sol) {
queueline(h1, h2, col, 2 + vid.linequality).prio = PPR::STRUCT0;
}
else {
cell *center = multidraw ? c : centerover;
if(!multidraw && ei->orig && ei->orig != center && celldistance(ei->orig, center) > 3)
ei->orig = NULL;
if(!ei->orig) {
ei->orig = center; // cwt.at;
ei->prec.clear();
const shiftmatrix& T = multidraw ? V : ggmatrix(ei->orig);
if(callhandlers(false, hooks_alt_edges, ei, true)) ;
else if(fat_edges) {
ei->tinf.tvertices.clear();
shiftmatrix T1 = gm1 * vd1.m->at;
hyperpoint goal = inverse_shift(T1, h2);
transmatrix S = inverse_shift(T, gm1) * vd1.m->at * rspintox(goal);
ld d = hdist0(goal);
for(int a=0; a<360; a+=30) {
auto store = [&] (ld a, ld b) {
storevertex(ei->prec, S * cpush(0, b) * hr::cspin(1, 2, a * degree) * cpush(1, fat_edges) * C0);
ei->tinf.tvertices.push_back(glhr::makevertex(0,(3+cos(a * degree))/4,0));
};
store(a, 0);
store(a+30, 0);
store(a, d);
store(a+30, 0);
store(a, d);
store(a+30, d);
}
}
else
storeline(ei->prec, inverse_shift(T, h1), inverse_shift(T, h2));
}
const shiftmatrix& T = multidraw ? V : ggmatrix(ei->orig);
queue_prec(T, ei, col);
if(elliptic) queue_prec(ggmatrix(ei->orig) * centralsym, ei, col);
}
}
/*
*/
if(!lshiftclick) for(auto& e: vd.edges) {
draw_edge(V, c, e.second);
if(vdata[e.first].m == shmup::mousetarget)
hi_weight = e.second->weight;
}
string *url = nullptr; if(vd.urls.size()) url = &vd.urls[0];
if(!vd.virt) {
queuedisk(V * m->at, vd.cp, false, url, i);
}
queuedisk(V * m->at, vd.cp, false, url, i);
if((showlabels || (show_edges && hi_weight)) && !darken) {
bool doshow = true;
if((vizflags & RV_COMPRESS_LABELS) && i > 0 && !vd.virt) {
if((vizflags & RV_COMPRESS_LABELS) && i > 0) {
vertexdata& vdp = vdata[vd.data];
shiftpoint h2 = ggmatrix(vdp.m->base) * vdp.m->at * C0;
if(hdist(h2, V * m->at * C0) < 0.1) doshow = false;

View File

@@ -24,7 +24,6 @@ ld hub_penalty;
string hub_filename;
vector<int> hubval;
vector<edgeinfo> sagedges;
vector<vector<int>> edges_yes, edges_no;
vector<vector<pair<int, double>>> edge_weights;
@@ -35,15 +34,27 @@ 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;
}
void prepare_graph() {
int DN = isize(sagid);
DEBBI(debug_init_sag, ("prepare_graph with DN = ", DN));
set<pair<int, int>> alledges;
for(auto e: sagedges) {
if(e.i == e.j) continue;
alledges.emplace(e.i, e.j);
alledges.emplace(e.j, e.i);
for(auto e: edgeinfos) {
if(e->i == e->j) continue;
alledges.emplace(e->i, e->j);
alledges.emplace(e->j, e->i);
}
edges_yes.clear(); edges_yes.resize(DN);
@@ -51,7 +62,7 @@ void prepare_graph() {
fixed_position.clear(); fixed_position.resize(DN);
for(int i=0; i<DN; i++) for(int j=0; j<DN; j++) if(i != j) {
for(int i=0; i<DN; i++) for(int j=0; j<DN; j++) if(take(i, j)) {
if(alledges.count({i, j}))
edges_yes[i].push_back(j);
else
@@ -59,11 +70,11 @@ void prepare_graph() {
}
edge_weights.clear(); edge_weights.resize(DN);
for(auto& e: sagedges) {
if(e.i == e.j) continue;
e.weight2 = pow((double) e.weight, (double) edgepower) * edgemul;
edge_weights[e.i].emplace_back(e.j, e.weight2);
edge_weights[e.j].emplace_back(e.i, e.weight2);
for(auto& e: edgeinfos) {
if(e->i == e->j) continue;
e->weight2 = pow((double) e->weight, (double) edgepower) * edgemul;
edge_weights[e->i].emplace_back(e->j, e->weight2);
edge_weights[e->j].emplace_back(e->i, e->weight2);
}
sagnode.clear();
@@ -86,14 +97,15 @@ void place_correctly() {
for(int i=0; i<DN; i++) {
int ci = sag::sagid[i];
vdata[i].m->base = sagcells[ci].first;
vdata[i].m->at = Id;
transmatrix T = Id;
if(allow_doubles) vdata[i].m->at =
if(allow_doubles) T =
spin(TAU*(qsf[ci]++) / qon[ci]) * xpush(rad * (qon[ci]-1) / qon[ci]);
if(isize(subcell_points) > 1)
vdata[i].m->at = rgpushxto0(subcell_points[sagcells[ci].second]) * vdata[i].m->at;
T = rgpushxto0(subcell_points[sagcells[ci].second]) * T;
vdata[i].be(sagcells[ci].first, T);
}
}
@@ -112,7 +124,6 @@ void create_viz() {
state |= SS_GRAPH;
if(!vact) for(int i=0; i<DN; i++) vdata[i].data = 0;
if(!vact) for(auto& e: sagedges) addedge0(e.i, e.j, &e);
if(sagcells[0].first == nullptr) return;
@@ -120,13 +131,10 @@ void create_viz() {
if(!vact) for(int i=0; i<DN; i++) {
vertexdata& vd = vdata[i];
vd.cp = colorpair(dftcolor);
rogueviz::createViz(i, sagcells[sagid[i]].first, Id);
vd.be(sagcells[sagid[i]].first, Id);
}
place_correctly();
if(!vact) storeall();
if(vact) shmup::fixStorage();
set_inverse();
vact = true;
}
@@ -234,11 +242,7 @@ void read_weighted(const char *fname) {
}
ld wei;
if(!scan(f, wei)) continue;
edgeinfo ei(sag_edge);
ei.i = getid(l1);
ei.j = getid(l2);
ei.weight = wei;
sagedges.push_back(ei);
addedge(getid(l1), getid(l2), wei, ensure_sag_edge());
}
after:
@@ -264,16 +268,16 @@ void read_unweighted(const char *fname) {
string l2 = scan<string>(f);
if(l1 == "") continue;
if(l2 == "") continue;
edgeinfo ei(sag_edge);
ei.i = getid(l1);
ei.j = getid(l2);
if(ei.i > ei.j) swap(ei.i, ei.j);
int i = getid(l1), j = getid(l2);
if(i > j) swap(i, j);
all++;
if(edges.count({ei.i, ei.j})) continue;
if(edges.count({i, j})) continue;
good++;
edges.emplace(ei.i, ei.j);
ei.weight = 1;
sagedges.push_back(ei);
edges.emplace(i, j);
addedge(i, j, 1, ensure_sag_edge());
}
println(hlog, "N = ", isize(vdata), " edges = ", good, "/", all);
@@ -322,19 +326,13 @@ void generate_fake_data(int n, int m) {
if(m > n || m < 0) throw hr_exception("generate_fake_data parameters incorrect");
sagid.resize(m);
int DN = isize(sagid);
vdata.resize(DN);
resize_vertices(DN);
for(int i=0; i<DN; i++)
vdata[i].name = its(i) + "@" + its(sagid[i]);
sag_edge = add_edgetype("SAG edge");
for(int i=0; i<DN; i++)
for(int j=i+1; j<DN; j++) {
edgeinfo ei(sag_edge);
ei.i = i;
ei.j = j;
ei.weight = 1. / sagdist[sagid[i]][sagid[j]];
sagedges.push_back(ei);
}
for(int j=i+1; j<DN; j++)
addedge(i, j, 1. / sagdist[sagid[i]][sagid[j]], ensure_sag_edge());
after_data();

View File

@@ -231,11 +231,12 @@ void output_stats() {
dhrg::iddata routing_result;
if(!known_pairs) { known_pairs = true; dhrg::prepare_pairs(DN, [] (int i) { return edges_yes[i]; }); }
dhrg::greedy_routing(routing_result, [] (int i, int j) { return sagdist[sagid[i]][sagid[j]]; });
print(hlog, "CSV;", logid++, ";", isize(sagnode), ";", DN, ";", isize(sagedges), ";", lgsag_pre.R, ";", lgsag_pre.T, ";", lgsag.R, ";", lgsag.T, ";", cost, ";", mAP, ";", MeanRank, ";", routing_result.suc / routing_result.tot, ";", routing_result.routedist / routing_result.bestdist);
print(hlog, "CSV;", logid++, ";", isize(sagnode), ";", DN, ";", isize(edgeinfos), ";", lgsag_pre.R, ";", lgsag_pre.T, ";", lgsag.R, ";", lgsag.T, ";", cost, ";", mAP, ";", MeanRank, ";", routing_result.suc / routing_result.tot, ";", routing_result.routedist / routing_result.bestdist);
if(lastmethod) print(hlog, ";", lastmethod);
if(mul_used) print(hlog, ";", mul_used);
if(report_tempi) print(hlog, ";", hightemp,";",lowtemp,";",format("%lld", numiter));
println(hlog);
println(hlog, "R=", lgsag.R, " T=", lgsag.T, " cost=", cost, " mAP=", mAP, " meanrank=", MeanRank);
}
int exp_read_args() {

View File

@@ -121,19 +121,18 @@ void optimize_sag_loglik_logistic() {
int N = isize(sagid);
for(int i=0; i<N; i++)
for(int j=0; j<i; j++) {
for(int j=0; j<i; j++) if(take(i, j)) {
int d = sagdist[sagid[i]][sagid[j]];
indist[d]++;
}
vector<int> pedge(max_sag_dist, 0);
for(int i=0; i<isize(sagedges); i++) {
edgeinfo& ei = sagedges[i];
for(auto& e: edgeinfos) {
// if(int(sagdist[sagid[ei.i]][sagid[ei.j]] * mul) == 136) printf("E %d,%d\n", ei.i, ei.j);
if(ei.i != ei.j)
if(ei.weight >= sag_edge->visible_from)
pedge[sagdist[sagid[ei.i]][sagid[ei.j]] * mul]++;
if(take(e->i, e->j))
if(e->weight >= sag_edge->visible_from)
pedge[sagdist[sagid[e->i]][sagid[e->j]] * mul]++;
}
if(debug_opt) for(int d=0; d<max_sag_dist; d++)
@@ -180,9 +179,9 @@ void optimize_sag_loglik_match() {
if(state &~ SS_WEIGHTED) return;
stats::leastsquare_solver<2> lsqs;
for(auto& ei: sagedges) {
ld y = sagdist[sagid[ei.i]][sagid[ei.j]];
ld x = 1. / ei.weight;
for(auto& e: edgeinfos) {
ld y = sagdist[sagid[e->i]][sagid[e->j]];
ld x = 1. / e->weight;
lsqs.add_data({{x, 1}}, y);
}
@@ -209,7 +208,7 @@ pair<ld, ld> compute_mAP() {
for(int i=0; i<DN; i++) {
vector<int> alldist(max_sag_dist, 0);
for(int j=0; j<DN; j++) if(i != j) alldist[sagdist[sagid[i]][sagid[j]]]++;
for(int j=0; j<DN; j++) if(take(i, j)) alldist[sagdist[sagid[i]][sagid[j]]]++;
vector<int> edgedist(max_sag_dist, 0);
for(auto j: edges_yes[i]) edgedist[sagdist[sagid[i]][sagid[j]]]++;
@@ -249,7 +248,7 @@ void compute_kendall() {
int DN = isize(sagid);
weights.resize(DN);
for(int i=0; i<DN; i++) weights[i].resize(DN, 0);
for(auto& e: sagedges) weights[e.i][e.j] += e.weight2, weights[e.j][e.i] += e.weight2;
for(auto& e: edgeinfos) weights[e->i][e->j] += e->weight2, weights[e->j][e->i] += e->weight2;
vector<pair<int, ld>> kdata;
for(int i=0; i<DN; i++) for(int j=0; j<i; j++) kdata.emplace_back(sagdist[sagid[i]][sagid[j]], -weights[i][j]);
kendall = stats::kendall(kdata);

View File

@@ -352,7 +352,6 @@ void init() {
}
void clear() {
sagedges.clear();
visualization_active = false;
neighbors.clear();
sagcells.clear();

View File

@@ -739,15 +739,12 @@ int showsample(int id) {
}
net[bids[id]].drawn_samples++;
}
int i = vdata.size();
sample_vdata_id[id] = i;
vdata.emplace_back();
auto& v = vdata.back();
auto& v = add_vertex();
sample_vdata_id[id] = v.id;
v.name = data[id].name;
v.cp = dftcolor;
createViz(i, bids.size() ? net[bids[id]].where : cwt.at, Id);
v.m->store();
return i;
v.be(bids.size() ? net[bids[id]].where : cwt.at, Id);
return v.id;
}
int showsample(string s) {
@@ -875,13 +872,11 @@ void initialize_samples_to_show() {
if(!noshow) for(int s: samples_to_show) {
int vdid = isize(vdata);
sample_vdata_id[s] = vdid;
vdata.emplace_back();
auto &vd = vdata.back();
auto &vd = add_vertex();
vd.name = data[s].name;
labeler[data[s].name] = vdid;
vd.cp = dftcolor;
createViz(vdid, cwt.at, Id);
storeall(vdid);
vd.be(cwt.at, Id);
}
samples_to_show.clear();
@@ -1303,7 +1298,7 @@ void load_edges(const string& fname_edges, string edgename, int pick = 0) {
int i = 0;
for(auto p: edgedata2)
if(p.first >= 0 && p.second >= 0)
addedge(p.first, p.second, 1 / (i+++.5), true, t);
addedge(p.first, p.second, 1 / (i+++.5), t);
else {
printf("error reading graph\n");
exit(1);
@@ -1315,7 +1310,7 @@ void random_edges(int q) {
vector<int> ssamp;
for(auto p: sample_vdata_id) ssamp.push_back(p.second);
for(int i=0; i<q; i++)
addedge(ssamp[hrand(isize(ssamp))], ssamp[hrand(isize(ssamp))], 0, true, t);
addedge(ssamp[hrand(isize(ssamp))], ssamp[hrand(isize(ssamp))], 0, t);
}
void klistsamples(const string& fname_samples, bool best, bool colorformat) {
@@ -1588,16 +1583,14 @@ void load_compressed(string name) {
f.read(d.name);
int i = vdata.size();
sample_vdata_id[id] = i;
vdata.emplace_back();
auto& v = vdata.back();
auto& v = add_vertex();
v.name = data[i].name;
struct colorpair_old { color_t color1, color2; char shade; } cpo;
hread_raw(f, cpo);
v.cp.color1 = cpo.color1;
v.cp.color2 = cpo.color2;
v.cp.shade = cpo.shade;
createViz(i, cwt.at, Id);
v.m->store();
v.be(cwt.at, Id);
id++;
}
// load edge types
@@ -1614,7 +1607,7 @@ void load_compressed(string name) {
int ei = f.get<int>();
int ej = f.get<int>();
float w = f.get_raw<float>();
addedge(ei, ej, w, true, &*t);
addedge(ei, ej, w, &*t);
}
analyze();
}

View File

@@ -179,7 +179,7 @@ void create_edgedata() {
if(!using_subdata) {
for(auto e: edges)
addedge(e.first, e.second, 1, false, any);
addedge(e.first, e.second, 1, any);
}
else {
vector<int> nearest(isize(orig_data), -1);
@@ -201,7 +201,7 @@ void create_edgedata() {
subedges.emplace(nearest[e.first], nearest[e.second]);
// for(auto se: subedges) println(hlog, "subedges = ", se);
for(auto sube: subedges)
addedge(sube.first, sube.second, 1, false, any);
addedge(sube.first, sube.second, 1, any);
}
println(hlog, "edgedata created, ", using_subdata);

View File

@@ -88,21 +88,15 @@ namespace tree {
vd.m = new shmup::monster;
vd.m->pid = i;
vd.data = lv.parent;
createViz(i, cwt.at, h);
vd.be(cwt.at, h);
vd.cp = dftcolor;
if(tol[i].parent >= 0)
addedge(i, tol[i].parent, 1, true, tree_edge);
}
for(int i=0; i<isize(vdata); i++) {
vertexdata& vd = vdata[i];
virtualRebase(vd.m);
addedge(i, tol[i].parent, 1, tree_edge);
}
printf("Clearing the TOL data...\n");
tol.clear();
storeall();
}
int ah = arg::add3("-tree", [] { tree::read(arg::shift_args()); })