1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2026-01-02 02:19:02 +00:00
Files
hyperrogue/rogueviz/embeddings/polar.cpp
2025-12-11 10:11:42 +01:00

101 lines
2.8 KiB
C++

namespace rogueviz {
namespace embeddings {
double graph_R, graph_alpha, graph_T;
struct polar_point {
ld r, theta;
};
struct polar_embedding : public untiled_embedding {
vector<polar_point> coords;
virtual string name() override { return "polar in BFKL format"; }
virtual int get_dimension() override { return 2; }
hyperpoint as_hyperpoint(int id) override {
return spin(coords[id].theta) * xpush0(coords[id].r);
}
ld zero_distance(int id) override { return coords[id].r; }
ld distance(int i, int j) override {
ld da = coords[i].r;
ld db = coords[j].r;
ld phi = coords[i].theta - coords[j].theta;
ld co = sinh(da) * sinh(db) * (1 - cos(phi));
ld v = cosh(da - db) + co;
if(v < 1) return 0;
return acosh(v);
}
void save(fhstream& f) override {
println(f, "n R alpha t");
println(f, isize(vdata), " ", cont_logistic.R, " ", graph_alpha, " ", cont_logistic.T);
int i = 0;
for(auto& co: coords)
println(f, vdata[i++].name, format(" %.20lf %.20lf", co.r, co.theta / degree));
}
};
/** read polar coordinates, in the format returned by the BFKL embdder. */
void read_polar(const string& fn) {
if(fn == "-") {
auto pe = std::make_shared<polar_embedding> ();
int N = isize(vdata);
pe->coords.resize(N);
for(int i=0; i<N; i++) {
auto h = current->as_hyperpoint(i);
pe->coords[i] = { hdist0(h), atan2(h) };
}
return enable_embedding(pe);
}
fhstream f(fn, "rt");
if(!f.f) return file_error(fn);
int N;
println(hlog, "Reading coordinates...\n");
string ignore;
if(!scan(f, ignore, ignore, ignore, ignore, N, graph_R, graph_alpha, graph_T)) {
println(hlog, "Error: incorrect format of the first line\n"); exit(1);
}
if(graph_R && graph_T) cont_logistic.setRT(graph_R, graph_T);
if(N == 0) N = isize(vdata);
if(N != isize(vdata)) throw hr_exception("incorrect N");
auto pe = std::make_shared<polar_embedding> ();
pe->coords.resize(N);
for(int i=0; i<N; i++) {
string s = scan<string>(f);
if(s == "" || s == "#ROGUEVIZ_ENDOFDATA") throw hr_exception("data failure");
int id = rogueviz::labeler.at(s);
double r, theta;
if(!scan(f, r, theta)) { println(hlog, "Error: incorrect format of r/alpha\n"); exit(1); }
pe->coords[id] = polar_point{r, theta * degree};
}
enable_embedding(pe);
}
int a_polar =
arg::add3("-el-polar", [] { arg::shift(); read_polar(arg::args()); })
+ arg::add3("-el-bfkl", [] { arg::shift(); read_edgelist(arg::args() + "-links.txt"); read_polar(arg::args() + "-coordinates.txt"); });
}
}