--- /dev/null
+/*
+ * actually do mapping from metaspace to realspace
+ */
+
+#include "half.h"
+
+/*
+ * Our metaspace dimensions are, in order:
+ * - y realspace coordinate of symmetry axis vertices
+ * - x,y,z realspace coordinates of even-y opposite-of-axis vertices
+ * - x,y,z realspace coordinates of even-y non-axis vertices
+ * - x,y,z realspace coordinates of odd-y vertices in canonical order
+ */
+
+#define FOR_MAP_DIMENSION__VERTEX_PAIR(body,mirror) \
+ k=0; sign=-1; { body } { mirror } i++; \
+ k=1; sign=+1; { body } { mirror } i++; \
+ k=2; sign=-1; { body } { mirror } i++;
+
+/*#define FOR_MAP_DIMENSION_VPRIME \
+ int vprime= N-1-v
+ */
+
+#define FOR_MAP_DIMENSION(body, mirror, degenerate) \
+ do{ \
+ int i,v,vprime,k,sign; /* public */ \
+ int fmd_i, fmd_x, fmd_y; \
+ i= 0; \
+ for (fmd_i=0; fmd_i<HALF_DEGRADED_NVERTICES; fmd_i++) { \
+ v= fmd_i*X*2; \
+ k=0; { degenerate } \
+ k=1; sign=+1; { body } i++; \
+ k=2; { degenerate } \
+ } \
+ for (fmd_y=0; fmd_y<Y; fmd_y+=2) { \
+ v= fmd_y << YSHIFT | (X/2); \
+ FOR_MAP_DIMENSION__VERTEX_PAIR(body,) \
+ } \
+ for (fmd_y=0; fmd_y<Y; fmd_y+=2) \
+ for (fmd_x=1; fmd_x<X/2; fmd_x++) { \
+ v= fmd_y << YSHIFT | fmd_x; \
+ vprime= ((Y-1) << YSHIFT | X) - v; \
+ FOR_MAP_DIMENSION__VERTEX_PAIR(body,mirror) \
+ } \
+ for (fmd_y=1; fmd_y<Y; fmd_y+=2) \
+ for (fmd_x=0; fmd_x<X/2; fmd_x++) { \
+ v= fmd_y << YSHIFT | fmd_x; \
+ vprime= ((Y-1) << YSHIFT | (X-1)) - v; \
+ FOR_MAP_DIMENSION__VERTEX_PAIR(body,mirror) \
+ } \
+ assert(i == DIM); \
+ }while(0)
+
+void pmap_dimensions(const struct Vertices *vs) {
+ int ixfrom[N][D3], count[N][D3], bad;
+ int vc,kc;
+
+ bad= 0;
+
+ FOR_VERTEX(vc)
+ FOR_COORD(kc) {
+ count[vc][kc]= 0;
+ ixfrom[vc][kc]= -1;
+ }
+
+#define CHECK_V(v) assert(v >= 0); assert(v < N);
+#define CHECK_NEAR(a,b) \
+ if (abs(a-b) >= 1e-6) { printf(" BAD!"); bad++; } \
+ putchar('\n');
+
+ FOR_MAP_DIMENSION(
+ (printf("i=%2d v=%03x k=%d %# 20g\n",
+ i,v,k,
+ vs->a[v][k]
+ ));
+ CHECK_V(v)
+ ixfrom[v][k]=i;
+ count[v][k]++;,
+
+// FOR_MAP_DIMENSION_VPRIME;
+ (printf("i=%2d v'=%03x k=%d %# 20g := %# 20g",
+ i,vprime,k,
+ vs->a[vprime][k], sign*vs->a[v][k]
+ ));
+ CHECK_V(vprime)
+ CHECK_NEAR(vs->a[vprime][k], sign*vs->a[v][k])
+ ixfrom[vprime][k]=-i;
+ count[vprime][k]++;,
+
+ (printf("zero v=%03x k=%d %# 20g := 0",
+ v,k,
+ vs->a[v][k]
+ ));
+ CHECK_V(v)
+ CHECK_NEAR(vs->a[v][k], 0)
+ count[v][k]++;
+ );
+
+ FOR_VERTEX(vc)
+ FOR_COORD(kc) {
+ if (count[vc][kc]==1) continue;
+ printf("BAD %03x %d count=%d ixfrom=%d\n",
+ vc,kc, count[vc][kc], ixfrom[vc][kc]);
+ bad++;
+ }
+ assert(!bad);
+}
+
+void map_dimensions(const double metavertex[DIM], Vertices out) {
+ FOR_MAP_DIMENSION(out[v ][k]= metavertex[i];,
+
+// FOR_MAP_DIMENSION_VPRIME;
+ out[vprime][k]= sign*metavertex[i];,
+
+ out[v ][k]= 0;
+ );
+}
+
+void unmap_dimensions(double metavertex[DIM], const struct Vertices *in) {
+ FOR_MAP_DIMENSION(
+ metavertex[i]= in->a[v][k];,
+ ,
+ );
+}
+
+
+/*
+ * OLD NUMBERING
+ *
+ * Our numbering is as follows:
+ *
+ * :axis of symmetry
+ * | :
+ * | :
+ * ___| 0 ___ 1 ___ 2 ___ 3 ___ 4 ___ up to X"-1
+ * | : where X"=(X/2)
+ * / :\ / \ / \ / \ / \
+ * /| : \ / \ / \ / \ / \
+ * |___ 0 ___ 1 ___ 2 ___ 3 ___ 4
+ * | : +X" +X" +X" +X" +X"
+ * \| : / \ / \ / \ / \ /
+ * \ :/ \ / \ / \ / \ /
+ * ___|2*X"___ 1+ ___ 2+ ___ 3+ __ 4+ ___
+ * | : 2*X" 2*X" 2*X" 2*X"
+ * / :\ / \ / \ / \ / \
+ * /| : \ / \ / \ / \ / \
+ * |___ 0+ ___ 1+ ___ 2+ ___ 3+ ___ 4+
+ * | : 3*X" 3*X" 3*X" 3*X" 3*X"
+ * | :
+ *
+ * X" is still a power of two so a vertex pair can be named by a
+ * number structured like this:
+ *
+ * vertex number": 0000 | y | x
+ * YBITS XBITS-1
+ *
+ */