Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
pollard_rho.H
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29*/
30
43# ifndef POLLARD_RHO_H
44# define POLLARD_RHO_H
45
46# include <cstdint>
47# include <numeric>
48# include <random>
49
50# include <ah-errors.H>
51# include <tpl_array.H>
52# include <ahSort.H>
53# include <primality.H>
54# include <modular_arithmetic.H>
55
56namespace Aleph
57{
58
59namespace detail
60{
61
70 const uint64_t c)
71{
72 uint64_t x = seed, y = seed, d = 1;
73 auto f = [&](const uint64_t val) {
74 const uint64_t v2 = mod_mul(val, val, n);
75# if defined(__SIZEOF_INT128__) && !defined(_WIN32)
76 return static_cast<uint64_t>((static_cast<__uint128_t>(v2) + c) % n);
77# else
78 // Safe modular addition
79 uint64_t c_mod = c % n;
80 if (n - v2 <= c_mod) return c_mod - (n - v2);
81 return v2 + c_mod;
82# endif
83 };
84
85 // Limit iterations to prevent infinite loops on degenerate cases.
86 // Pollard's rho is expected to find a factor in O(n^1/4) iterations.
87 // For 64-bit integers, 1,000,000 iterations is a very safe upper bound.
88 constexpr size_t max_iterations = 1000000;
89 for (size_t iter = 0; iter < max_iterations and d == 1; ++iter)
90 {
91 x = f(x);
92 y = f(f(y));
93 const uint64_t diff = x > y ? x - y : y - x;
94 d = std::gcd(diff, n);
95 }
96
97 if (d == 1 or d == n)
98 return n; // Failure for this seed/c combination or iteration limit reached
99
100 return d;
101}
102
114{
115 if (n % 2 == 0) return 2;
116 if (n % 3 == 0) return 3;
117 if (n % 5 == 0) return 5;
118
119 // Use a thread_local engine to avoid expensive re-construction and re-seeding.
120 thread_local std::mt19937_64 rng([]() {
121 std::random_device rd;
122 return rd();
123 }());
124
125 constexpr size_t max_attempts = 256;
126 for (size_t attempt = 0; attempt < max_attempts; ++attempt)
127 {
128 const uint64_t seed = rng() % (n - 2) + 2;
129 const uint64_t c = rng() % (n - 1) + 1;
130 if (const uint64_t d = pollard_rho_step(n, seed, c); d != n)
131 return d;
132 }
133
135 << "pollard_rho: failed to find a factor of " << n
136 << " after " << max_attempts << " attempts";
137
138# if defined(__GNUC__) || defined(__clang__)
140# elif defined(_MSC_VER)
141 __assume(0);
142# endif
143}
144
148{
149 if (n <= 1)
150 return;
151 if (miller_rabin(n))
152 {
153 factors.append(n);
154 return;
155 }
156
157 const uint64_t factor = find_any_factor(n);
159 extract_prime_factors(n / factor, factors);
160}
161
162} // namespace detail
163
185{
186 ah_invalid_argument_if(n < 2) << "pollard_rho: n must be >= 2";
190 return factors;
191}
192
193} // namespace Aleph
194
195# endif // POLLARD_RHO_H
Exception handling system with formatted messages for Aleph-w.
#define ah_runtime_error()
Throws std::runtime_error unconditionally.
Definition ah-errors.H:287
#define ah_invalid_argument_if(C)
Throws std::invalid_argument if condition holds.
Definition ah-errors.H:644
High-level sorting functions for Aleph containers.
Simple dynamic array with automatic resizing and functional operations.
Definition tpl_array.H:138
static mt19937 rng
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
Safe modular arithmetic, extended Euclidean algorithm, and Chinese Remainder Theorem.
static mpfr_t y
Definition mpfr_mul_d.c:3
uint64_t pollard_rho_step(const uint64_t n, const uint64_t seed, const uint64_t c)
Inner function for Pollard's rho algorithm.
Definition pollard_rho.H:69
void extract_prime_factors(const uint64_t n, Array< uint64_t > &factors)
Recursive extraction of all prime factors.
uint64_t find_any_factor(const uint64_t n)
Helper to repeatedly apply Pollard's rho until a factor is found.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
Array< uint64_t > pollard_rho(uint64_t n)
Compute the prime factorization of a number using Pollard's rho.
and
Check uniqueness with explicit hash + equality functors.
DynArray< T > & in_place_sort(DynArray< T > &c, Cmp cmp=Cmp())
Sorts a DynArray in place.
Definition ahSort.H:328
bool miller_rabin(uint64_t n) noexcept
Miller-Rabin primality test for 64-bit integers.
Definition primality.H:88
bool diff(const C1 &c1, const C2 &c2, Eq e=Eq())
Check if two containers differ.
uint64_t mod_mul(uint64_t a, uint64_t b, uint64_t m)
Safe 64-bit modular multiplication.
Advanced primality testing algorithms.
ValueArg< size_t > seed
Definition testHash.C:53
Dynamic array container with automatic resizing.