mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[poincare] Fix primeFactorization to factorize any number (no bound
anymore) Change-Id: I389124fcca03843aadcae4a6d5db10188f14c194
This commit is contained in:
@@ -30,8 +30,9 @@ int primeFactors[Arithmetic::k_numberOfPrimeFactors] = {2, 3, 5, 7, 11, 13, 17,
|
||||
|
||||
// we can go to 7907*7907 = 62 520 649
|
||||
void Arithmetic::PrimeFactorization(const Integer * n, Integer * outputFactors, Integer * outputCoefficients, int outputLength) {
|
||||
// TODO: Find the prime factorization of any number. When k_numberOfPrimeFactors is overflow, try every number as divisor.
|
||||
assert(n->isLowerThan(Integer(primeFactors[k_numberOfPrimeFactors-1]*primeFactors[k_numberOfPrimeFactors-1])));
|
||||
/* First we look for prime divisors in the table primeFactors (to speed up
|
||||
* the prime factorization for low numbers). When k_numberOfPrimeFactors is
|
||||
* overflow, try every number as divisor. */
|
||||
for (int index = 0; index < outputLength; index++) {
|
||||
outputCoefficients[index] = Integer(0);
|
||||
}
|
||||
@@ -42,11 +43,12 @@ void Arithmetic::PrimeFactorization(const Integer * n, Integer * outputFactors,
|
||||
}
|
||||
int t = 0; // n prime factor index
|
||||
int k = 0; // prime factor index
|
||||
outputFactors[t] = Integer(primeFactors[k]);
|
||||
Integer testedPrimeFactor = Integer(primeFactors[k]); // prime factor
|
||||
outputFactors[t] = testedPrimeFactor;
|
||||
IntegerDivision d = {.quotient = 0, .remainder = 0};
|
||||
bool stopCondition;
|
||||
do {
|
||||
d = Integer::Division(m, Integer(primeFactors[k]));
|
||||
d = Integer::Division(m, testedPrimeFactor);
|
||||
stopCondition = outputFactors[t].isLowerThan(d.quotient); // We evaluate the condition here in case we move d.quotient in n
|
||||
if (d.remainder.isEqualTo(Integer(0))) {
|
||||
outputCoefficients[t] = Integer::Addition(outputCoefficients[t], Integer(1));
|
||||
@@ -56,11 +58,12 @@ void Arithmetic::PrimeFactorization(const Integer * n, Integer * outputFactors,
|
||||
}
|
||||
continue;
|
||||
}
|
||||
k++;
|
||||
if (!outputCoefficients[t].isEqualTo(Integer(0))) {
|
||||
t++;
|
||||
}
|
||||
outputFactors[t] = Integer(primeFactors[k]);
|
||||
k++;
|
||||
testedPrimeFactor = k < k_numberOfPrimeFactors ? Integer(primeFactors[k]) : Integer::Addition(testedPrimeFactor, Integer(1));
|
||||
outputFactors[t] = testedPrimeFactor;
|
||||
} while (stopCondition);
|
||||
outputFactors[t] = std::move(m);
|
||||
outputCoefficients[t] = Integer::Addition(outputCoefficients[t], Integer(1));
|
||||
|
||||
@@ -42,8 +42,12 @@ void assert_prime_factorization_equals_to(Integer a, int * factors, int * coeffi
|
||||
if (outputCoefficients[index].isEqualTo(Integer(0))) {
|
||||
break;
|
||||
}
|
||||
assert(outputFactors[index].identifier() == factors[index]); // Cheat: instead of comparing to integers, we compare only identifier as we know that prime factors and their coefficients will always be lower than 2^32.
|
||||
assert(outputCoefficients[index].identifier() == coefficients[index]);
|
||||
/* Cheat: instead of comparing to integers, we compare their approximations
|
||||
* (the relation between integers and their approximation is a surjection,
|
||||
* however different integers are really likely to have different
|
||||
* approximations... */
|
||||
assert(outputFactors[index].approximate<float>(context) == Integer(factors[index]).approximate<float>(context));
|
||||
assert(outputCoefficients[index].approximate<float>(context) == Integer(coefficients[index]).approximate<float>(context));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,4 +66,7 @@ QUIZ_CASE(poincare_arithmetic) {
|
||||
int factors2[3] = {2,5, 7};
|
||||
int coefficients2[3] = {2,4,2};
|
||||
assert_prime_factorization_equals_to(Integer(122500), factors2, coefficients2, 3);
|
||||
int factors3[8] = {3,7,11, 13, 19, 3607, 3803, 52579};
|
||||
int coefficients3[8] = {4,2,2,2,2,2,2,2};
|
||||
assert_prime_factorization_equals_to(Integer("15241578780673678515622620750190521"), factors3, coefficients3, 8);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user