Skip to content

Commit

Permalink
Added progress for equal degree factorization
Browse files Browse the repository at this point in the history
  • Loading branch information
alpertron committed Oct 10, 2017
1 parent 43d9ba5 commit 8ce95b2
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 9 deletions.
78 changes: 75 additions & 3 deletions polfact.c
Expand Up @@ -25,6 +25,11 @@ along with Alpertron Calculators. If not, see <http://www.gnu.org/licenses/>.
#include "polynomial.h"
#include "showtime.h"

#ifdef __EMSCRIPTEN__
int attemptNbr;
char *ptrPercentageOutput;
#endif

extern int poly4[1000000];
// Perform distinct degree factorization
static void DistinctDegreeFactorization(int polyDegree)
Expand Down Expand Up @@ -63,6 +68,7 @@ static void DistinctDegreeFactorization(int polyDegree)
if (elapsedTime / 10 != oldTimeElapsed / 10)
{
char *ptrOutput = output;
oldTimeElapsed = elapsedTime;
if (lang)
{
strcpy(ptrOutput, "1<p>Factorización de distintos grados: buscando factores de grado ");
Expand Down Expand Up @@ -102,7 +108,7 @@ static void DistinctDegreeFactorization(int polyDegree)
ptrValue1 = &poly3[polyDegree*nbrLimbs];
memcpy(poly3, ptrPolyToFactor, (ptrValue1 - &poly3[0])*sizeof(int));
SetNumberToOne(ptrValue1); // Set leading coefficient to 1.
powerPolynomial(poly1, poly3, polyDegree, &primeMod, poly2);
powerPolynomial(poly1, poly3, polyDegree, &primeMod, poly2, NULL);
memcpy(poly1, poly2, polyDegree*nbrLimbs * sizeof(int));
// Subtract x.
UncompressBigInteger(&poly2[nbrLimbs], &operand1);
Expand Down Expand Up @@ -152,6 +158,39 @@ static void DistinctDegreeFactorization(int polyDegree)
}
}

static void percentageCallback(int percentage)
{
#ifdef __EMSCRIPTEN__
int elapsedTime = (int)(tenths() - originalTenthSecond);
char *ptrOutput = ptrPercentageOutput;
if (elapsedTime / 10 != oldTimeElapsed / 10)
{
oldTimeElapsed = elapsedTime;
int2dec(&ptrOutput, percentage);
if (lang)
{
strcpy(ptrOutput, "% del ");
ptrOutput += strlen(ptrOutput);
int2dec(&ptrOutput, attemptNbr);
strcpy(ptrOutput, ".º intento");
ptrOutput += strlen(ptrOutput);
}
else
{
strcpy(ptrOutput, "% of attempt #");
ptrOutput += strlen(ptrOutput);
int2dec(&ptrOutput, attemptNbr);
}
strcpy(ptrOutput, lang ? ".</p><p>Transcurrió " : ".</p><p>Time elapsed: ");
ptrOutput += strlen(ptrOutput);
GetDHMS(&ptrOutput, elapsedTime / 10);
strcpy(ptrOutput, "</p>");
databack(output);
}
#endif
}


// Perform Cantor-Zassenhaus algorithm to factor polynomials of the same degree.
static void SameDegreeFactorization(void)
{
Expand All @@ -171,6 +210,9 @@ static void SameDegreeFactorization(void)
pstFactorInfo++;
continue;
}
#ifdef __EMSCRIPTEN__
attemptNbr = 1;
#endif
if (isCharacteristic2 == 0)
{ // If prime is not 2,
// Calculate operand2 <- (prime^degree-1)/2
Expand All @@ -184,6 +226,27 @@ static void SameDegreeFactorization(void)
GetPolyInvParm(polyDegree, ptrPolyToFactor);
for (;;)
{
#ifdef __EMSCRIPTEN__
char *ptrOutput = output;
if (lang)
{
strcpy(ptrOutput, "1<p>Factorización del mismo grado: buscando ");
ptrOutput += strlen(ptrOutput);
int2dec(&ptrOutput, polyDegree / pstFactorInfo->expectedDegree);
strcpy(ptrOutput, " factores de grado ");
}
else
{
strcpy(ptrOutput, "1<p>Equal degree factorization: searching for ");
ptrOutput += strlen(ptrOutput);
int2dec(&ptrOutput, polyDegree / pstFactorInfo->expectedDegree);
strcpy(ptrOutput, " factors of degree ");
}
ptrOutput += strlen(ptrOutput);
int2dec(&ptrOutput, pstFactorInfo->expectedDegree);
strcpy(ptrOutput, ".</p><p>");
ptrPercentageOutput = ptrOutput + strlen(ptrOutput);
#endif
// Copy polynomial to factor to poly3 and set leading coefficient to 1.
ptrValue1 = &poly3[pstFactorInfo->degree*nbrLimbs];
memcpy(poly3, ptrPolyToFactor, (ptrValue1 - &poly3[0])*sizeof(int));
Expand Down Expand Up @@ -211,7 +274,7 @@ static void SameDegreeFactorization(void)
}
if (isCharacteristic2 == 0)
{ // If prime is not 2: compute (random poly)^((p^d-1)/2)
powerPolynomial(poly1, poly3, polyDegree, &operand4, poly2);
powerPolynomial(poly1, poly3, polyDegree, &operand4, poly2, percentageCallback);
// Subtract 1.
UncompressBigInteger(&poly2[0], &operand1);
SubtBigNbrMod(operand1.limbs, MontgomeryMultR1, operand1.limbs);
Expand Down Expand Up @@ -250,12 +313,18 @@ static void SameDegreeFactorization(void)
memcpy(ptrPolyToFactor, polyMultTemp, degreeGcd*nbrLimbs*sizeof(int));
memcpy(pstNewFactorInfo->ptr, poly2, (polyDegree - degreeGcd)*nbrLimbs*sizeof(int));
polyDegree = degreeGcd;
#ifdef __EMSCRIPTEN__
attemptNbr = 0;
#endif
if (pstFactorInfo->expectedDegree == pstFactorInfo->degree)
{
break;
}
GetPolyInvParm(polyDegree, ptrPolyToFactor);
}
#ifdef __EMSCRIPTEN__
attemptNbr++;
#endif
}
pstFactorInfo++;
}
Expand Down Expand Up @@ -428,7 +497,10 @@ void polyFactText(char *modText, char *polyText, int groupLength)
{
outputPolynomial(ptrOutput, groupLength);
ptrOutput += strlen(ptrOutput);
showElapsedTime(&ptrOutput);
if (onlyEvaluate == 0)
{ // Show time only when factoring, not when just evaluating polynomial.
showElapsedTime(&ptrOutput);
}
}
strcpy(ptrOutput, lang ? "<p>" COPYRIGHT_SPANISH "</p>" :
"<p>" COPYRIGHT_ENGLISH "</p>");
Expand Down
21 changes: 18 additions & 3 deletions polynomial.c
Expand Up @@ -1789,33 +1789,48 @@ void multPolynomial(/*@in@*/int *polyFact1, /*@in@*/int *polyFact2,
}
memcpy(polyProduct, polyMultTemp, polyDegree*nbrLimbs*sizeof(int));
}

// Perform polyPower <- polyBase ^ expon (mod polyMod)
void powerPolynomial(int *polyBase, int *polyMod, int polyDegree, BigInteger *expon, int *polyPower)
void powerPolynomial(int *polyBase, int *polyMod, int polyDegree, BigInteger *expon,
int *polyPower, powerCback callback)
{
int mask, index;
int nbrLimbs = NumberLength + 1;
int powerIsOne = TRUE;
int nbrBits = 0;
int bitCounter;
// Initialize polyPower to 1.
memset(polyPower, 0, (polyDegree + 1)*nbrLimbs * sizeof(int));
for (index = 0; index <= polyDegree; index++)
{
*(polyPower + index*nbrLimbs) = 1;
}
SetNumberToOne(polyPower);
for (index = expon->nbrLimbs - 1; index >= 0; index--)
index = expon->nbrLimbs - 1;
bitCounter = (index+1) * BITS_PER_GROUP;
for (; index >= 0; index--)
{
int groupExp = (int)(expon->limbs[index].x);
for (mask = 1 << (BITS_PER_GROUP - 1); mask > 0; mask >>= 1)
{
if (!powerIsOne)
{
if (callback)
{
callback(100 - 100 * bitCounter/nbrBits);
}
multUsingInvPolynomial(polyPower, polyPower, polyPower, polyDegree, polyMod);
}
if ((groupExp & mask) != 0)
{
multUsingInvPolynomial(polyPower, polyBase, polyPower, polyDegree, polyMod);
powerIsOne = FALSE;
if (powerIsOne)
{
nbrBits = bitCounter;
powerIsOne = FALSE;
}
}
bitCounter--;
}
}
}
Expand Down
10 changes: 7 additions & 3 deletions polynomial.h
Expand Up @@ -46,12 +46,16 @@ extern int degree;
extern int *ptrOrigPoly;
extern int degreeOrigPoly;

typedef void (*powerCback)(int percentage);
void SetNumberToOne(/*@out@*/int *ptrValue1);
void PolynomialGcd(int *arg1, int degree1, int *arg2, int degree2, int *gcd, int *degreeGcd);
void powerPolynomial(int *polyBase, int *polyMod, int polyDegree, BigInteger *expon, int *polyPower);
void powerPolynomial(int *polyBase, int *polyMod, int polyDegree, BigInteger *expon,
int *polyPower, powerCback cback);
int getDegreePoly(int *poly, int polyDegree);
void DividePolynomial(/*@in@*/int *pDividend, int dividendDegree, /*@in@*/int *pDivisor, int divisorDegree, /*@out@*/int *ptrQuotient);
void multPolynomial(/*@in@*/int *polyFact1, /*@in@*/int *polyFact2, /*@out@*/int *polyProduct, int polyDegree, /*@in@*/int *polyMod);
void DividePolynomial(/*@in@*/int *pDividend, int dividendDegree, /*@in@*/int *pDivisor,
int divisorDegree, /*@out@*/int *ptrQuotient);
void multPolynomial(/*@in@*/int *polyFact1, /*@in@*/int *polyFact2, /*@out@*/int *polyProduct,
int polyDegree, /*@in@*/int *polyMod);
void GetPolyInvParm(int polyDegree, /*@in@*/int *polyMod);
int ComputePolynomial(char *input, int expo);
void OrigPolyFromMontgomeryToStandard(void);
Expand Down

0 comments on commit 8ce95b2

Please sign in to comment.