HPCombi
High Performance Combinatorics in C++ using vector instructions v1.0.3
Loading...
Searching...
No Matches
bmat8_impl.hpp
Go to the documentation of this file.
1//****************************************************************************//
2// Copyright (C) 2018-2024 Finn Smith <fls3@st-andrews.ac.uk> //
3// Copyright (C) 2018-2024 James Mitchell <jdm3@st-andrews.ac.uk> //
4// Copyright (C) 2018-2024 Florent Hivert <Florent.Hivert@lisn.fr>, //
5// //
6// This file is part of HP-Combi <https://github.com/libsemigroups/HPCombi> //
7// //
8// HP-Combi is free software: you can redistribute it and/or modify it //
9// under the terms of the GNU General Public License as published by the //
10// Free Software Foundation, either version 3 of the License, or //
11// (at your option) any later version. //
12// //
13// HP-Combi is distributed in the hope that it will be useful, but WITHOUT //
14// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or //
15// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License //
16// for more details. //
17// //
18// You should have received a copy of the GNU General Public License along //
19// with HP-Combi. If not, see <https://www.gnu.org/licenses/>. //
20//****************************************************************************//
21
26// NOLINT(build/header_guard)
27
28namespace HPCombi {
29static_assert(std::is_trivial<BMat8>(), "BMat8 is not a trivial class!");
30
31static const constexpr std::array<uint64_t, 8> ROW_MASK = {
32 {0xff00000000000000, 0xff000000000000, 0xff0000000000, 0xff00000000,
33 0xff000000, 0xff0000, 0xff00, 0xff}};
34
35static const constexpr std::array<uint64_t, 8> COL_MASK = {
36 0x8080808080808080, 0x4040404040404040, 0x2020202020202020,
37 0x1010101010101010, 0x808080808080808, 0x404040404040404,
38 0x202020202020202, 0x101010101010101};
39
40static const constexpr std::array<uint64_t, 64> BIT_MASK = {{0x8000000000000000,
41 0x4000000000000000,
42 0x2000000000000000,
43 0x1000000000000000,
44 0x800000000000000,
45 0x400000000000000,
46 0x200000000000000,
47 0x100000000000000,
48 0x80000000000000,
49 0x40000000000000,
50 0x20000000000000,
51 0x10000000000000,
52 0x8000000000000,
53 0x4000000000000,
54 0x2000000000000,
55 0x1000000000000,
56 0x800000000000,
57 0x400000000000,
58 0x200000000000,
59 0x100000000000,
60 0x80000000000,
61 0x40000000000,
62 0x20000000000,
63 0x10000000000,
64 0x8000000000,
65 0x4000000000,
66 0x2000000000,
67 0x1000000000,
68 0x800000000,
69 0x400000000,
70 0x200000000,
71 0x100000000,
72 0x80000000,
73 0x40000000,
74 0x20000000,
75 0x10000000,
76 0x8000000,
77 0x4000000,
78 0x2000000,
79 0x1000000,
80 0x800000,
81 0x400000,
82 0x200000,
83 0x100000,
84 0x80000,
85 0x40000,
86 0x20000,
87 0x10000,
88 0x8000,
89 0x4000,
90 0x2000,
91 0x1000,
92 0x800,
93 0x400,
94 0x200,
95 0x100,
96 0x80,
97 0x40,
98 0x20,
99 0x10,
100 0x8,
101 0x4,
102 0x2,
103 0x1}};
104
105inline bool BMat8::operator()(size_t i, size_t j) const noexcept {
106 HPCOMBI_ASSERT(i < 8);
107 HPCOMBI_ASSERT(j < 8);
108 return (_data << (8 * i + j)) >> 63;
109}
110
111inline void BMat8::set(size_t i, size_t j, bool val) noexcept {
112 HPCOMBI_ASSERT(i < 8);
113 HPCOMBI_ASSERT(j < 8);
114 _data ^= (-val ^ _data) & BIT_MASK[8 * i + j];
115}
116
117inline BMat8::BMat8(std::vector<std::vector<bool>> const &mat) {
118 HPCOMBI_ASSERT(mat.size() <= 8);
119 HPCOMBI_ASSERT(0 < mat.size());
120 _data = 0;
121 uint64_t pow = 1;
122 pow = pow << 63;
123 for (auto const &row : mat) {
124 HPCOMBI_ASSERT(row.size() == mat.size());
125 for (auto entry : row) {
126 if (entry) {
127 _data ^= pow;
128 }
129 pow = pow >> 1;
130 }
131 pow = pow >> (8 - mat.size());
132 }
133}
134
136 static std::random_device _rd;
137 static std::mt19937 _gen(_rd());
138 static std::uniform_int_distribution<uint64_t> _dist(0, 0xffffffffffffffff);
139
140 return BMat8(_dist(_gen));
141}
142
143inline BMat8 BMat8::random(size_t const dim) {
144 HPCOMBI_ASSERT(0 < dim && dim <= 8);
145 BMat8 bm = BMat8::random();
146 for (size_t i = dim; i < 8; ++i) {
147 bm._data &= ~ROW_MASK[i];
148 bm._data &= ~COL_MASK[i];
149 }
150 return bm;
151}
152
153inline BMat8 BMat8::transpose() const noexcept {
154 uint64_t x = _data;
155 uint64_t y = (x ^ (x >> 7)) & 0xAA00AA00AA00AA;
156 x = x ^ y ^ (y << 7);
157 y = (x ^ (x >> 14)) & 0xCCCC0000CCCC;
158 x = x ^ y ^ (y << 14);
159 y = (x ^ (x >> 28)) & 0xF0F0F0F0;
160 x = x ^ y ^ (y << 28);
161 return BMat8(x);
162}
163
164inline BMat8 BMat8::transpose_mask() const noexcept {
165 epu8 x = simde_mm_set_epi64x(_data, _data << 1);
166 uint64_t res = simde_mm_movemask_epi8(x);
167 x = x << Epu8(2);
168 res = res << 16 | simde_mm_movemask_epi8(x);
169 x = x << Epu8(2);
170 res = res << 16 | simde_mm_movemask_epi8(x);
171 x = x << Epu8(2);
172 res = res << 16 | simde_mm_movemask_epi8(x);
173 return BMat8(res);
174}
175
176inline BMat8 BMat8::transpose_maskd() const noexcept {
177 uint64_t res =
178 simde_mm_movemask_epi8(simde_mm_set_epi64x(_data, _data << 1));
179 res = res << 16 |
180 simde_mm_movemask_epi8(simde_mm_set_epi64x(_data << 2, _data << 3));
181 res = res << 16 |
182 simde_mm_movemask_epi8(simde_mm_set_epi64x(_data << 4, _data << 5));
183 res = res << 16 |
184 simde_mm_movemask_epi8(simde_mm_set_epi64x(_data << 6, _data << 7));
185 return BMat8(res);
186}
187
188using epu64 = uint64_t __attribute__((__vector_size__(16), __may_alias__));
189
190inline void BMat8::transpose2(BMat8 &a, BMat8 &b) noexcept {
191 epu64 x = simde_mm_set_epi64x(a._data, b._data);
192 epu64 y = (x ^ (x >> 7)) & (epu64{0xAA00AA00AA00AA, 0xAA00AA00AA00AA});
193 x = x ^ y ^ (y << 7);
194 y = (x ^ (x >> 14)) & (epu64{0xCCCC0000CCCC, 0xCCCC0000CCCC});
195 x = x ^ y ^ (y << 14);
196 y = (x ^ (x >> 28)) & (epu64{0xF0F0F0F0, 0xF0F0F0F0});
197 x = x ^ y ^ (y << 28);
198 a._data = simde_mm_extract_epi64(x, 1);
199 b._data = simde_mm_extract_epi64(x, 0);
200}
201
202static constexpr epu8 rotlow{7, 0, 1, 2, 3, 4, 5, 6};
203static constexpr epu8 rothigh{0, 1, 2, 3, 4, 5, 6, 7,
204 15, 8, 9, 10, 11, 12, 13, 14};
205static constexpr epu8 rotboth{7, 0, 1, 2, 3, 4, 5, 6,
206 15, 8, 9, 10, 11, 12, 13, 14};
207static constexpr epu8 rot2{6, 7, 0, 1, 2, 3, 4, 5,
208 14, 15, 8, 9, 10, 11, 12, 13};
209
210inline BMat8 BMat8::mult_transpose(BMat8 const &that) const noexcept {
211 epu8 x = simde_mm_set_epi64x(_data, _data);
212 epu8 y = simde_mm_shuffle_epi8(simde_mm_set_epi64x(that._data, that._data),
213 rothigh);
214 epu8 data{};
215 epu8 diag{0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
216 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40};
217 for (int i = 0; i < 4; ++i) {
218 data |= ((x & y) != epu8{}) & diag;
219 y = simde_mm_shuffle_epi8(y, rot2);
220 diag = simde_mm_shuffle_epi8(diag, rot2);
221 }
222 return BMat8(simde_mm_extract_epi64(data, 0) |
223 simde_mm_extract_epi64(data, 1));
224}
225
226inline epu8 BMat8::row_space_basis_internal() const noexcept {
227 epu8 res = remove_dups(revsorted8(simde_mm_set_epi64x(0, _data)));
228 epu8 rescy = res;
229 // We now compute the union of all the included different rows
230 epu8 orincl{};
231 for (int i = 0; i < 7; i++) {
232 rescy = permuted(rescy, rotlow);
233 orincl |= ((rescy | res) == res) & rescy;
234 }
235 res = (res != orincl) & res;
236 return res;
237}
238
239inline BMat8 BMat8::row_space_basis() const noexcept {
240 return BMat8(
241 simde_mm_extract_epi64(sorted8(row_space_basis_internal()), 0));
242}
243
244#if defined(FF)
245#error FF is defined !
246#endif // FF
247#define FF 0xff
248
249constexpr std::array<epu8, 4> masks{{
250 // clang-format off
251 {FF, 0,FF, 0,FF, 0,FF, 0,FF, 0,FF, 0,FF, 0,FF, 0}, // NOLINT()
252 {FF,FF, 1, 1,FF,FF, 1, 1,FF,FF, 1, 1,FF,FF, 1, 1}, // NOLINT()
253 {FF,FF,FF,FF, 2, 2, 2, 2,FF,FF,FF,FF, 2, 2, 2, 2}, // NOLINT()
254 {FF,FF,FF,FF,FF,FF,FF,FF, 3, 3, 3, 3, 3, 3, 3, 3} // NOLINT()
255 }};
256#undef FF
257
258static const epu8 shiftres{1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
259
260namespace detail {
261
262inline void row_space_update_bitset(epu8 block, epu8 &set0, epu8 &set1)
263noexcept {
264 static const epu8 bound08 = simde_mm_slli_epi32(
265 static_cast<simde__m128i>(Epu8.id()), 3); // shift for *8
266 static const epu8 bound18 = bound08 + Epu8(0x80);
267 for (size_t slice8 = 0; slice8 < 16; slice8++) {
268 epu8 bm5 = Epu8(0xf8) & block; /* 11111000 */
269 epu8 shft = simde_mm_shuffle_epi8(shiftres, block - bm5);
270 set0 |= (bm5 == bound08) & shft;
271 set1 |= (bm5 == bound18) & shft;
272 block = simde_mm_shuffle_epi8(block, Epu8.right_cycle());
273 }
274}
275} // namespace detail
276
277inline void BMat8::row_space_bitset(epu8 &res0, epu8 &res1) const noexcept {
278 epu8 in = simde_mm_set_epi64x(0, _data);
279 epu8 block0{}, block1{};
280 for (epu8 m : masks) {
281 block0 |= static_cast<epu8>(simde_mm_shuffle_epi8(in, m));
282 block1 |= static_cast<epu8>(simde_mm_shuffle_epi8(in, m | Epu8(4)));
283 }
284 res0 = epu8{};
285 res1 = epu8{};
286 for (size_t r = 0; r < 16; r++) {
287 detail::row_space_update_bitset(block0 | block1, res0, res1);
288 block1 = simde_mm_shuffle_epi8(block1, Epu8.right_cycle());
289 }
290}
291
292inline uint64_t BMat8::row_space_size_bitset() const noexcept {
293 epu8 res0{}, res1{};
294 row_space_bitset(res0, res1);
295 return (__builtin_popcountll(simde_mm_extract_epi64(res0, 0)) +
296 __builtin_popcountll(simde_mm_extract_epi64(res1, 0)) +
297 __builtin_popcountll(simde_mm_extract_epi64(res0, 1)) +
298 __builtin_popcountll(simde_mm_extract_epi64(res1, 1)));
299}
300
301inline uint64_t BMat8::row_space_size_incl1() const noexcept {
302 epu8 in = simde_mm_set_epi64x(_data, _data);
303 epu8 block = Epu8.id();
304 uint64_t res = 0;
305 for (size_t r = 0; r < 16; r++) {
306 epu8 orincl{};
307 for (int i = 0; i < 8; i++) {
308 orincl |= ((in | block) == block) & in;
309 in = permuted(in, rotboth);
310 }
311 res += __builtin_popcountll(simde_mm_movemask_epi8(block == orincl));
312 block += Epu8(16);
313 }
314 return res;
315}
316
317inline uint64_t BMat8::row_space_size_incl() const noexcept {
318 epu8 in = simde_mm_set_epi64x(_data, _data);
319 epu8 block = Epu8.id();
320 uint64_t res = 0;
321 for (size_t r = 0; r < 16; r++) {
322 epu8 orincl = ((in | block) == block) & in;
323 for (int i = 0; i < 7; i++) { // Only rotating
324 in = permuted(in, rotboth);
325 orincl |= ((in | block) == block) & in;
326 }
327 res += __builtin_popcountll(simde_mm_movemask_epi8(block == orincl));
328 block += Epu8(16);
329 }
330 return res;
331}
332
333inline bool BMat8::row_space_included_bitset(BMat8 other) const noexcept {
334 epu8 this0, this1, other0, other1;
335 this->row_space_bitset(this0, this1);
336 other.row_space_bitset(other0, other1);
337 // Double inclusion of bitsets
338 return equal(this0 | other0, other0) && equal(this1 | other1, other1);
339}
340
341inline bool BMat8::row_space_included(BMat8 other) const noexcept {
342 epu8 in = simde_mm_set_epi64x(0, other._data);
343 epu8 block = simde_mm_set_epi64x(0, _data);
344 epu8 orincl = ((in | block) == block) & in;
345 for (int i = 0; i < 7; i++) { // Only rotating
346 in = permuted(in, rotlow);
347 orincl |= ((in | block) == block) & in;
348 }
349 return equal(block, orincl);
350}
351
352inline epu8 BMat8::row_space_mask(epu8 block) const noexcept {
353 epu8 in = simde_mm_set_epi64x(_data, _data);
354 epu8 orincl = ((in | block) == block) & in;
355 for (int i = 0; i < 7; i++) { // Only rotating
356 in = permuted(in, rotboth);
357 orincl |= ((in | block) == block) & in;
358 }
359 return block == orincl;
360}
361
362inline std::pair<bool, bool> BMat8::row_space_included2(BMat8 a0, BMat8 b0,
363 BMat8 a1, BMat8 b1) {
364 epu8 in = simde_mm_set_epi64x(b1._data, b0._data);
365 epu8 block = simde_mm_set_epi64x(a1._data, a0._data);
366 epu8 orincl = ((in | block) == block) & in;
367 for (int i = 0; i < 7; i++) { // Only rotating
368 in = permuted(in, rotboth);
369 orincl |= ((in | block) == block) & in;
370 }
371 epu8 res = (block == orincl);
372 return std::make_pair(simde_mm_extract_epi64(res, 0) == -1,
373 simde_mm_extract_epi64(res, 1) == -1);
374}
375
376inline std::bitset<256> BMat8::row_space_bitset_ref() const {
377 std::bitset<256> lookup;
378 std::vector<uint8_t> row_vec = row_space_basis().rows();
379 auto last = std::remove(row_vec.begin(), row_vec.end(), 0);
380 row_vec.erase(last, row_vec.end());
381 for (uint8_t x : row_vec) {
382 lookup.set(x);
383 }
384 lookup.set(0);
385 std::vector<uint8_t> row_space(row_vec.begin(), row_vec.end());
386 for (size_t i = 0; i < row_space.size(); ++i) {
387 for (uint8_t row : row_vec) {
388 uint8_t x = row_space[i] | row;
389 if (!lookup[x]) {
390 row_space.push_back(x);
391 lookup.set(x);
392 }
393 }
394 }
395 return lookup;
396}
397
398inline bool BMat8::row_space_included_ref(BMat8 other) const noexcept {
399 std::bitset<256> thisspace = row_space_bitset_ref();
400 std::bitset<256> otherspace = other.row_space_bitset_ref();
401 return (thisspace | otherspace) == otherspace;
402}
403
404inline uint64_t BMat8::row_space_size_ref() const {
405 return row_space_bitset_ref().count();
406}
407
408inline std::vector<uint8_t> BMat8::rows() const {
409 std::vector<uint8_t> rows;
410 for (size_t i = 0; i < 8; ++i) {
411 uint8_t row = static_cast<uint8_t>(_data << (8 * i) >> 56);
412 rows.push_back(row);
413 }
414 return rows;
415}
416
417inline size_t BMat8::nr_rows() const noexcept {
418 epu8 x = simde_mm_set_epi64x(_data, 0);
419 return __builtin_popcountll(simde_mm_movemask_epi8(x != epu8{}));
420}
421
422static constexpr epu8 rev8{7, 6, 5, 4, 3, 2, 1, 0,
423 8, 9, 10, 11, 12, 13, 14, 15};
424
425inline BMat8 BMat8::row_permuted(Perm16 p) const noexcept {
426 epu8 x = simde_mm_set_epi64x(0, _data);
427 x = permuted(x, rev8);
428 x = permuted(x, p);
429 x = permuted(x, rev8);
430 return BMat8(simde_mm_extract_epi64(x, 0));
431}
432
433inline BMat8 BMat8::col_permuted(Perm16 p) const noexcept {
434 return transpose().row_permuted(p).transpose();
435}
436
438 return one().row_permuted(p);
439}
440
442 return one().row_permuted(p).transpose();
443}
444
447 std::vector<uint8_t> rows = this->rows();
448 BMat8 product = *this * bm;
449 std::vector<uint8_t> prod_rows = product.rows();
450
451 HPCOMBI_ASSERT(product.row_space_basis() == bm);
452
453 std::vector<uint8_t> perm(8);
454 for (size_t i = 0; i < nr_rows(); ++i) {
455 uint8_t row = rows[i];
456 perm[i] =
457 std::distance(prod_rows.begin(),
458 std::find(prod_rows.begin(), prod_rows.end(), row));
459 }
460
461#ifndef __clang__
462#pragma GCC diagnostic push
463#pragma GCC diagnostic ignored "-Wstringop-overflow"
464#endif
465 std::iota(perm.begin() + nr_rows(), perm.end(), nr_rows());
466#ifndef __clang__
467#pragma GCC diagnostic pop
468#endif
469
471 for (size_t i = 0; i < 8; i++)
472 res[i] = perm[i];
473 return res;
474}
475
476inline Perm16 BMat8::right_perm_action_on_basis(BMat8 other) const noexcept {
477 epu8 x = permuted(simde_mm_set_epi64x(_data, 0), Epu8.rev());
478 epu8 y = permuted(simde_mm_set_epi64x((*this * other)._data, 0),
479 Epu8.rev());
480 // Vector ternary operator is not supported by clang.
481 // return (x != (epu8 {})) ? permutation_of(y, x) : Epu8.id();
482 return simde_mm_blendv_epi8(Epu8.id(), permutation_of(y, x), x != epu8{});
483}
484
485// Not noexcept because std::ostream::operator<< isn't
486inline std::ostream &BMat8::write(std::ostream &os) const {
487 uint64_t x = _data;
488 uint64_t pow = 1;
489 pow = pow << 63;
490 for (size_t i = 0; i < 8; ++i) {
491 for (size_t j = 0; j < 8; ++j) {
492 if (pow & x) {
493 os << "1";
494 } else {
495 os << "0";
496 }
497 x = x << 1;
498 }
499 os << "\n";
500 }
501 return os;
502}
503
504} // namespace HPCombi
505
506namespace std {
507
508// Not noexcept because BMat8::write isn't
509inline std::ostream &operator<<(std::ostream &os, HPCombi::BMat8 const &bm) {
510 return bm.write(os);
511}
512
513} // namespace std
#define FF
Definition bmat8_impl.hpp:247
Boolean matrices of dimension up to 8×8, stored as a single uint64; isomorph to binary relations with...
Definition bmat8.hpp:55
uint64_t row_space_size_incl() const noexcept
Returns the cardinality of the row space of this.
Definition bmat8_impl.hpp:317
BMat8 row_space_basis() const noexcept
Returns a canonical basis of the row space of this.
Definition bmat8_impl.hpp:239
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:362
static void transpose2(BMat8 &, BMat8 &) noexcept
Transpose two matrices at once.
Definition bmat8_impl.hpp:190
uint64_t row_space_size_bitset() const noexcept
Returns the cardinality of the row space of this.
Definition bmat8_impl.hpp:292
static BMat8 row_permutation_matrix(Perm16 p) noexcept
Returns the matrix associated to the permutation p by rows.
Definition bmat8_impl.hpp:437
BMat8 mult_transpose(BMat8 const &that) const noexcept
Returns the matrix product of this and the transpose of that.
Definition bmat8_impl.hpp:210
BMat8 transpose_maskd() const noexcept
Returns the transpose of this.
Definition bmat8_impl.hpp:176
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:333
BMat8 transpose() const noexcept
Returns the transpose of this.
Definition bmat8_impl.hpp:153
static BMat8 col_permutation_matrix(Perm16 p) noexcept
Returns the matrix associated to the permutation p by columns.
Definition bmat8_impl.hpp:441
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:352
BMat8 row_permuted(Perm16 p) const noexcept
Returns the matrix whose rows have been permuted according to p.
Definition bmat8_impl.hpp:425
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:341
std::ostream & write(std::ostream &os) const
Write this on os.
Definition bmat8_impl.hpp:486
void row_space_bitset(epu8 &res1, epu8 &res2) const noexcept
Returns the the row space of this as 256 bits.
Definition bmat8_impl.hpp:277
Perm16 right_perm_action_on_basis(BMat8) const noexcept
Give the permutation whose right multiplication change *this to other.
Definition bmat8_impl.hpp:476
std::bitset< 256 > row_space_bitset_ref() const
Returns the the row space of this.
Definition bmat8_impl.hpp:376
BMat8 col_permuted(Perm16 p) const noexcept
Returns the matrix whose columns have been permuted according to p.
Definition bmat8_impl.hpp:433
uint64_t row_space_size_ref() const
Returns the cardinality of the row space of this.
Definition bmat8_impl.hpp:404
BMat8 transpose_mask() const noexcept
Returns the transpose of this.
Definition bmat8_impl.hpp:164
std::vector< uint8_t > rows() const
Returns a std::vector for rows of this.
Definition bmat8_impl.hpp:408
size_t nr_rows() const noexcept
Returns the number of non-zero rows of this.
Definition bmat8_impl.hpp:417
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:135
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:301
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:398
Perm16 right_perm_action_on_basis_ref(BMat8) const
Give the permutation whose right multiplication change *this to other.
Definition bmat8_impl.hpp:445
#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
void row_space_update_bitset(epu8 block, epu8 &set0, epu8 &set1) noexcept
Definition bmat8_impl.hpp:262
Definition bmat8.hpp:42
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:188
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:249
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 bmat8.hpp:367
std::ostream & operator<<(std::ostream &os, HPCombi::BMat8 const &bm)
Definition bmat8_impl.hpp:509
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