32 #include <type_traits>
42 template <
typename T,
typename = std::enable_if_t<std::is_
unsigned_v<T>>>
49 std::array<T, 8> roots = {1, 3, 5, 7, 0, 0, 0, 0};
50 std::array<T, 8> new_roots = {0};
51 for (std::size_t j = 4; j < k + 1; ++j) {
52 for (std::size_t l = 0; l < 4; ++l) {
54 T i = ((r * r - a) >> (j - 1)) & 1;
55 T nr = (r + (i << (j - 2))) & ((T(1) << j) - 1);
57 new_roots[l + 4] = (T(1) << j) - nr;
60 for (std::size_t l = 0; l < 8; ++l) {
62 for (
size_t m = 0; m < 8; ++m) {
66 }
else if (roots[m] == nr) {
74 for (std::size_t l = 1; l < 4; ++l) {
75 if (roots[l] < minimum) minimum = roots[l];
81 template <
typename T,
typename = std::enable_if_t<std::is_
unsigned_v<T>>>
84 const T mask = (T(1) << k) - 1;
89 for (std::size_t i = 0; i < k; ++i) {
115 template <
typename T>
118 template <
typename T>
120 return sizeof(T) * 8;
123 template <
typename T,
typename U = get_expanded_type_t<T>,
124 typename = std::enable_if_t<std::is_same_v<U, get_expanded_type_t<T>>>>
126 return (U(1) << (GetBitSize<T>() + 2)) - 1;
129 template <
typename T,
typename U = get_expanded_type_t<T>,
130 typename = std::enable_if_t<std::is_same_v<U, get_expanded_type_t<T>>>>
134 constexpr U mod_mask = GetModMask<T>();
137 auto wb1 = RandomVector<U>(number_of_sbs);
142 std::transform(wb1.cbegin(), wb1.cend(), wb1.begin(),
143 [mod_mask](
auto u_i) { return (2 * u_i + 1) & mod_mask; });
145 std::transform(wb1.cbegin(), wb1.cend(), wb1.begin(),
146 [mod_mask](
auto u_i) { return (2 * u_i) & mod_mask; });
153 wb2.reserve(number_of_sbs);
154 std::transform(wb1.cbegin(), wb1.cend(), sps.
a.cbegin(), std::back_inserter(wb2),
155 [mod_mask](
auto a_i,
auto sp_a_i) { return (a_i - sp_a_i) & mod_mask; });
162 template <
typename T,
typename U = get_expanded_type_t<T>,
163 typename = std::enable_if_t<std::is_same_v<U, get_expanded_type_t<T>>>>
169 constexpr U mod_mask = GetModMask<T>();
174 std::transform(wb1.cbegin(), wb1.cend(), wb2.cbegin(), wb2.begin(),
175 [](
auto a,
auto d) { return 2 * d * a - d * d; });
177 std::transform(wb1.cbegin(), wb1.cend(), wb2.cbegin(), wb2.begin(),
178 [](
auto a,
auto d) { return 2 * d * a; });
180 std::transform(wb2.cbegin(), wb2.cend(), sps.
c.cbegin(), wb2.begin(),
181 [mod_mask](
auto t,
auto c) { return (c + t) & mod_mask; });
185 template <
typename T,
typename U = get_expanded_type_t<T>,
186 typename = std::enable_if_t<std::is_same_v<U, get_expanded_type_t<T>>>>
193 constexpr U mod_mask = GetModMask<T>();
194 constexpr U mod_mask_1 = mod_mask >> 1;
195 auto number_of_sbs = wb1.size();
198 std::transform(wb2.cbegin(), wb2.cend(), wb2.begin(),
199 [mod_mask](
auto asq) { return sqrt(GetBitSize<T>() + 2, U(asq & mod_mask)); });
204 std::transform(wb1.cbegin(), wb1.cend(), wb2.cbegin(), wb1.begin(), [](U a_i, U c) {
205 return (invert<U>(GetBitSize<T>() + 1, U(c & mod_mask_1)) * a_i + 1) & mod_mask_1;
208 std::transform(wb1.cbegin(), wb1.cend(), wb2.cbegin(), wb1.begin(), [](
auto a_i,
auto c) {
209 return (invert<U>(GetBitSize<T>() + 1, U(c & mod_mask_1)) * a_i) & mod_mask_1;
215 sbs.reserve(number_of_sbs);
216 std::transform(wb1.cbegin(), wb1.cend(), std::back_inserter(sbs),
217 [](
auto& d_i) { return static_cast<T>(d_i >> 1); });