29static_assert(std::is_trivial<BMat8>(),
"BMat8 is not a trivial class!");
31static const constexpr std::array<uint64_t, 8> ROW_MASK = {
32 {0xff00000000000000, 0xff000000000000, 0xff0000000000, 0xff00000000,
33 0xff000000, 0xff0000, 0xff00, 0xff}};
35static const constexpr std::array<uint64_t, 8> COL_MASK = {
36 0x8080808080808080, 0x4040404040404040, 0x2020202020202020,
37 0x1010101010101010, 0x808080808080808, 0x404040404040404,
38 0x202020202020202, 0x101010101010101};
40static const constexpr std::array<uint64_t, 64> BIT_MASK = {{0x8000000000000000,
108 return (_data << (8 * i + j)) >> 63;
111inline void BMat8::set(
size_t i,
size_t j,
bool val)
noexcept {
114 _data ^= (-val ^ _data) & BIT_MASK[8 * i + j];
119 std::array<std::array<bool, 8>, 8>
res;
120 for (
int i = 0; i < 64; i++) {
121 res[7 - i / 8][7 - i % 8] = a % 2;
133 for (
auto const &row : mat) {
135 for (
auto entry : row) {
141 pow =
pow >> (8 - mat.size());
146 static std::random_device _rd;
147 static std::mt19937 _gen(_rd());
148 static std::uniform_int_distribution<uint64_t> _dist(0, 0xffffffffffffffff);
150 return BMat8(_dist(_gen));
158 for (
size_t i = dim; i < 8; ++i) {
159 bm._data &= ~ROW_MASK[i];
160 bm._data &= ~COL_MASK[i];
167 for (
int i = 0; i < 8; i++) {
168 for (
int j = 0; j < 8; j++) {
169 res = (
res << 1) | (*
this)(j, i);
177 uint64_t y = (x ^ (x >> 7)) & 0xAA00AA00AA00AA;
178 x = x ^ y ^ (y << 7);
179 y = (x ^ (x >> 14)) & 0xCCCC0000CCCC;
180 x = x ^ y ^ (y << 14);
181 y = (x ^ (x >> 28)) & 0xF0F0F0F0;
182 x = x ^ y ^ (y << 28);
187 epu8 x = simde_mm_set_epi64x(_data, _data << 1);
188 uint64_t
res = simde_mm_movemask_epi8(x);
190 res =
res << 16 | simde_mm_movemask_epi8(x);
192 res =
res << 16 | simde_mm_movemask_epi8(x);
194 res =
res << 16 | simde_mm_movemask_epi8(x);
200 simde_mm_movemask_epi8(simde_mm_set_epi64x(_data, _data << 1));
202 simde_mm_movemask_epi8(simde_mm_set_epi64x(_data << 2, _data << 3));
204 simde_mm_movemask_epi8(simde_mm_set_epi64x(_data << 4, _data << 5));
206 simde_mm_movemask_epi8(simde_mm_set_epi64x(_data << 6, _data << 7));
210using epu64 = uint64_t __attribute__((__vector_size__(16), __may_alias__));
213 epu64 x = simde_mm_set_epi64x(a._data, b._data);
214 epu64 y = (x ^ (x >> 7)) & (
epu64{0xAA00AA00AA00AA, 0xAA00AA00AA00AA});
215 x = x ^ y ^ (y << 7);
216 y = (x ^ (x >> 14)) & (
epu64{0xCCCC0000CCCC, 0xCCCC0000CCCC});
217 x = x ^ y ^ (y << 14);
218 y = (x ^ (x >> 28)) & (
epu64{0xF0F0F0F0, 0xF0F0F0F0});
219 x = x ^ y ^ (y << 28);
220 a._data = simde_mm_extract_epi64(x, 1);
221 b._data = simde_mm_extract_epi64(x, 0);
224static constexpr epu8 rotlow{7, 0, 1, 2, 3, 4, 5, 6};
225static constexpr epu8 rothigh{0, 1, 2, 3, 4, 5, 6, 7,
226 15, 8, 9, 10, 11, 12, 13, 14};
227static constexpr epu8 rotboth{7, 0, 1, 2, 3, 4, 5, 6,
228 15, 8, 9, 10, 11, 12, 13, 14};
229static constexpr epu8 rot2{6, 7, 0, 1, 2, 3, 4, 5,
230 14, 15, 8, 9, 10, 11, 12, 13};
233 epu8 x = simde_mm_set_epi64x(_data, _data);
234 epu8 y = simde_mm_shuffle_epi8(simde_mm_set_epi64x(that._data, that._data),
237 epu8 diag{0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
238 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40};
239 for (
int i = 0; i < 4; ++i) {
240 data |= ((x & y) !=
epu8{}) & diag;
241 y = simde_mm_shuffle_epi8(y, rot2);
242 diag = simde_mm_shuffle_epi8(diag, rot2);
244 return BMat8(simde_mm_extract_epi64(data, 0) |
245 simde_mm_extract_epi64(data, 1));
250 for (
int i = 0; i < 8; i++) {
251 for (
int j = 0; j < 8; j++) {
253 for (
int k = 0; k < 8; k++) {
254 a |= ((*this)(i, k) & that(k, j));
262 std::array<std::array<bool, 8>, 8> tab1 =
to_array(),
263 tab2 = that.to_array();
265 for (
int i = 0; i < 8; i++) {
266 for (
int j = 0; j < 8; j++) {
268 for (
int k = 0; k < 8; k++) {
269 a |= tab1[i][k] & tab2[k][j];
276inline epu8 BMat8::row_space_basis_internal() const noexcept {
281 for (
int i = 0; i < 7; i++) {
283 orincl |= ((rescy |
res) ==
res) & rescy;
291 simde_mm_extract_epi64(
sorted8(row_space_basis_internal()), 0));
295#error FF is defined !
299constexpr std::array<epu8, 4>
masks{{
301 {
FF, 0,
FF, 0,
FF, 0,
FF, 0,
FF, 0,
FF, 0,
FF, 0,
FF, 0},
302 {
FF,
FF, 1, 1,
FF,
FF, 1, 1,
FF,
FF, 1, 1,
FF,
FF, 1, 1},
303 {
FF,
FF,
FF,
FF, 2, 2, 2, 2,
FF,
FF,
FF,
FF, 2, 2, 2, 2},
304 {
FF,
FF,
FF,
FF,
FF,
FF,
FF,
FF, 3, 3, 3, 3, 3, 3, 3, 3}
308static const epu8 shiftres{1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
314 static const epu8 bound08 = simde_mm_slli_epi32(
315 static_cast<simde__m128i
>(
Epu8.id()), 3);
316 static const epu8 bound18 = bound08 +
Epu8(0x80);
317 for (
size_t slice8 = 0; slice8 < 16; slice8++) {
319 epu8 shft = simde_mm_shuffle_epi8(shiftres, block - bm5);
320 set0 |= (bm5 == bound08) & shft;
321 set1 |= (bm5 == bound18) & shft;
322 block = simde_mm_shuffle_epi8(block,
Epu8.right_cycle());
328 epu8 in = simde_mm_set_epi64x(0, _data);
329 epu8 block0{}, block1{};
331 block0 |=
static_cast<epu8>(simde_mm_shuffle_epi8(in, m));
332 block1 |=
static_cast<epu8>(simde_mm_shuffle_epi8(in, m |
Epu8(4)));
336 for (
size_t r = 0; r < 16; r++) {
338 block1 = simde_mm_shuffle_epi8(block1,
Epu8.right_cycle());
345 return (__builtin_popcountll(simde_mm_extract_epi64(res0, 0)) +
346 __builtin_popcountll(simde_mm_extract_epi64(res1, 0)) +
347 __builtin_popcountll(simde_mm_extract_epi64(res0, 1)) +
348 __builtin_popcountll(simde_mm_extract_epi64(res1, 1)));
352 epu8 in = simde_mm_set_epi64x(_data, _data);
355 for (
size_t r = 0; r < 16; r++) {
357 for (
int i = 0; i < 8; i++) {
358 orincl |= ((in | block) == block) & in;
361 res += __builtin_popcountll(simde_mm_movemask_epi8(block == orincl));
368 epu8 in = simde_mm_set_epi64x(_data, _data);
371 for (
size_t r = 0; r < 16; r++) {
372 epu8 orincl = ((in | block) == block) & in;
373 for (
int i = 0; i < 7; i++) {
375 orincl |= ((in | block) == block) & in;
377 res += __builtin_popcountll(simde_mm_movemask_epi8(block == orincl));
384 epu8 this0, this1, other0, other1;
386 other.row_space_bitset(other0, other1);
388 return equal(this0 | other0, other0) &&
equal(this1 | other1, other1);
392 epu8 in = simde_mm_set_epi64x(0, other._data);
393 epu8 block = simde_mm_set_epi64x(0, _data);
394 epu8 orincl = ((in | block) == block) & in;
395 for (
int i = 0; i < 7; i++) {
397 orincl |= ((in | block) == block) & in;
399 return equal(block, orincl);
403 epu8 in = simde_mm_set_epi64x(_data, _data);
404 epu8 orincl = ((in | block) == block) & in;
405 for (
int i = 0; i < 7; i++) {
407 orincl |= ((in | block) == block) & in;
409 return block == orincl;
414 epu8 in = simde_mm_set_epi64x(b1._data, b0._data);
415 epu8 block = simde_mm_set_epi64x(
a1._data, a0._data);
416 epu8 orincl = ((in | block) == block) & in;
417 for (
int i = 0; i < 7; i++) {
419 orincl |= ((in | block) == block) & in;
422 return std::make_pair(simde_mm_extract_epi64(
res, 0) == -1,
423 simde_mm_extract_epi64(
res, 1) == -1);
427 std::bitset<256> lookup;
429 auto last = std::remove(row_vec.begin(), row_vec.end(), 0);
430 row_vec.erase(last, row_vec.end());
431 for (uint8_t x : row_vec) {
435 std::vector<uint8_t> row_space(row_vec.begin(), row_vec.end());
436 for (
size_t i = 0; i < row_space.size(); ++i) {
437 for (uint8_t row : row_vec) {
438 uint8_t x = row_space[i] | row;
440 row_space.push_back(x);
450 std::bitset<256> otherspace = other.row_space_bitset_ref();
451 return (thisspace | otherspace) == otherspace;
459 std::vector<uint8_t>
rows;
460 for (
size_t i = 0; i < 8; ++i) {
461 uint8_t row =
static_cast<uint8_t
>(_data << (8 * i) >> 56);
468 epu8 x = simde_mm_set_epi64x(_data, 0);
469 return __builtin_popcountll(simde_mm_movemask_epi8(x !=
epu8{}));
472static constexpr epu8 rev8{7, 6, 5, 4, 3, 2, 1, 0,
473 8, 9, 10, 11, 12, 13, 14, 15};
476 epu8 x = simde_mm_set_epi64x(0, _data);
480 return BMat8(simde_mm_extract_epi64(x, 0));
484 return transpose().row_permuted(p).transpose();
488 return one().row_permuted(p);
492 return one().row_permuted(p).transpose();
497 std::vector<uint8_t>
rows = this->
rows();
498 BMat8 product = *
this * bm;
499 std::vector<uint8_t> prod_rows = product.
rows();
503 std::vector<uint8_t> perm(8);
504 for (
size_t i = 0; i <
nr_rows(); ++i) {
505 uint8_t row =
rows[i];
507 std::distance(prod_rows.begin(),
508 std::find(prod_rows.begin(), prod_rows.end(), row));
512#pragma GCC diagnostic push
513#pragma GCC diagnostic ignored "-Wstringop-overflow"
517#pragma GCC diagnostic pop
521 for (
size_t i = 0; i < 8; i++)
528 epu8 y =
permuted(simde_mm_set_epi64x((*
this * other)._data, 0),
540 for (
size_t i = 0; i < 8; ++i) {
541 for (
size_t j = 0; j < 8; ++j) {
uint8_t __attribute__((vector_size(16))) epu8
epu8 stands for Extended Packed Unsigned, grouped by 8 bits; this is the low level type chosen by Int...
Definition epu8.hpp:73
#define FF
Definition bmat8_impl.hpp:297
Boolean matrices of dimension up to 8×8, stored as a single uint64; isomorph to binary relations with...
Definition bmat8.hpp:55
std::array< std::array< bool, 8 >, 8 > to_array() const noexcept
Returns the array representation of this.
Definition bmat8_impl.hpp:117
uint64_t row_space_size_incl() const noexcept
Returns the cardinality of the row space of this.
Definition bmat8_impl.hpp:367
BMat8 mult_naive_array(BMat8 const &that) const noexcept
Returns the matrix product of this and that.
Definition bmat8_impl.hpp:261
BMat8 row_space_basis() const noexcept
Returns a canonical basis of the row space of this.
Definition bmat8_impl.hpp:289
BMat8 mult_naive(BMat8 const &that) const noexcept
Returns the matrix product of this and that.
Definition bmat8_impl.hpp:248
static std::pair< bool, bool > row_space_included2(BMat8 a1, BMat8 b1, BMat8 a2, BMat8 b2)
Returns inclusion of row spaces.
Definition bmat8_impl.hpp:412
static void transpose2(BMat8 &, BMat8 &) noexcept
Transpose two matrices at once.
Definition bmat8_impl.hpp:212
uint64_t row_space_size_bitset() const noexcept
Returns the cardinality of the row space of this.
Definition bmat8_impl.hpp:342
static BMat8 row_permutation_matrix(Perm16 p) noexcept
Returns the matrix associated to the permutation p by rows.
Definition bmat8_impl.hpp:487
BMat8 mult_transpose(BMat8 const &that) const noexcept
Returns the matrix product of this and the transpose of that.
Definition bmat8_impl.hpp:232
BMat8 transpose_maskd() const noexcept
Returns the transpose of this.
Definition bmat8_impl.hpp:198
bool row_space_included_bitset(BMat8 other) const noexcept
Returns whether the row space of this is included in other's.
Definition bmat8_impl.hpp:383
BMat8 transpose() const noexcept
Returns the transpose of this.
Definition bmat8_impl.hpp:175
static BMat8 col_permutation_matrix(Perm16 p) noexcept
Returns the matrix associated to the permutation p by columns.
Definition bmat8_impl.hpp:491
epu8 row_space_mask(epu8 vects) const noexcept
Returns a mask for which vectors of a 16 rows epu8 are in the row space of this.
Definition bmat8_impl.hpp:402
BMat8 row_permuted(Perm16 p) const noexcept
Returns the matrix whose rows have been permuted according to p.
Definition bmat8_impl.hpp:475
BMat8() noexcept=default
A default constructor.
bool row_space_included(BMat8 other) const noexcept
Returns whether the row space of this is included in other's.
Definition bmat8_impl.hpp:391
std::ostream & write(std::ostream &os) const
Write this on os.
Definition bmat8_impl.hpp:536
void row_space_bitset(epu8 &res1, epu8 &res2) const noexcept
Returns the the row space of this as 256 bits.
Definition bmat8_impl.hpp:327
Perm16 right_perm_action_on_basis(BMat8) const noexcept
Give the permutation whose right multiplication change *this to other.
Definition bmat8_impl.hpp:526
std::bitset< 256 > row_space_bitset_ref() const
Returns the the row space of this.
Definition bmat8_impl.hpp:426
BMat8 col_permuted(Perm16 p) const noexcept
Returns the matrix whose columns have been permuted according to p.
Definition bmat8_impl.hpp:483
uint64_t to_int() const noexcept
Returns the integer representation of this.
Definition bmat8.hpp:147
uint64_t row_space_size_ref() const
Returns the cardinality of the row space of this.
Definition bmat8_impl.hpp:454
BMat8 transpose_naive() const noexcept
Returns the transpose of this.
Definition bmat8_impl.hpp:165
BMat8 transpose_mask() const noexcept
Returns the transpose of this.
Definition bmat8_impl.hpp:186
static BMat8 one(size_t dim=8) noexcept
Returns the identity BMat8.
Definition bmat8.hpp:358
std::vector< uint8_t > rows() const
Returns a std::vector for rows of this.
Definition bmat8_impl.hpp:458
size_t nr_rows() const noexcept
Returns the number of non-zero rows of this.
Definition bmat8_impl.hpp:467
void set(size_t i, size_t j, bool val) noexcept
Sets the (i, j)th position to val.
Definition bmat8_impl.hpp:111
static BMat8 random()
Returns a random BMat8.
Definition bmat8_impl.hpp:145
bool operator()(size_t i, size_t j) const noexcept
Returns the entry in the (i, j)th position.
Definition bmat8_impl.hpp:105
uint64_t row_space_size_incl1() const noexcept
Returns the cardinality of the row space of this.
Definition bmat8_impl.hpp:351
bool row_space_included_ref(BMat8 other) const noexcept
Returns whether the row space of this is included in other's.
Definition bmat8_impl.hpp:448
Perm16 right_perm_action_on_basis_ref(BMat8) const
Give the permutation whose right multiplication change *this to other.
Definition bmat8_impl.hpp:495
#define HPCOMBI_ASSERT(x)
Definition debug.hpp:31
const Transf16 a1
Definition image.cpp:52
std::array< std::tuple< uint16_t, uint16_t, std::array< uint16_t, gens.size()> >, 65536 > res
Definition image.cpp:66
Definition bmat8_impl.hpp:310
void row_space_update_bitset(epu8 block, epu8 &set0, epu8 &set1) noexcept
Definition bmat8_impl.hpp:312
epu8 permuted(epu8 a, epu8 b) noexcept
Same as permuted_ref but with an optimized implementation using intrinsics.
Definition epu8.hpp:103
uint64_t __attribute__((__vector_size__(16), __may_alias__)) epu64
Definition bmat8_impl.hpp:210
epu8 remove_dups(epu8 a, uint8_t repl=0) noexcept
Remove duplicates in a sorted HPCombi::epu8.
Definition epu8_impl.hpp:261
epu8 revsorted8(epu8 a) noexcept
Return a HPCombi::epu8 with both halves reverse sorted.
Definition epu8_impl.hpp:213
epu8 permutation_of(epu8 a, epu8 b) noexcept
Find if a vector is a permutation of another one.
Definition epu8_impl.hpp:304
bool equal(epu8 a, epu8 b) noexcept
Equality of HPCombi::epu8.
Definition epu8.hpp:91
epu8 sorted8(epu8 a) noexcept
Return a HPCombi::epu8 with both halves sorted.
Definition epu8_impl.hpp:207
constexpr TPUBuild< epu8 > Epu8
Factory object acting as a class constructor for type HPCombi::epu8.
Definition epu8.hpp:81
constexpr std::array< epu8, 4 > masks
Definition bmat8_impl.hpp:299
uint8_t __attribute__((vector_size(16))) epu8
epu8 stands for Extended Packed Unsigned, grouped by 8 bits; this is the low level type chosen by Int...
Definition epu8.hpp:73
const T pow(const T x)
A generic compile time exponentiation function.
Definition power.hpp:91
Definition bmat16_impl.hpp:362
std::ostream & operator<<(std::ostream &os, HPCombi::BMat16 const &bm)
Definition bmat16_impl.hpp:365
Permutations of : A permutation is a bijective mapping of a set of n elements onto itself.
Definition perm16.hpp:237
static constexpr Perm16 one()
The identity partial permutation.
Definition perm16.hpp:252