aboutsummaryrefslogtreecommitdiff
path: root/src/fst.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fst.c')
-rw-r--r--src/fst.c124
1 files changed, 80 insertions, 44 deletions
diff --git a/src/fst.c b/src/fst.c
index df5b81f..7fee732 100644
--- a/src/fst.c
+++ b/src/fst.c
@@ -3,7 +3,6 @@
3#include "fst.h" 3#include "fst.h"
4 4
5static FstCube ep_to_fst_epos(int *ep); 5static FstCube ep_to_fst_epos(int *ep);
6static void transform_ep_only(Trans t, int *ep, Cube *dst);
7static void init_fst_corner_invtables(); 6static void init_fst_corner_invtables();
8static void init_fst_eo_invtables(); 7static void init_fst_eo_invtables();
9static void init_fst_eo_update(uint64_t, uint64_t, int, Cube *); 8static void init_fst_eo_update(uint64_t, uint64_t, int, Cube *);
@@ -54,24 +53,12 @@ cube_to_fst(Cube *cube)
54static FstCube 53static FstCube
55ep_to_fst_epos(int *ep) 54ep_to_fst_epos(int *ep)
56{ 55{
57 /* TODO: maybe optimize */
58 56
59/* TODO: this version if faster, but broken 57/* The block of commented code works, but it is slower.
60 probably need to fix transform_ep_only() 58 The actual code is mysterious, and there is some overlap with coord.c
61 59 (coord_eposepe.i), and trans.c, butbut it is faster. */
62 FstCube ret;
63 Cube c;
64
65 memcpy(c.ep, ep, 12 * sizeof(int));
66 ret.uf_eposepe = coord_eposepe.i[0]->index(&c);
67
68 transform_ep_only(fr, ep, &c);
69 ret.fr_eposepe = coord_eposepe.i[0]->index(&c);
70
71 transform_ep_only(rd, ep, &c);
72 ret.rd_eposepe = coord_eposepe.i[0]->index(&c);
73*/
74 60
61/*
75 FstCube ret; 62 FstCube ret;
76 Cube c, d; 63 Cube c, d;
77 64
@@ -90,16 +77,89 @@ ep_to_fst_epos(int *ep)
90 ret.rd_eposepe = coord_eposepe.i[0]->index(&d); 77 ret.rd_eposepe = coord_eposepe.i[0]->index(&d);
91 78
92 return ret; 79 return ret;
80*/
81
82 static int eind[12] = {
83 [FR] = 0, [FL] = 1, [BL] = 2, [BR] = 3,
84 [UR] = 0, [DR] = 1, [DL] = 2, [UL] = 3,
85 [DB] = 0, [DF] = 1, [UF] = 2, [UB] = 3
86 };
87 static int eptrans_fr[12] = {
88 [FR] = UF, [DF] = UL, [FL] = UB, [UF] = UR,
89 [BR] = DF, [DB] = DL, [BL] = DB, [UB] = DR,
90 [UR] = FR, [DR] = FL, [DL] = BL, [UL] = BR
91 };
92 static int eptrans_rd[12] = {
93 [DR] = UF, [FR] = UL, [UR] = UB, [BR] = UR,
94 [DL] = DF, [FL] = DL, [UL] = DB, [BL] = DR,
95 [DB] = FR, [DF] = FL, [UF] = BL, [UB] = BR
96 };
97
98 FstCube ret;
99 int i, ce, cs, cm;
100 int epe[4], eps[4], epm[4], epose[12], eposs[12], eposm[12];
101
102 memset(epose, 0, 12*sizeof(int));
103 memset(eposs, 0, 12*sizeof(int));
104 memset(eposm, 0, 12*sizeof(int));
105
106 for (i = 0, ce = 0; i < 12; i++) {
107 switch (edge_slice[ep[i]]) {
108 case 0:
109 epose[i] = 1;
110 epe[ce++] = eind[ep[i]];
111 break;
112 case 1:
113 eposs[eptrans_fr[i]] = eind[ep[i]] + 1;
114 break;
115 default:
116 eposm[eptrans_rd[i]] = eind[ep[i]] + 1;
117 break;
118 }
119 }
120
121 for (i = 0, cs = 0, cm = 0; i < 12; i++) {
122 if (eposs[i]) {
123 eps[cs++] = eposs[i] - 1;
124 eposs[i] = 1;
125 }
126 if (eposm[i]) {
127 epm[cm++] = eposm[i] - 1;
128 eposm[i] = 1;
129 }
130 }
131
132 ret.uf_eposepe = subset_to_index(epose, 12, 4) * FACTORIAL4 +
133 perm_to_index(epe, 4);
134 ret.fr_eposepe = subset_to_index(eposs, 12, 4) * FACTORIAL4 +
135 perm_to_index(eps, 4);
136 ret.rd_eposepe = subset_to_index(eposm, 12, 4) * FACTORIAL4 +
137 perm_to_index(epm, 4);
138
139 return ret;
93} 140}
94 141
95FstCube 142FstCube
96fst_inverse(FstCube fst) 143fst_inverse(FstCube fst)
97{ 144{
98 FstCube ret; 145 FstCube ret;
99 int i, ep_inv[12]; 146 int ep_inv[12];
147
148 ep_inv[FR] = fst_where_is_edge_arr[0][FR][fst.uf_eposepe];
149 ep_inv[FL] = fst_where_is_edge_arr[0][FL][fst.uf_eposepe];
150 ep_inv[BL] = fst_where_is_edge_arr[0][BL][fst.uf_eposepe];
151 ep_inv[BR] = fst_where_is_edge_arr[0][BR][fst.uf_eposepe];
152
153 ep_inv[UR] = fst_where_is_edge_arr[1][UR][fst.fr_eposepe];
154 ep_inv[UL] = fst_where_is_edge_arr[1][UL][fst.fr_eposepe];
155 ep_inv[DR] = fst_where_is_edge_arr[1][DR][fst.fr_eposepe];
156 ep_inv[DL] = fst_where_is_edge_arr[1][DL][fst.fr_eposepe];
157
158 ep_inv[UF] = fst_where_is_edge_arr[2][UF][fst.rd_eposepe];
159 ep_inv[UB] = fst_where_is_edge_arr[2][UB][fst.rd_eposepe];
160 ep_inv[DF] = fst_where_is_edge_arr[2][DF][fst.rd_eposepe];
161 ep_inv[DB] = fst_where_is_edge_arr[2][DB][fst.rd_eposepe];
100 162
101 for (i = 0; i < 12; i++)
102 ep_inv[i] = fst_where_is_edge(i, fst);
103 ret = ep_to_fst_epos(ep_inv); 163 ret = ep_to_fst_epos(ep_inv);
104 164
105 ret.uf_eofb = ((uint16_t)eo_invtable[0][fst.uf_eofb][fst.uf_eposepe]) | 165 ret.uf_eofb = ((uint16_t)eo_invtable[0][fst.uf_eofb][fst.uf_eposepe]) |
@@ -175,30 +235,6 @@ fst_to_cube(FstCube fst, Cube *cube)
175 cube->xp[i] = i; 235 cube->xp[i] = i;
176} 236}
177 237
178int
179fst_where_is_edge(int e, FstCube fst)
180{
181 switch (edge_slice[e]) {
182 case 0:
183 return fst_where_is_edge_arr[0][e][fst.uf_eposepe];
184 case 1:
185 return fst_where_is_edge_arr[1][e][fst.fr_eposepe];
186 default:
187 return fst_where_is_edge_arr[2][e][fst.rd_eposepe];
188 }
189
190 return -1;
191}
192
193static void
194transform_ep_only(Trans t, int *ep, Cube *dst)
195{
196 int i;
197
198 for (i = 0; i < 12; i++)
199 dst->ep[i] = trans_ep_alg[t][ep[trans_ep_inv[t][i]]];
200}
201
202void 238void
203init_fst() 239init_fst()
204{ 240{

Generated with cgit - Back to sebastiano.tronto.net