Function num_prime::factor::pollard_rho
source · pub fn pollard_rho<T: Integer + FromPrimitive + NumRef + Clone + for<'r> ModularCoreOps<&'r T, &'r T, Output = T> + for<'r> ModularUnaryOps<&'r T, Output = T>>(
target: &T,
start: T,
offset: T,
max_iter: usize
) -> (Option<T>, usize)
Expand description
Find factors using Pollard’s rho algorithm with Brent’s loop detection algorithm
The returned values are the factor and the count of passed iterations.
Examples found in repository?
examples/profile_factorization.rs (line 22)
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 93 94 95 96 97 98 99 100 101
fn profile_n(n: u128) -> Vec<(String, usize)> {
let k_squfof: Vec<u16> = SQUFOF_MULTIPLIERS.iter().take(10).cloned().collect();
let k_oneline: Vec<u16> = vec![1, 360, 480];
const MAXITER: usize = 1 << 20;
const POLLARD_REPEATS: usize = 2;
let mut n_stats = Vec::new();
// pollard rho
for i in 0..POLLARD_REPEATS {
n_stats.push((
format!("pollard_rho{}", i + 1),
pollard_rho(&n, random(), random(), MAXITER).1,
));
}
// squfof
for &k in &k_squfof {
let key = format!("squfof_k{}", k);
if let Some(kn) = n.checked_mul(k as u128) {
let n = squfof(&n, kn, MAXITER).1;
n_stats.push((key, n));
} else {
n_stats.push((key, MAXITER));
};
}
// one line
for &k in &k_oneline {
let key = format!("one_line_k{}", k);
if let Some(kn) = n.checked_mul(k as u128) {
let n = one_line(&n, kn, MAXITER).1;
n_stats.push((key, n));
} else {
n_stats.push((key, MAXITER));
};
}
n_stats
}
/// Collect the best case of each factorization algorithm
fn profile_n_min(n: u128) -> Vec<(String, usize)> {
let k_squfof: Vec<u16> = SQUFOF_MULTIPLIERS.iter().cloned().collect();
let k_oneline: Vec<u16> = vec![1, 360, 480];
const MAXITER: usize = 1 << 24;
const POLLARD_REPEATS: usize = 4;
let mut n_stats = Vec::new();
// pollard rho
let mut pollard_best = (MAXITER, u128::MAX);
for _ in 0..POLLARD_REPEATS {
let tstart = Instant::now();
let (result, iters) = pollard_rho(&n, random(), random(), pollard_best.0);
if result.is_some() {
pollard_best = pollard_best.min((iters, tstart.elapsed().as_micros()));
}
}
n_stats.push(("pollard_rho".to_string(), pollard_best.0));
n_stats.push(("time_pollard_rho".to_string(), pollard_best.1 as usize));
// squfof
let mut squfof_best = (MAXITER, u128::MAX);
for &k in &k_squfof {
if let Some(kn) = n.checked_mul(k as u128) {
let tstart = Instant::now();
let (result, iters) = squfof(&n, kn, squfof_best.0);
if result.is_some() {
squfof_best = squfof_best.min((iters, tstart.elapsed().as_micros()));
}
}
}
n_stats.push(("squfof".to_string(), squfof_best.0));
n_stats.push(("time_squfof".to_string(), squfof_best.1 as usize));
// one line
let mut oneline_best = (MAXITER, u128::MAX);
for &k in &k_oneline {
if let Some(kn) = n.checked_mul(k as u128) {
let tstart = Instant::now();
let (result, iters) = one_line(&n, kn, oneline_best.0);
if result.is_some() {
oneline_best = oneline_best.min((iters, tstart.elapsed().as_micros()));
}
}
}
n_stats.push(("one_line".to_string(), oneline_best.0));
n_stats.push(("time_one_line".to_string(), squfof_best.1 as usize));
n_stats
}