[SCM] an open source computer algebra system branch, cleanedupstream, updated. 6125e540ca6d66c307958938a9d53b245507c323
Bernhard R. Link
brlink at debian.org
Tue Apr 24 15:54:38 UTC 2012
The following commit has been merged in the cleanedupstream branch:
commit af0acb05cd4c464c6509dbdbc0c36b690bf18719
Author: Martin Lee <martinlee84 at web.de>
Date: Mon Jan 9 14:01:10 2012 +0100
chg: replaced Hensel lifting and early factor detection by a
faster version
diff --git a/factory/facBivar.cc b/factory/facBivar.cc
index 9a3d980..aeb25ec 100644
--- a/factory/facBivar.cc
+++ b/factory/facBivar.cc
@@ -18,6 +18,7 @@
#include "facFqBivar.h"
#include "facBivar.h"
+#include "facHensel.h"
#ifdef HAVE_NTL
TIMING_DEFINE_PRINT(fac_uni_factorizer)
@@ -80,6 +81,171 @@ CanonicalForm evalPoint (const CanonicalForm& F, int& i)
} while (1);
}
+CFList
+earlyFactorDetection0 (CanonicalForm& F, CFList& factors,int& adaptedLiftBound,
+ DegreePattern& degs, bool& success, int deg)
+{
+ DegreePattern bufDegs1= degs;
+ DegreePattern bufDegs2;
+ CFList result;
+ CFList T= factors;
+ CanonicalForm buf= F;
+ CanonicalForm LCBuf= LC (buf, Variable (1));
+ CanonicalForm g, quot;
+ CanonicalForm M= power (F.mvar(), deg);
+ adaptedLiftBound= 0;
+ int d= degree (F) + degree (LCBuf, F.mvar());
+ for (CFListIterator i= factors; i.hasItem(); i++)
+ {
+ if (!bufDegs1.find (degree (i.getItem(), 1)))
+ continue;
+ else
+ {
+ g= i.getItem() (0, 1);
+ g *= LCBuf;
+ g= mod (g, M);
+ if (fdivides (LC (g), LCBuf))
+ {
+ g= mulMod2 (i.getItem(), LCBuf, M);
+ g /= content (g, Variable (1));
+ if (fdivides (g, buf, quot))
+ {
+ result.append (g);
+ buf= quot;
+ d -= degree (g) + degree (LC (g, Variable (1)), F.mvar());
+ LCBuf= LC (buf, Variable (1));
+ T= Difference (T, CFList (i.getItem()));
+
+ // compute new possible degree pattern
+ bufDegs2= DegreePattern (T);
+ bufDegs1.intersect (bufDegs2);
+ bufDegs1.refine ();
+ if (bufDegs1.getLength() <= 1)
+ {
+ result.append (buf);
+ break;
+ }
+ }
+ }
+ }
+ }
+ adaptedLiftBound= d + 1;
+ if (d < deg)
+ {
+ factors= T;
+ degs= bufDegs1;
+ F= buf;
+ success= true;
+ }
+ if (bufDegs1.getLength() <= 1)
+ degs= bufDegs1;
+ return result;
+}
+
+
+CFList
+henselLiftAndEarly0 (CanonicalForm& A, bool& earlySuccess, CFList&
+ earlyFactors, DegreePattern& degs, int& liftBound,
+ const CFList& uniFactors, const CanonicalForm& eval)
+{
+ int sizeOfLiftPre;
+ int * liftPre= getLiftPrecisions (A, sizeOfLiftPre, degree (LC (A, 1), 2));
+
+ Variable x= Variable (1);
+ Variable y= Variable (2);
+ CFArray Pi;
+ CFList diophant;
+ CFList bufUniFactors= uniFactors;
+ bufUniFactors.insert (LC (A, x));
+ CFMatrix M= CFMatrix (liftBound, bufUniFactors.length() - 1);
+ earlySuccess= false;
+ int newLiftBound= 0;
+ int smallFactorDeg= tmin (11, liftPre [sizeOfLiftPre- 1] + 1);//this is a tunable parameter
+ if (smallFactorDeg >= liftBound || degree (A,y) <= 4)
+ henselLift12 (A, bufUniFactors, liftBound, Pi, diophant, M);
+ else if (sizeOfLiftPre > 1 && sizeOfLiftPre < 30)
+ {
+ henselLift12 (A, bufUniFactors, smallFactorDeg, Pi, diophant, M);
+ earlyFactors= earlyFactorDetection0 (A, bufUniFactors, newLiftBound,
+ degs, earlySuccess,
+ smallFactorDeg);
+ if (degs.getLength() > 1 && !earlySuccess &&
+ smallFactorDeg != liftPre [sizeOfLiftPre-1] + 1)
+ {
+ if (newLiftBound > liftPre[sizeOfLiftPre-1]+1)
+ {
+ bufUniFactors.insert (LC (A, x));
+ henselLiftResume12 (A, bufUniFactors, smallFactorDeg,
+ liftPre[sizeOfLiftPre-1] + 1, Pi, diophant, M);
+ earlyFactors= earlyFactorDetection0 (A, bufUniFactors, newLiftBound,
+ degs, earlySuccess, liftPre[sizeOfLiftPre-1] + 1);
+ }
+ }
+ else if (earlySuccess)
+ liftBound= newLiftBound;
+ int i= sizeOfLiftPre - 1;
+ while (degs.getLength() > 1 && !earlySuccess && i - 1 >= 0)
+ {
+ if (newLiftBound > liftPre[i] + 1)
+ {
+ bufUniFactors.insert (LC (A, x));
+ henselLiftResume12 (A, bufUniFactors, liftPre[i] + 1,
+ liftPre[i-1] + 1, Pi, diophant, M);
+ earlyFactors= earlyFactorDetection0 (A, bufUniFactors, newLiftBound,
+ degs, earlySuccess, liftPre[i-1] + 1);
+ }
+ else
+ {
+ liftBound= newLiftBound;
+ break;
+ }
+ i--;
+ }
+ if (earlySuccess)
+ liftBound= newLiftBound;
+ //after here all factors are lifted to liftPre[sizeOfLiftPre-1]
+ }
+ else
+ {
+ henselLift12 (A, bufUniFactors, smallFactorDeg, Pi, diophant, M);
+ earlyFactors= earlyFactorDetection0 (A, bufUniFactors, newLiftBound,
+ degs, earlySuccess,
+ smallFactorDeg);
+ int i= 1;
+ while ((degree (A,y)/4)*i + 4 <= smallFactorDeg)
+ i++;
+ if (degs.getLength() > 1 && !earlySuccess)
+ {
+ bufUniFactors.insert (LC (A, x));
+ henselLiftResume12 (A, bufUniFactors, smallFactorDeg,
+ (degree (A, y)/4)*i + 4, Pi, diophant, M);
+ earlyFactors= earlyFactorDetection0 (A, bufUniFactors, newLiftBound,
+ degs, earlySuccess, (degree (A, y)/4)*i + 4);
+ }
+ while (degs.getLength() > 1 && !earlySuccess && i < 4)
+ {
+ if (newLiftBound > (degree (A, y)/4)*i + 4)
+ {
+ bufUniFactors.insert (LC (A, x));
+ henselLiftResume12 (A, bufUniFactors, (degree (A,y)/4)*i + 4,
+ (degree (A, y)/4)*(i+1) + 4, Pi, diophant, M);
+ earlyFactors= earlyFactorDetection0 (A, bufUniFactors, newLiftBound,
+ degs, earlySuccess, (degree (A, y)/4)*(i+1) + 4);
+ }
+ else
+ {
+ liftBound= newLiftBound;
+ break;
+ }
+ i++;
+ }
+ if (earlySuccess)
+ liftBound= newLiftBound;
+ }
+
+ return bufUniFactors;
+}
+
CFList biFactorize (const CanonicalForm& F, const Variable& v)
{
if (F.inCoeffDomain())
@@ -362,13 +528,12 @@ CFList biFactorize (const CanonicalForm& F, const Variable& v)
int liftBound= degree (A, y) + 1;
- ExtensionInfo dummy= ExtensionInfo (false);
bool earlySuccess= false;
CFList earlyFactors;
TIMING_START (fac_hensel_lift);
- uniFactors= henselLiftAndEarly
+ uniFactors= henselLiftAndEarly0
(A, earlySuccess, earlyFactors, degs, liftBound,
- uniFactors, dummy, evaluation);
+ uniFactors, evaluation);
TIMING_END_AND_PRINT (fac_hensel_lift, "time for hensel lifting: ");
DEBOUTLN (cerr, "lifted factors= " << uniFactors);
--
an open source computer algebra system
More information about the debian-science-commits
mailing list