mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-01-11 09:50:34 +00:00
reg3/field:: incorrect field computations generate errors; fixed a bug in suspending discovery; more elegant fieldpattern search not based on cgi.rels
This commit is contained in:
parent
3f32112937
commit
14a9961f92
@ -142,14 +142,23 @@ struct fpattern {
|
||||
}
|
||||
|
||||
int sqr(int x) { return mul(x,x); }
|
||||
|
||||
|
||||
int err;
|
||||
|
||||
matrix mmul(const matrix& A, const matrix& B) {
|
||||
matrix res;
|
||||
for(int i=0; i<MWDIM; i++) for(int k=0; k<MWDIM; k++) {
|
||||
int t = 0;
|
||||
#ifdef EASY
|
||||
for(int j=0; j<MWDIM; j++) t += mul(A[i][j], B[j][k]);
|
||||
t %= Prime;
|
||||
int tp = 0, tn = 0;
|
||||
for(int j=0; j<MWDIM; j++) {
|
||||
int val = mul(A[i][j], B[j][k]);
|
||||
if(val > 0) tp += val;
|
||||
else tn += val;
|
||||
}
|
||||
tp %= Prime; tn %= Prime;
|
||||
if(tp && tn) err++;
|
||||
t = tp + tn;
|
||||
#else
|
||||
for(int j=0; j<MWDIM; j++) t = add(t, mul(A[i][j], B[j][k]));
|
||||
#endif
|
||||
@ -362,12 +371,13 @@ struct discovery {
|
||||
#endif
|
||||
|
||||
bool fpattern::check_order(matrix M, int req) {
|
||||
int err = 0;
|
||||
matrix P = M;
|
||||
for(int i=1; i<req; i++) {
|
||||
if(P == Id) return false;
|
||||
P = mmul(P, M);
|
||||
}
|
||||
return P == Id;
|
||||
return P == Id && !err;
|
||||
}
|
||||
|
||||
vector<matrix> fpattern::generate_isometries() {
|
||||
@ -497,6 +507,7 @@ unsigned fpattern::compute_hash() {
|
||||
bool fpattern::generate_all3() {
|
||||
|
||||
reg3::generate_fulls();
|
||||
err = 0;
|
||||
|
||||
matrices.clear();
|
||||
matcode.clear();
|
||||
@ -505,19 +516,23 @@ bool fpattern::generate_all3() {
|
||||
for(int i=0; i<isize(matrices); i++) {
|
||||
add1(mmul(matrices[i], R), fullv[i] * cgi.full_R);
|
||||
add1(mmul(matrices[i], X), fullv[i] * cgi.full_X);
|
||||
if(err) return false;
|
||||
}
|
||||
local_group = isize(matrices);
|
||||
if(local_group != isize(cgi.cellrotations)) return false;
|
||||
|
||||
for(int i=0; i<(int)matrices.size(); i++) {
|
||||
matrix E = mmul(matrices[i], P);
|
||||
if(!matcode.count(E))
|
||||
for(int j=0; j<local_group; j++) add1(mmul(E, matrices[j]));
|
||||
if(err) return false;
|
||||
if(isize(matrices) >= limitv) { println(hlog, "limitv exceeded"); return false; }
|
||||
}
|
||||
hashv = compute_hash();
|
||||
DEBB(DF_FIELD, ("all = ", isize(matrices), "/", local_group, " = ", isize(matrices) / local_group, " hash = ", hashv, " count = ", ++hash_found[hashv]));
|
||||
|
||||
if(use_quotient_fp)
|
||||
generate_quotientgroup();
|
||||
generate_quotientgroup();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -588,7 +603,8 @@ void fpattern::generate_quotientgroup() {
|
||||
EX purehookset hooks_solve3;
|
||||
|
||||
int fpattern::solve3() {
|
||||
reg3::construct_relations();
|
||||
|
||||
reg3::generate_fulls();
|
||||
|
||||
DEBB(DF_FIELD, ("generating isometries for ", Field));
|
||||
|
||||
@ -597,10 +613,6 @@ int fpattern::solve3() {
|
||||
|
||||
int cmb = 0;
|
||||
|
||||
int N = isize(cgi.rels);
|
||||
|
||||
vector<int> fails(N);
|
||||
|
||||
vector<matrix> possible_P, possible_X, possible_R;
|
||||
|
||||
for(auto& M: iso3) {
|
||||
@ -616,20 +628,18 @@ int fpattern::solve3() {
|
||||
DEBB(DF_FIELD, ("field = ", Field, " #P = ", isize(possible_P), " #X = ", isize(possible_X), " #R = ", isize(possible_R), " r_order = ", cgi.r_order, " xp_order = ", cgi.xp_order));
|
||||
|
||||
for(auto& xX: possible_X)
|
||||
for(auto& xP: possible_P) if(check_order(mmul(xP, xX), cgi.xp_order))
|
||||
for(auto& xR: possible_R) if(check_order(mmul(xR, xX), cgi.rx_order)) { // if(xR[0][0] == 1 && xR[0][1] == 0)
|
||||
#if CAP_THREAD && MAXMDIM >+ 4
|
||||
for(auto& xP: possible_P) if(check_order(mmul(xP, xX), cgi.xp_order))
|
||||
for(auto& xR: possible_R) if(check_order(mmul(xR, xX), cgi.rx_order)) {
|
||||
|
||||
err = 0;
|
||||
if(mmul(xX, xP) != mmul(xR, mmul(mmul(xP, xX), xR))) continue;
|
||||
if(err) continue;
|
||||
|
||||
#if CAP_THREAD && MAXMDIM >= 4
|
||||
if(dis) dis->check_suspend();
|
||||
if(dis && dis->stop_it) return 0;
|
||||
#endif
|
||||
auto by = [&] (char ch) -> matrix& { return ch == 'X' ? xX : ch == 'R' ? xR : xP; };
|
||||
for(int i=0; i<N; i++) {
|
||||
matrix ml = Id;
|
||||
for(char c: cgi.rels[i].first) { ml = mmul(ml, by(c)); if(ml == Id) { fails[i]++; goto bad; }}
|
||||
matrix mr = Id;
|
||||
for(char c: cgi.rels[i].second) { mr = mmul(mr, by(c)); if(mr == Id) { fails[i]++; goto bad; }}
|
||||
if(ml != mr) { fails[i]++; goto bad;}
|
||||
}
|
||||
|
||||
P = xP; R = xR; X = xX;
|
||||
if(!generate_all3()) continue;
|
||||
callhooks(hooks_solve3);
|
||||
@ -639,13 +649,11 @@ int fpattern::solve3() {
|
||||
if(force_hash && hashv != force_hash) continue;
|
||||
cmb++;
|
||||
goto ok;
|
||||
bad: ;
|
||||
}
|
||||
|
||||
|
||||
ok:
|
||||
|
||||
DEBB(DF_FIELD, ("cmb = ", cmb, " for field = ", Field));
|
||||
for(int i=0; i<N; i++) if(fails[i]) DEBB(DF_FIELD, (cgi.rels[i], " fails = ", fails[i]));
|
||||
|
||||
return cmb;
|
||||
}
|
||||
|
64
reg3.cpp
64
reg3.cpp
@ -2766,70 +2766,6 @@ EX void generate_fulls() {
|
||||
println(hlog, "orders = ", tie(cgi.rx_order, cgi.r_order, cgi.xp_order));
|
||||
}
|
||||
|
||||
EX void construct_relations() {
|
||||
auto& rels = cgi.rels;
|
||||
if(!rels.empty()) return;
|
||||
rels.clear();
|
||||
|
||||
reg3::generate_cellrotations();
|
||||
reg3::generate_fulls();
|
||||
vector<transmatrix> all;
|
||||
|
||||
vector<string> formulas;
|
||||
|
||||
formulas.push_back("");
|
||||
|
||||
all.push_back(Id);
|
||||
auto& faces = cgi.heptshape->faces;
|
||||
hyperpoint v = faces[0][0];
|
||||
auto add = [&] (transmatrix T) {
|
||||
for(int i=0; i<isize(all); i++) if(eqmatrix(all[i], T)) return i;
|
||||
int S = isize(all);
|
||||
all.push_back(T);
|
||||
return S;
|
||||
};
|
||||
|
||||
println(hlog, faces);
|
||||
|
||||
println(hlog, "cellshape = ", isize(faces));
|
||||
bool ok = true;
|
||||
int last_i = -1;
|
||||
for(auto& v: faces) for(hyperpoint h: v) {
|
||||
int i = 0, j = 0;
|
||||
for(auto& uv: faces) for(hyperpoint u: uv) {
|
||||
if(hdist(h, cgi.full_X*u) < 5e-2) i++;
|
||||
if(hdist(h, cgi.full_R*u) < 5e-2) j++;
|
||||
}
|
||||
if(last_i == -1) last_i = i;
|
||||
if(i != j || i != last_i) ok = false;
|
||||
}
|
||||
|
||||
if(!ok) { println(hlog, "something wrong"); exit(1); }
|
||||
|
||||
add(Id);
|
||||
|
||||
auto work = [&] (transmatrix T, int p, char c) {
|
||||
if(hdist0(tC0(T)) > 5) return;
|
||||
for(auto& hv: faces) for(hyperpoint h: hv) if(hdist(T * h, v) < 1e-4) goto ok;
|
||||
return;
|
||||
ok:
|
||||
int id = add(T);
|
||||
// println(hlog, p, " x ", (s0+c), " = ", id);
|
||||
|
||||
if(id >= isize(formulas)) formulas.push_back(formulas[p] + c);
|
||||
else if(id == 0) println(hlog, "reached identity: ", formulas[p]+c);
|
||||
else if(formulas[p][0] != formulas[id][0])
|
||||
rels.emplace_back(formulas[p] + c, formulas[id]);
|
||||
};
|
||||
|
||||
for(int i=0; i<isize(all); i++) {
|
||||
transmatrix T = all[i];
|
||||
work(T * cgi.full_R, i, 'R');
|
||||
work(T * cgi.full_X, i, 'X');
|
||||
work(T * cgi.full_P, i, 'P');
|
||||
}
|
||||
}
|
||||
|
||||
eVariation target_variation;
|
||||
flagtype target_coxeter;
|
||||
int target_subcube_count;
|
||||
|
Loading…
Reference in New Issue
Block a user