aboutsummaryrefslogtreecommitdiff
path: root/cube.c
diff options
context:
space:
mode:
Diffstat (limited to 'cube.c')
-rw-r--r--cube.c95
1 files changed, 94 insertions, 1 deletions
diff --git a/cube.c b/cube.c
index 508ed0d..fd6b0cf 100644
--- a/cube.c
+++ b/cube.c
@@ -126,6 +126,9 @@ Section: constants, strings and other stuff
126#define _coshift 5U 126#define _coshift 5U
127 127
128#define _pbits 0xFU 128#define _pbits 0xFU
129#define _esepbit1 0x4U
130#define _esepbit2 0x8U
131#define _csepbit 0x4U
129#define _eobit 0x10U 132#define _eobit 0x10U
130#define _cobits 0xF0U 133#define _cobits 0xF0U
131#define _cobits2 0x60U 134#define _cobits2 0x60U
@@ -484,6 +487,21 @@ static char *transstr[] = {
484 [BLm] = "mirrored BL", 487 [BLm] = "mirrored BL",
485}; 488};
486 489
490static int64_t binomial[12][12] = {
491 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
492 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
493 {1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
494 {1, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0},
495 {1, 4, 6, 4, 1, 0, 0, 0, 0, 0, 0, 0},
496 {1, 5, 10, 10, 5, 1, 0, 0, 0, 0, 0, 0},
497 {1, 6, 15, 20, 15, 6, 1, 0, 0, 0, 0, 0},
498 {1, 7, 21, 35, 35, 21, 7, 1, 0, 0, 0, 0},
499 {1, 8, 28, 56, 70, 56, 28, 8, 1, 0, 0, 0},
500 {1, 9, 36, 84, 126, 126, 84, 36, 9, 1, 0, 0},
501 {1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1, 0},
502 {1, 11, 55, 165, 330, 462, 462, 330, 165, 55, 11, 1},
503};
504
487/****************************************************************************** 505/******************************************************************************
488Section: AVX2 fast methods 506Section: AVX2 fast methods
489 507
@@ -500,6 +518,7 @@ typedef __m256i cube_fast_t;
500#define _co2_avx2 _mm256_set_epi64x(0, 0, 0, 0x6060606060606060) 518#define _co2_avx2 _mm256_set_epi64x(0, 0, 0, 0x6060606060606060)
501#define _cocw_avx2 _mm256_set_epi64x(0, 0, 0, 0x2020202020202020) 519#define _cocw_avx2 _mm256_set_epi64x(0, 0, 0, 0x2020202020202020)
502#define _cp_avx2 _mm256_set_epi64x(0, 0, 0, 0x0707070707070707) 520#define _cp_avx2 _mm256_set_epi64x(0, 0, 0, 0x0707070707070707)
521#define _ep_avx2 _mm256_set_epi64x(0x0F0F0F0F, 0x0F0F0F0F0F0F0F0F, 0, 0)
503#define _eo_avx2 _mm256_set_epi64x(0x10101010, 0x1010101010101010, 0, 0) 522#define _eo_avx2 _mm256_set_epi64x(0x10101010, 0x1010101010101010, 0, 0)
504 523
505_static_inline cube_fast_t fastcube( 524_static_inline cube_fast_t fastcube(
@@ -518,6 +537,7 @@ _static_inline cube_fast_t compose_fast(cube_fast_t, cube_fast_t);
518_static_inline int64_t coord_fast_co(cube_fast_t); 537_static_inline int64_t coord_fast_co(cube_fast_t);
519_static_inline int64_t coord_fast_csep(cube_fast_t); 538_static_inline int64_t coord_fast_csep(cube_fast_t);
520_static_inline int64_t coord_fast_eo(cube_fast_t); 539_static_inline int64_t coord_fast_eo(cube_fast_t);
540_static_inline int64_t coord_fast_esep(cube_fast_t);
521 541
522_static_inline cube_fast_t 542_static_inline cube_fast_t
523fastcube( 543fastcube(
@@ -686,6 +706,36 @@ coord_fast_eo(cube_fast_t c)
686 return mask >> 17; 706 return mask >> 17;
687} 707}
688 708
709_static_inline int64_t
710coord_fast_esep(cube_fast_t c)
711{
712 cube_fast_t ep;
713 int64_t e, mem[4], i, j, k, l, ret1, ret2, bit1, bit2, is1;
714
715 ep = _mm256_and_si256(c, _ep_avx2);
716 _mm256_storeu_si256((__m256i *)mem, ep);
717
718 mem[3] <<= 8L;
719 ret1 = ret2 = 0;
720 k = l = 4;
721 for (i = 0, j = 0; i < 12; i++, mem[i/8 + 2] >>= 8L) {
722 e = mem[i/8 + 2];
723
724 bit1 = (e & _esepbit1) >> 2L;
725 bit2 = (e & _esepbit2) >> 3L;
726 is1 = (1 - bit2) * bit1;
727
728 ret1 += bit2 * binomial[11-i][k];
729 k -= bit2;
730
731 ret2 += is1 * binomial[7-j][l];
732 l -= is1;
733 j += (1-bit2);
734 }
735
736 return ret1 * 70 + ret2;
737}
738
689/****************************************************************************** 739/******************************************************************************
690Section: ARM NEON fast methods 740Section: ARM NEON fast methods
691 741
@@ -730,6 +780,7 @@ _static_inline cube_fast_t compose_fast(cube_fast_t, cube_fast_t);
730_static_inline int64_t coord_fast_co(cube_fast_t); 780_static_inline int64_t coord_fast_co(cube_fast_t);
731_static_inline int64_t coord_fast_csep(cube_fast_t); 781_static_inline int64_t coord_fast_csep(cube_fast_t);
732_static_inline int64_t coord_fast_eo(cube_fast_t); 782_static_inline int64_t coord_fast_eo(cube_fast_t);
783_static_inline int64_t coord_fast_esep(cube_fast_t);
733 784
734_static_inline cube_fast_t 785_static_inline cube_fast_t
735fastcube( 786fastcube(
@@ -863,6 +914,13 @@ coord_fast_co(cube_fast_t c)
863 return ret; 914 return ret;
864} 915}
865 916
917/*
918For corner separation, we consider the axis (a.k.a. tetrad) each
919corner belongs to as 0 or 1 and we translate this sequence into binary.
920Ignoring the last bit, we have a value up to 2^7, but not all values are
921possible. Encoding this as a number from 0 to C(8,4) would save about 40%
922of space, but we are not going to use this coordinate in large tables.
923*/
866_static_inline int64_t 924_static_inline int64_t
867coord_fast_csep(cube_fast_t c) 925coord_fast_csep(cube_fast_t c)
868{ 926{
@@ -870,7 +928,7 @@ coord_fast_csep(cube_fast_t c)
870 int64_t ret; 928 int64_t ret;
871 929
872 for (ret = 0, i = 0, p = 1; i < 7; i++, p *= 2) 930 for (ret = 0, i = 0, p = 1; i < 7; i++, p *= 2)
873 ret += p * ((c.corner[i] & _pbits) >> 2U); 931 ret += p * ((c.corner[i] & _csepbit) >> 2U);
874 932
875 return ret; 933 return ret;
876} 934}
@@ -887,6 +945,41 @@ coord_fast_eo(cube_fast_t c)
887 return ret; 945 return ret;
888} 946}
889 947
948/*
949We encode the edge separation as a number from 0 to C(12,4)*C(8,4).
950It can be seen as the composition of two "subset index" coordinates.
951*/
952_static_inline int64_t
953coord_fast_esep(cube_fast_t c)
954{
955 int64_t i, j, k, l, ret1, ret2, bit1, bit2, is1;
956
957 for (i = 0, j = 0, k = 4, l = 4, ret1 = 0, ret2 = 0; i < 12; i++) {
958 /* Simple version:
959 if (c.edge[i] & _esepbit2) {
960 ret1 += binomial[11-i][k--];
961 } else {
962 if (c.edge[i] & _esepbit1)
963 ret2 += binomial[7-j][l--];
964 j++;
965 }
966 */
967
968 bit1 = (c.edge[i] & _esepbit1) >> 2U;
969 bit2 = (c.edge[i] & _esepbit2) >> 3U;
970 is1 = (1 - bit2) * bit1;
971
972 ret1 += bit2 * binomial[11-i][k];
973 k -= bit2;
974
975 ret2 += is1 * binomial[7-j][l];
976 l -= is1;
977 j += (1-bit2);
978 }
979
980 return ret1 * 70 + ret2;
981}
982
890#endif 983#endif
891 984
892/****************************************************************************** 985/******************************************************************************

Generated with cgit - Back to sebastiano.tronto.net