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
42# ifndef POLLARD_RHO_H
43# define POLLARD_RHO_H
44
45# include <cstdint>
46# include <numeric>
47# include <random>
48
49# include <ah-errors.H>
50# include <tpl_array.H>
51# include <ahSort.H>
52# include <primality.H>
53# include <modular_arithmetic.H>
54
55namespace Aleph
56{
57
58namespace detail
59{
60
69 const uint64_t c)
70{
71 uint64_t x = seed, y = seed, d = 1;
72 auto f = [&](const uint64_t val) {
73 const uint64_t v2 = mod_mul(val, val, n);
74# if defined(__SIZEOF_INT128__)
75 return static_cast<uint64_t>((static_cast<__uint128_t>(v2) + c) % n);
76# else
77 // Safe modular addition
78 uint64_t c_mod = c % n;
79 if (n - v2 <= c_mod) return c_mod - (n - v2);
80 return v2 + c_mod;
81# endif
82 };
83
84 // Limit iterations to prevent infinite loops on degenerate cases.
85 // Pollard's rho is expected to find a factor in O(n^1/4) iterations.
86 // For 64-bit integers, 1,000,000 iterations is a very safe upper bound.
87 constexpr size_t max_iterations = 1000000;
88 for (size_t iter = 0; iter < max_iterations and d == 1; ++iter)
89 {
90 x = f(x);
91 y = f(f(y));
92 const uint64_t diff = x > y ? x - y : y - x;
93 d = std::gcd(diff, n);
94 }
95
96 if (d == 1 or d == n)
97 return n; // Failure for this seed/c combination or iteration limit reached
98
99 return d;
100}
101
113{
114 if (n % 2 == 0) return 2;
115 if (n % 3 == 0) return 3;
116 if (n % 5 == 0) return 5;
117
118 // Use a thread_local engine to avoid expensive re-construction and re-seeding.
119 thread_local std::mt19937_64 rng([]() {
120 std::random_device rd;
121 return rd();
122 }());
123
124 constexpr size_t max_attempts = 256;
125 for (size_t attempt = 0; attempt < max_attempts; ++attempt)
126 {
127 const uint64_t seed = rng() % (n - 2) + 2;
128 const uint64_t c = rng() % (n - 1) + 1;
129 if (const uint64_t d = pollard_rho_step(n, seed, c); d != n)
130 return d;
131 }
132
134 << "pollard_rho: failed to find a factor of " << n
135 << " after " << max_attempts << " attempts";
136
137# if defined(__GNUC__) || defined(__clang__)
139# elif defined(_MSC_VER)
140 __assume(0);
141# endif
142}
143
147{
148 if (n <= 1)
149 return;
150 if (miller_rabin(n))
151 {
152 factors.append(n);
153 return;
154 }
155
156 const uint64_t factor = find_any_factor(n);
158 extract_prime_factors(n / factor, factors);
159}
160
161} // namespace detail
162
184{
185 ah_invalid_argument_if(n < 2) << "pollard_rho: n must be >= 2";
189 return factors;
190}
191
192} // namespace Aleph
193
194# 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:282
#define ah_invalid_argument_if(C)
Throws std::invalid_argument if condition holds.
Definition ah-errors.H:639
High-level sorting functions for Aleph containers.
Simple dynamic array with automatic resizing and functional operations.
Definition tpl_array.H:139
static mt19937 rng
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:68
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
and
Check uniqueness with explicit hash + equality functors.
Array< uint64_t > pollard_rho(uint64_t n)
Compute the prime factorization of a number using Pollard's rho.
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
DynArray< T > & in_place_sort(DynArray< T > &c, Cmp cmp=Cmp())
Sorts a DynArray in place.
Definition ahSort.H:321
bool miller_rabin(uint64_t n) noexcept
Miller-Rabin primality test for 64-bit integers.
Definition primality.H:87
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:48
Dynamic array container with automatic resizing.