2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
98
99
100
101
102
104#define CECCO_ERASURE_SUPPORT
108
109
110
111
112
114#define CECCO_USE_LUTS_FOR_FP
118
119
120
121
122
123
124
125#define CECCO_COMPRESS_LUTS_FROM_Q 256
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
161template <ComponentType T>
163template <ComponentType T>
165template <ComponentType T>
167template <FiniteFieldType MAIN, FiniteFieldType... OTHERS>
175
176
177
178
179
180
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
226 constexpr bool operator!=(
const T& rhs)
const {
return !(
static_cast<
const T&>(*
this) == rhs); }
233 constexpr T
operator+()
const& {
return static_cast<
const T&>(*
this); }
235 constexpr T&&
operator+() &&
noexcept {
return static_cast<T&&>(*
this); }
278#ifdef CECCO_ERASURE_SUPPORT
293
294
295
296
297
298
299
300
301
302
303
304
306template <FieldType T>
313template <FieldType T>
315 T res(
std::move(lhs));
320template <FieldType T>
322 T res(
std::move(rhs));
327template <FieldType T>
329 T res(
std::move(lhs));
334template <FieldType T>
341template <FieldType T>
343 T res(
std::move(lhs));
348template <FieldType T>
350 T res(-
std::move(rhs));
355template <FieldType T>
357 T res(
std::move(lhs));
362template <FieldType T>
369template <FieldType T>
371 T res(
std::move(lhs));
376template <FieldType T>
378 T res(
std::move(rhs));
383template <FieldType T>
385 T res(
std::move(lhs));
390template <FieldType T>
397template <FieldType T>
404template <FieldType T>
406 T res(
std::move(lhs));
411template <FieldType T>
413 T res(
std::move(rhs));
418template <FieldType T>
425template <FieldType T>
427 T res(
std::move(lhs));
432template <FieldType T>
434 return sqm<T>(base, exponent);
437template <FieldType T>
439 return sqm<T>(
std::move(base), exponent);
444#ifdef CECCO_ERASURE_SUPPORT
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470template <SignedIntType T = InfInt>
474
475
476
477
478
479
493#ifdef CECCO_ERASURE_SUPPORT
494 if (is_erased() != rhs.is_erased())
return false;
496 return numerator * rhs.get_denominator() == rhs.get_numerator() * denominator;
519
520
521
522
523
531 static const std::string info =
"rational number";
540 return (numerator >= 0 && denominator > 0) || (numerator <= 0 && denominator < 0);
544 constexpr bool is_zero()
const noexcept {
return numerator == 0; }
546#ifdef CECCO_ERASURE_SUPPORT
548
549
550
551
552
570 constexpr void simplify();
575template <SignedIntType T>
577 if (d == 0)
throw std::invalid_argument(
"denominator must not be zero");
581template <SignedIntType T>
588template <SignedIntType T>
590#ifdef CECCO_ERASURE_SUPPORT
591 if (
this->is_erased())
return Rationals().erase();
594 res.numerator = -res.numerator;
598template <SignedIntType T>
600#ifdef CECCO_ERASURE_SUPPORT
601 if (
this->is_erased())
return this->erase();
603 numerator = -numerator;
607template <SignedIntType T>
609#ifdef CECCO_ERASURE_SUPPORT
610 if (
this->is_erased() || rhs.is_erased())
return this->erase();
612 auto tn = numerator * rhs.get_denominator() + denominator * rhs.get_numerator();
613 auto td = denominator * rhs.get_denominator();
620template <SignedIntType T>
622#ifdef CECCO_ERASURE_SUPPORT
623 if (
this->is_erased() || rhs.is_erased())
return this->erase();
625 auto tn = numerator * rhs.get_denominator() - denominator * rhs.get_numerator();
626 auto td = denominator * rhs.get_denominator();
633template <SignedIntType T>
635#ifdef CECCO_ERASURE_SUPPORT
636 if (
this->is_erased() || rhs.is_erased())
return this->erase();
638 auto tn = numerator * rhs.get_numerator();
639 auto td = denominator * rhs.get_denominator();
646template <SignedIntType T>
648#ifdef CECCO_ERASURE_SUPPORT
649 if (
this->is_erased() || rhs.is_erased())
return this->erase();
651 if (rhs.numerator == 0)
throw std::invalid_argument(
"division by zero");
652 auto tn = numerator * rhs.get_denominator();
653 auto td = denominator * rhs.get_numerator();
660template <SignedIntType T>
662#ifdef CECCO_ERASURE_SUPPORT
665 thread_local std::uniform_int_distribution<
int> dist(-100, 100);
666 numerator = dist(gen());
668 denominator = dist(gen());
669 }
while (denominator == 0);
674template <SignedIntType T>
676#ifdef CECCO_ERASURE_SUPPORT
679 thread_local std::uniform_int_distribution<
int> dist(-100, 100);
687 }
while (T(n) * denominator == numerator * T(d));
694template <SignedIntType T>
697 throw std::invalid_argument(
698 "trying to calculate multiplicative order "
699 "of additive neutral element");
700 if (numerator == denominator)
702 else if (numerator == -denominator)
707template <SignedIntType T>
709 if (numerator == 0) {
715#ifdef CECCO_ERASURE_SUPPORT
732template <SignedIntType T>
734 if (numerator == 0) {
739 auto d = GCD<T>(numerator, denominator);
742 if (denominator < 0) {
749
750
751
752
753template <SignedIntType T>
755#ifdef CECCO_ERASURE_SUPPORT
757 os << ERASURE_MARKER;
760 std::string temp = std::to_string(e.get_numerator());
761 if (e.get_denominator() != 1) temp +=
"/" + std::to_string(e.get_denominator());
763#ifdef CECCO_ERASURE_SUPPORT
769template <FiniteFieldType B,
MOD modulus,
LutMode mode>
779
780
781
782
783
784
785template <uint16_t q, uint8_t m, size_t SIZE>
787 static_assert(SIZE >=
static_cast<size_t>(m),
"array size must be at least the extension degree m");
788 size_t res = coeffs[0];
790 for (uint8_t i = 1; i < m; ++i) {
791 res += coeffs[i] * t;
798
799
800
801
802
803template <
typename LabelType, size_t FieldSize>
810
811
812
813
814
815
816
817
818
819template <
typename LabelType, size_t FieldSize>
822 constexpr LabelType&
operator()(size_t i, size_t j) {
823 if (i > j)
return operator()(j, i);
828 return values[FieldSize - i][j - i];
836 constexpr LabelType
operator()(size_t i, size_t j)
const noexcept {
837 if (i > j)
return operator()(j, i);
842 return values[FieldSize - i][j - i];
850 std::array < std::array<LabelType, FieldSize>,
856
857
858
859
860
861
862template <
typename LabelType, size_t ExtensionDegree, size_t FieldSize>
864 std::array<
std::array<LabelType, ExtensionDegree>, FieldSize>
values{};
871template <
typename LabelType, LabelType FieldSize>
873 Lut1D<LabelType, FieldSize> lut_mul_ord;
875 lut_mul_ord.values[0] = 0;
876 lut_mul_ord.values[1] = 1;
877 for (LabelType i = 2; i < FieldSize; ++i) {
879 for (LabelType j = 1; j < FieldSize; ++j) {
881 lut_mul_ord.values[i] = j;
884 temp = mul_lut(temp, i);
895template <
typename LabelType, LabelType FieldSize>
993 if constexpr (
p == 2)
return typename F::
label_t{1};
1051 "trying to calculate multiplicative order "
1052 "of additive neutral element");
1152 const auto S =
lhs[
m - 1 -
s];
1153 if (
S == 0)
continue;
1155 const auto T =
rhs[
m - 1 -
t];
1156 if (
T == 0)
continue;
1165 if (
flag == 0)
continue;
1188
1189
1190
1191
1192
1193
1194
1195
1200template <
typename LutType, LutType (*F)()>
1205 static constexpr LutType
lut = F();
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234template <
typename LutType,
typename ProviderLutType,
const ProviderLutType& (*P)(),
1235 LutType (*F)(
const ProviderLutType& (*)()),
LutMode mode>
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1308#ifdef CECCO_ERASURE_SUPPORT
1309 if (sub.is_erased())
return SUPERFIELD().erase();
1311 return SUPERFIELD(embedding_map[sub.get_label()]);
1315
1316
1317
1318
1319
1320
1321
1325 std::span<
const size_t> embedding_map;
1328 static std::vector<size_t> compute_embedding();
1332
1333
1347#ifdef CECCO_ERASURE_SUPPORT
1435
1436
1437
1438
1439
1440
1441
1442
1469 if (
h_A(
a) ==
A(0)) {
1479 if (
h_B(
b) ==
B(0)) {
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1570
1571
1572
1573
1578#ifdef CECCO_ERASURE_SUPPORT
1592
1593
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646template <uint16_t p>
1648 static_assert(is_prime(p),
"p is not a prime");
1659 constexpr Fp(
const Fp& other)
noexcept =
default;
1660 constexpr Fp(
Fp&& other)
noexcept =
default;
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673 template <FiniteFieldType S,
MOD ext_modulus,
LutMode mode>
1674 Fp(
const Ext<S, ext_modulus, mode>& other);
1677
1678
1679
1680
1681
1682
1683
1684 template <FiniteFieldType MAIN, FiniteFieldType... OTHERS>
1688 ~
Fp()
noexcept =
default;
1697 template <FiniteFieldType S,
MOD ext_modulus,
LutMode mode>
1701 template <FiniteFieldType MAIN, FiniteFieldType... OTHERS>
1702 requires(MAIN::get_characteristic() == p)
1705 constexpr bool operator==(
const Fp& rhs)
const noexcept {
return label == rhs.get_label(); }
1729
1730
1731
1732
1740 static const std::string info =
"prime field with " + std::to_string(p) +
" elements";
1758
1759
1760
1761
1762
1771 constexpr bool is_zero()
const noexcept {
return label == 0; }
1773#ifdef CECCO_ERASURE_SUPPORT
1775
1776
1777
1778
1779
1788
1789
1790
1791
1792
1794#ifdef CECCO_USE_LUTS_FOR_FP
1804#ifndef CECCO_USE_LUTS_FOR_FP
1806 static constexpr label_t lut_add(label_t a, label_t b)
noexcept {
1807 Fp temp_a(a), temp_b(b);
1809 return temp_a.get_label();
1813 static constexpr label_t lut_mul(label_t a, label_t b)
noexcept {
1814 Fp temp_a(a), temp_b(b);
1816 return temp_a.get_label();
1820 static constexpr label_t lut_neg(label_t a)
noexcept {
1822 temp = -
std::move(temp);
1823 return temp.get_label();
1836#ifdef CECCO_USE_LUTS_FOR_FP
1844
1845
1846
1847
1865 static_assert(
lut_add(0, 0) == 0);
1866 static_assert(
lut_neg(0) == 0);
1867 static_assert(
lut_mul(0, 1) == 0);
1878template <uint16_t p>
1880 if (l <= -(
int)p || l >= (
int)p) l %= (
int)p;
1881 if (l < 0) l += (
int)p;
1886template <FiniteFieldType S,
MOD ext_modulus,
LutMode mode>
1887Fp<p>::
Fp(
const Ext<S, ext_modulus, mode>& other) {
1889 static_assert(Fp<p>::get_characteristic() ==
Ext<S, ext_modulus, mode>::get_characteristic(),
1890 "trying to convert between fields with different characteristic");
1892#ifdef CECCO_ERASURE_SUPPORT
1893 if (other.is_erased()) {
1901 auto embedding = Embedding<Fp<p>, Ext<S, ext_modulus, mode>>();
1902 Fp<p> result = embedding.extract(other);
1903 label = result.get_label();
1907template <FiniteFieldType MAIN, FiniteFieldType... OTHERS>
1911#ifdef CECCO_ERASURE_SUPPORT
1940template <uint16_t p>
1942 if (l <= -(
int)p || l >= (
int)p) l %= (
int)p;
1943 if (l < 0) l += (
int)p;
1949template <FiniteFieldType S,
MOD ext_modulus,
LutMode mode>
1952 std::swap(*
this, temp);
1967#ifdef CECCO_ERASURE_SUPPORT
1972#ifndef CECCO_USE_LUTS_FOR_FP
1984#ifdef CECCO_ERASURE_SUPPORT
1988#ifndef CECCO_USE_LUTS_FOR_FP
1999#ifdef CECCO_ERASURE_SUPPORT
2002#ifndef CECCO_USE_LUTS_FOR_FP
2016#ifdef CECCO_ERASURE_SUPPORT
2019#ifndef CECCO_USE_LUTS_FOR_FP
2033#ifdef CECCO_ERASURE_SUPPORT
2036#ifndef CECCO_USE_LUTS_FOR_FP
2052#ifdef CECCO_ERASURE_SUPPORT
2063#ifdef CECCO_ERASURE_SUPPORT
2067#ifndef CECCO_USE_LUTS_FOR_FP
2077#ifdef CECCO_ERASURE_SUPPORT
2081#ifndef CECCO_USE_LUTS_FOR_FP
2095#ifdef CECCO_ERASURE_SUPPORT
2099#ifndef CECCO_USE_LUTS_FOR_FP
2113#ifdef CECCO_ERASURE_SUPPORT
2116 if (
label == 0)
throw std::
invalid_argument(
"trying to calculate multiplicative order of additive neutral element");
2117#ifndef CECCO_USE_LUTS_FOR_FP
2126#ifdef CECCO_ERASURE_SUPPORT
2129 if (
label == 0)
return 1;
2135 std::
cout <<
"addition table (row and column headers omitted)" <<
std::
endl;
2141#ifdef CECCO_USE_LUTS_FOR_FP
2142 std::
cout <<
"additive inverse table (row headers omitted)" <<
std::
endl;
2146 std::
cout <<
"multiplication table (row and column headers omitted)" <<
std::
endl;
2152#ifdef CECCO_USE_LUTS_FOR_FP
2153 std::
cout <<
"multiplicative inverse table (row headers omitted)" <<
std::
endl;
2158#ifdef CECCO_ERASURE_SUPPORT
2175#ifdef CECCO_ERASURE_SUPPORT
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2222 static_assert(
modulus.
back() == 1,
"provided polynomial is not monic");
2223 static_assert(
modulus.
size() > 2,
"provided polynomial has degree less than 2");
2224 static_assert(
B::
ready(),
"base field must be fully instantiated");
2226 "CompileTime extension fields require all base fields to have constexpr-ready interfaces");
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2266
2267
2268
2269
2270
2271
2272
2273
2278
2279
2280
2281
2282
2283
2284
2289
2290
2291
2292
2293
2343
2344
2345
2346
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2379
2380
2381
2382
2383
2390
2391
2392
2393
2413#ifdef CECCO_ERASURE_SUPPORT
2415
2416
2417
2418
2419
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2445
2446
2447
2448
2449
2450
2451
2452
2453
2473
2474
2475
2476
2555 static_assert(
B::
ready());
2560 static_assert(
lut_add()(0, 0) == 0);
2561 static_assert(
lut_neg()(0) == 0);
2562 static_assert(
lut_mul()(0, 1) == 0);
2564 static_assert(
g().
value != 1);
2583#ifdef CECCO_ERASURE_SUPPORT
2601#ifdef CECCO_ERASURE_SUPPORT
2621 "trying to convert between fields with different characteristic");
2623#ifdef CECCO_ERASURE_SUPPORT
2667 "trying to construct extension field element using base field vector of wrong length");
2669#ifdef CECCO_ERASURE_SUPPORT
2685 "extension field elements can only be constructed from vectors over subfields");
2689 "trying to construct extension field element using subfield vector of wrong length");
2691#ifdef CECCO_ERASURE_SUPPORT
2720 "trying to convert between fields with different characteristic");
2722#ifdef CECCO_ERASURE_SUPPORT
2797 "Prime field characteristic must match extension field characteristic");
2799#ifdef CECCO_ERASURE_SUPPORT
2848#ifdef CECCO_ERASURE_SUPPORT
2858#ifdef CECCO_ERASURE_SUPPORT
2867#ifdef CECCO_ERASURE_SUPPORT
2876#ifdef CECCO_ERASURE_SUPPORT
2885#ifdef CECCO_ERASURE_SUPPORT
2894#ifdef CECCO_ERASURE_SUPPORT
2905#ifdef CECCO_ERASURE_SUPPORT
2915#ifdef CECCO_ERASURE_SUPPORT
2925#ifdef CECCO_ERASURE_SUPPORT
2935#ifdef CECCO_ERASURE_SUPPORT
2938 if (
label == 0)
throw std::
invalid_argument(
"trying to calculate multiplicative order of additive neutral element");
2944#ifdef CECCO_ERASURE_SUPPORT
2947 if (
label == 0)
return 1;
2956#ifdef CECCO_ERASURE_SUPPORT
2964 if (
i > 0 &&
beta == *
this)
break;
2976 " extension of (" +
B::
get_info() +
"), irreducible polynomial ";
3009#ifdef CECCO_ERASURE_SUPPORT
3022 "extension field elements can only be converted into vectors over subfields");
3038 std::
cout <<
"addition table (row and column headers omitted)" <<
std::
endl;
3044 std::
cout <<
"additive inverse table (row headers omitted)" <<
std::
endl;
3047 std::
cout <<
"multiplication table (row and column headers omitted)" <<
std::
endl;
3053 std::
cout <<
"multiplicative inverse table (row headers omitted)" <<
std::
endl;
3056 std::
cout <<
"multiplicative order table (row headers omitted)" <<
std::
endl;
3059 std::
cout <<
"element coefficients table (column headers omitted)" <<
std::
endl;
3073#ifdef CECCO_ERASURE_SUPPORT
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3119 static_assert(
sizeof...(
OTHERS) > 0,
"Iso requires at least two field representations");
3122 "All field representations in Iso must be pairwise distinct");
3155
3156
3157
3158
3159
3160
3161
3162
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3181
3182
3183
3184
3185
3186
3193
3194
3195
3196
3197
3198
3199
3200
3201
3211 template <
typename OTHER>
3218 template <
typename OTHER>
3225 template <
typename OTHER>
3235 template <
typename OTHER>
3240
3241
3242
3243
3244 template <
typename TO>
3245 constexpr TO as()
const
3271#ifdef CECCO_ERASURE_SUPPORT
3273
3274
3275
3276
3277
3294 template <
typename OTHER>
3372
3373
3374
3375
3403template <
typename OTHER>
3413template <uint16_t p>
3445 "trying to convert between fields with different characteristic");
3447#ifdef CECCO_ERASURE_SUPPORT
3518 static_assert(
MAIN::
get_characteristic() ==
p,
"Prime field characteristic must match Iso field characteristic");
3520#ifdef CECCO_ERASURE_SUPPORT
3552 "trying to convert between fields with different characteristic");
3554#ifdef CECCO_ERASURE_SUPPORT
3729template <
typename OTHER>
3744template <
typename OTHER>
3759template <
typename OTHER>
3780template <
typename OTHER>
3789template <
typename TO>
3793#ifdef CECCO_ERASURE_SUPPORT
3804 ss <<
"stack of isomorphic fields, main field: ";
3841#ifdef CECCO_ERASURE_SUPPORT
Functor representing the field embedding Ο: SUBFIELD β SUPERFIELD, with reverse lookup.
constexpr SUPERFIELD operator()(const SUBFIELD &sub) const
Apply Ο: SUBFIELD β SUPERFIELD.
Embedding()
Constructs the embedding (cached on first instantiation per template arguments).
constexpr SUBFIELD extract(const SUPERFIELD &super) const
Reverse Ο: find the unique s β SUBFIELD with Ο(s) == super.
Extension field π½_{q^m} β
B[x]/(f(x)), constructed from a base field and an irreducible monic modulus...
Prime field π½_p β
β€/pβ€
constexpr Fp() noexcept
Default constructor: 0.
Fp & randomize_force_change()
Like randomize but guaranteed to differ from the current value.
constexpr Fp(const Fp &other) noexcept=default
static std::string get_info()
Human-readable description: "prime field with p elements".
static constexpr size_t get_characteristic() noexcept
size_t get_additive_order() const
Additive order: 1 for zero, p otherwise.
constexpr Fp(int l)
Construct from int, reducing modulo p (handles negative values).
Fp & operator=(const Ext< S, ext_modulus, mode > &other)
Project an extension-field element to π½_p (copy-and-swap; same semantics as the constructor).
constexpr Fp operator-() const &noexcept
Additive inverse (lvalue): returns a new element with -label mod p.
constexpr Fp & operator-() &&noexcept
Additive inverse (rvalue): in place.
static constexpr size_t get_q() noexcept
constexpr Fp & operator=(Fp &&rhs) noexcept=default
static void show_tables()
Print all lookup tables to std::cout (debugging aid).
Fp & randomize()
Uniform random element in {0, β¦, p β 1}.
static constexpr size_t get_size() noexcept
constexpr Fp & operator+=(const Fp &rhs) noexcept
*this = (label + rhs.label) mod p
constexpr bool operator==(const Fp &rhs) const noexcept
constexpr bool is_zero() const noexcept
True iff this is the additive identity.
static constexpr Fp get_generator() noexcept
Generator (primitive root) of π½_p*; precomputed label is Gen.
constexpr Fp & operator=(const Fp &rhs) noexcept=default
static constexpr size_t get_m() noexcept
size_t get_multiplicative_order() const
Multiplicative order in π½_p*.
static constexpr label_t Gen
Primitive element (generator) of F_p*.
Fp(const Iso< MAIN, OTHERS... > &other)
Extract a prime-field element from an Iso containing this prime subfield.
Fp & operator/=(const Fp &rhs)
*this = (label Β· rhs.labelβ»ΒΉ) mod p; throws std::invalid_argument if rhs is zero
static constexpr bool is_constexpr_ready() noexcept
Always true for prime fields.
constexpr Fp & operator*=(const Fp &rhs) noexcept
*this = (label Β· rhs.label) mod p
Fp(const Ext< S, ext_modulus, mode > &other)
Extract a prime-field element from an extension field (downcast).
constexpr bool has_positive_sign() const noexcept
Always true (finite fields are unordered).
constexpr Fp & operator=(int l) noexcept
Assign int, reducing modulo p.
constexpr Fp & operator*=(int s) noexcept
*this = (label Β· s) mod p (repeated addition)
constexpr Fp & operator-=(const Fp &rhs) noexcept
*this = (label β rhs.label) mod p
static constexpr size_t get_p() noexcept
constexpr Fp(Fp &&other) noexcept=default
static constexpr bool ready()
Compile-time signal that all LUTs are constructed.
constexpr size_t get_label() const noexcept
Underlying integer label in {0, β¦, p β 1}.
Single logical field unifying several pairwise-isomorphic representations.
Dense m Γ n matrix over a CECCO::ComponentType.
Univariate polynomial p(x) = aβ + aβx + β¦ + aβxβΏ over a CECCO::ComponentType.
Field of rational numbers β = { p/q : p, q β β€, q β 0 } with selectable precision.
static constexpr size_t get_characteristic() noexcept
Characteristic of β: 0.
constexpr bool operator==(const Rationals< T > &rhs) const
Cross-multiplication equality.
constexpr bool has_positive_sign() const noexcept
Sign predicate (true iff numerator and denominator share their sign).
constexpr Rationals & operator=(int l)
Assign the integer l as l / 1.
static const std::string get_info()
Human-readable description: "rational number".
Rationals(int n=0, int d=1)
Construct n / d, simplified to lowest terms with positive denominator.
constexpr Rationals & operator*=(const Rationals &rhs)
*this *= rhs, result kept in lowest terms
Rationals & randomize_force_change()
Like randomize but guaranteed to differ from the current value.
size_t get_multiplicative_order() const
Multiplicative order.
constexpr Rationals operator-() const &
Additive inverse (lvalue overload returns a copy with negated numerator).
constexpr Rationals & operator-=(const Rationals &rhs)
*this -= rhs, result kept in lowest terms
Rationals & randomize()
Random rational (bounded numerator and denominator), simplified.
Rationals(Rationals &&other)=default
constexpr const T & get_denominator() const noexcept
Denominator (always positive after simplification).
Rationals & operator/=(const Rationals &rhs)
*this /= rhs; throws std::invalid_argument if rhs is zero
constexpr const T & get_numerator() const noexcept
Numerator (sign carrier).
Rationals & operator=(Rationals &&rhs)=default
Rationals(const Rationals &other)=default
constexpr Rationals & operator-() &&
Additive inverse (rvalue overload negates in place).
constexpr Rationals & operator=(const Rationals &rhs)=default
constexpr Rationals & operator+=(const Rationals &rhs)
*this += rhs, result kept in lowest terms
constexpr bool is_zero() const noexcept
True iff numerator is zero.
size_t get_additive_order() const noexcept
Additive order: 1 for zero, 0 (infinite) otherwise (characteristic 0).
Vector v = (vβ, vβ, β¦, vβββ) over a CECCO::ComponentType.
Tag base for the CRTP-protection idiom.
CRTP base documenting the interface every field type must provide.
T & operator=(T &&rhs) noexcept=delete
Move assignment β derived must implement.
T & operator+=(const T &rhs) noexcept=delete
*this += rhs β derived must implement
T & operator-=(const T &rhs) noexcept=delete
*this -= rhs β derived must implement
T & operator*=(const T &rhs) noexcept=delete
*this *= rhs β derived must implement
bool is_zero() const noexcept=delete
True if *this is the additive identity.
T & operator/=(const T &rhs)=delete
*this /= rhs; throws std::invalid_argument if rhs is zero β derived must implement
size_t get_multiplicative_order() const =delete
Smallest k > 0 with this^k == 1; throws std::invalid_argument if *this is zero.
Field & randomize_force_change()=delete
Like randomize but guaranteed to differ from the current value β derived must implement.
~Field() noexcept=default
T & operator=(int l)=delete
Assign from int β derived must implement.
constexpr T operator+() const &
Unary + on an lvalue: returns a copy.
constexpr T && operator+() &&noexcept
Unary + on an rvalue: returns the rvalue itself.
Field & randomize()=delete
Uniform random element of the field β derived must implement; may return the same value.
size_t get_additive_order() const =delete
Smallest k > 0 with k * *this == 0; for finite fields of characteristic p this is p (or 1 for zero); ...
T & operator-() &&noexcept=delete
Additive inverse on an rvalue (in place) β derived must implement.
T & operator=(const T &rhs) noexcept=delete
Copy assignment β derived must implement.
constexpr bool operator!=(const T &rhs) const
Inequality, defined as !(*this == rhs).
T operator-() const &noexcept=delete
Additive inverse on an lvalue β derived must implement.
bool has_positive_sign() const noexcept=delete
True if the element is "positive" (always true for finite fields; sign of numerator for β).
#define MOD
Alias for std::array, used to spell modulus polynomials in CECCO::Ext.
#define CECCO_COMPRESS_LUTS_FROM_Q
Compression threshold for 2D lookup tables in extension fields.
Contains implementation details not to be exposed to the user. Functions and classes here may change ...
constexpr auto compute_multiplicative_orders(const Lut2D< LabelType, FieldSize > &mul_lut)
Build the table of multiplicative orders for all elements of π½_Q.
constexpr auto compute_multiplicative_inverses_direct()
Build multiplicative-inverse table for π½_p via extended Euclidean algorithm.
static size_t constexpr integer_from_coeffs(const std::array< size_t, SIZE > &coeffs) noexcept
Encode polynomial coefficients (low-to-high) as a base-q integer label.
constexpr double floor_constexpr(double x)
Constexpr floor function.
Provides a framework for error correcting codes.
constexpr T operator-(T &&lhs, const T &rhs)
constexpr T operator*(uint16_t lhs, const T &rhs)
constexpr T operator+(T &&lhs, const T &rhs)
constexpr T operator*(const T &lhs, T &&rhs)
constexpr T operator*(T &&lhs, T &&rhs)
T operator/(const T &lhs, const T &rhs)
constexpr T operator+(const T &lhs, T &&rhs)
constexpr T operator+(const T &lhs, const T &rhs)
constexpr T operator*(const T &lhs, const T &rhs)
constexpr T operator-(const T &lhs, const T &rhs)
constexpr T operator+(T &&lhs, T &&rhs)
constexpr T operator*(int lhs, T &&rhs)
constexpr T operator^(const T &base, int exponent)
constexpr T operator^(T &&base, int exponent)
constexpr T operator*(const T &lhs, uint16_t rhs)
constexpr T operator-(const T &lhs, T &&rhs)
T operator/(T &&lhs, const T &rhs)
constexpr T operator-(T &&lhs, T &&rhs)
LutMode
LUT generation mode for field operations.
constexpr T operator*(T &&lhs, const T &rhs)
constexpr T operator*(T &&lhs, int rhs)
1D lookup table for unary field operations (negation, inversion, order)
std::array< LabelType, FieldSize > values
constexpr LabelType operator()(size_t i) const noexcept
2D lookup table for commutative binary operations, optionally compressed
constexpr LabelType operator()(size_t i, size_t j) const noexcept
Const access (used during field operations).
constexpr LabelType & operator()(size_t i, size_t j)
Mutable access (used during table construction).
Lookup table mapping each extension-field label to its base-field coefficient vector.
std::array< std::array< LabelType, ExtensionDegree >, FieldSize > values
CompileTime specialisation: table is a constexpr static member.
static constexpr const LutType & get_lut()
static constexpr LutType lut
Holds a LUT generated by F(P); P provides a dependency table.