[MATH-964] Remove unused class PollardRho.
This commit is contained in:
parent
2ae6f996ec
commit
cb21480cb1
|
@ -1,164 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.commons.math4.primes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.math4.util.FastMath;
|
||||
|
||||
/**
|
||||
* Implementation of the Pollard's rho factorization algorithm.
|
||||
* @since 3.2
|
||||
*/
|
||||
class PollardRho {
|
||||
|
||||
/**
|
||||
* Hide utility class.
|
||||
*/
|
||||
private PollardRho() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Factorization using Pollard's rho algorithm.
|
||||
* @param n number to factors, must be > 0
|
||||
* @return the list of prime factors of n.
|
||||
*/
|
||||
public static List<Integer> primeFactors(int n) {
|
||||
final List<Integer> factors = new ArrayList<Integer>();
|
||||
|
||||
n = SmallPrimes.smallTrialDivision(n, factors);
|
||||
if (1 == n) {
|
||||
return factors;
|
||||
}
|
||||
|
||||
if (SmallPrimes.millerRabinPrimeTest(n)) {
|
||||
factors.add(n);
|
||||
return factors;
|
||||
}
|
||||
|
||||
int divisor = rhoBrent(n);
|
||||
factors.add(divisor);
|
||||
factors.add(n / divisor);
|
||||
return factors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of the Pollard's rho factorization algorithm.
|
||||
* <p>
|
||||
* This implementation follows the paper "An improved Monte Carlo factorization algorithm"
|
||||
* by Richard P. Brent. This avoids the triple computation of f(x) typically found in Pollard's
|
||||
* rho implementations. It also batches several gcd computation into 1.
|
||||
* <p>
|
||||
* The backtracking is not implemented as we deal only with semi-primes.
|
||||
*
|
||||
* @param n number to factor, must be semi-prime.
|
||||
* @return a prime factor of n.
|
||||
*/
|
||||
static int rhoBrent(final int n) {
|
||||
final int x0 = 2;
|
||||
final int m = 25;
|
||||
int cst = SmallPrimes.PRIMES_LAST;
|
||||
int y = x0;
|
||||
int r = 1;
|
||||
do {
|
||||
int x = y;
|
||||
for (int i = 0; i < r; i++) {
|
||||
final long y2 = ((long) y) * y;
|
||||
y = (int) ((y2 + cst) % n);
|
||||
}
|
||||
int k = 0;
|
||||
do {
|
||||
final int bound = FastMath.min(m, r - k);
|
||||
int q = 1;
|
||||
for (int i = -3; i < bound; i++) { //start at -3 to ensure we enter this loop at least 3 times
|
||||
final long y2 = ((long) y) * y;
|
||||
y = (int) ((y2 + cst) % n);
|
||||
final long divisor = FastMath.abs(x - y);
|
||||
if (0 == divisor) {
|
||||
cst += SmallPrimes.PRIMES_LAST;
|
||||
k = -m;
|
||||
y = x0;
|
||||
r = 1;
|
||||
break;
|
||||
}
|
||||
final long prod = divisor * q;
|
||||
q = (int) (prod % n);
|
||||
if (0 == q) {
|
||||
return gcdPositive(FastMath.abs((int) divisor), n);
|
||||
}
|
||||
}
|
||||
final int out = gcdPositive(FastMath.abs(q), n);
|
||||
if (1 != out) {
|
||||
return out;
|
||||
}
|
||||
k += m;
|
||||
} while (k < r);
|
||||
r = 2 * r;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gcd between two positive numbers.
|
||||
* <p>
|
||||
* Gets the greatest common divisor of two numbers, using the "binary gcd" method,
|
||||
* which avoids division and modulo operations. See Knuth 4.5.2 algorithm B.
|
||||
* This algorithm is due to Josef Stein (1961).
|
||||
* </p>
|
||||
* Special cases:
|
||||
* <ul>
|
||||
* <li>The result of {@code gcd(x, x)}, {@code gcd(0, x)} and {@code gcd(x, 0)} is the value of {@code x}.</li>
|
||||
* <li>The invocation {@code gcd(0, 0)} is the only one which returns {@code 0}.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param a first number, must be ≥ 0
|
||||
* @param b second number, must be ≥ 0
|
||||
* @return gcd(a,b)
|
||||
*/
|
||||
static int gcdPositive(int a, int b){
|
||||
// both a and b must be positive, it is not checked here
|
||||
// gdc(a,0) = a
|
||||
if (a == 0) {
|
||||
return b;
|
||||
} else if (b == 0) {
|
||||
return a;
|
||||
}
|
||||
|
||||
// make a and b odd, keep in mind the common power of twos
|
||||
final int aTwos = Integer.numberOfTrailingZeros(a);
|
||||
a >>= aTwos;
|
||||
final int bTwos = Integer.numberOfTrailingZeros(b);
|
||||
b >>= bTwos;
|
||||
final int shift = FastMath.min(aTwos, bTwos);
|
||||
|
||||
// a and b >0
|
||||
// if a > b then gdc(a,b) = gcd(a-b,b)
|
||||
// if a < b then gcd(a,b) = gcd(b-a,a)
|
||||
// so next a is the absolute difference and next b is the minimum of current values
|
||||
while (a != b) {
|
||||
final int delta = a - b;
|
||||
b = FastMath.min(a, b);
|
||||
a = FastMath.abs(delta);
|
||||
// for speed optimization:
|
||||
// remove any power of two in a as b is guaranteed to be odd throughout all iterations
|
||||
a >>= Integer.numberOfTrailingZeros(a);
|
||||
}
|
||||
|
||||
// gcd(a,a) = a, just "add" the common power of twos
|
||||
return a << shift;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue