My Project  debian-1:4.1.1-p2+ds-4
Functions | Variables
cfGcdAlgExt.cc File Reference
#include "config.h"
#include <stdio.h>
#include <iostream>
#include "cf_assert.h"
#include "timing.h"
#include "templates/ftmpl_functions.h"
#include "cf_defs.h"
#include "canonicalform.h"
#include "cf_iter.h"
#include "cf_primes.h"
#include "cf_algorithm.h"
#include "cfGcdAlgExt.h"
#include "cfUnivarGcd.h"
#include "cf_map.h"
#include "cf_generator.h"
#include "facMul.h"
#include "cfNTLzzpEXGCD.h"
#include "NTLconvert.h"
#include "FLINTconvert.h"

Go to the source code of this file.

Functions

 TIMING_DEFINE_PRINT (alg_content_p) TIMING_DEFINE_PRINT(alg_content) TIMING_DEFINE_PRINT(alg_compress) TIMING_DEFINE_PRINT(alg_termination) TIMING_DEFINE_PRINT(alg_termination_p) TIMING_DEFINE_PRINT(alg_reconstruction) TIMING_DEFINE_PRINT(alg_newton_p) TIMING_DEFINE_PRINT(alg_recursion_p) TIMING_DEFINE_PRINT(alg_gcd_p) TIMING_DEFINE_PRINT(alg_euclid_p) static int myCompress(const CanonicalForm &F
 compressing two polynomials F and G, M is used for compressing, N to reverse the compression More...
 
 for (int i=0;i<=n;i++) degsf[i]
 
 if (topLevel)
 
 DELETE_ARRAY (degsg)
 
void tryInvert (const CanonicalForm &F, const CanonicalForm &M, CanonicalForm &inv, bool &fail)
 
static CanonicalForm trycontent (const CanonicalForm &f, const Variable &x, const CanonicalForm &M, bool &fail)
 
static CanonicalForm tryvcontent (const CanonicalForm &f, const Variable &x, const CanonicalForm &M, bool &fail)
 
static CanonicalForm trycf_content (const CanonicalForm &f, const CanonicalForm &g, const CanonicalForm &M, bool &fail)
 
static CanonicalForm tryNewtonInterp (const CanonicalForm &alpha, const CanonicalForm &u, const CanonicalForm &newtonPoly, const CanonicalForm &oldInterPoly, const Variable &x, const CanonicalForm &M, bool &fail)
 
void tryBrownGCD (const CanonicalForm &F, const CanonicalForm &G, const CanonicalForm &M, CanonicalForm &result, bool &fail, bool topLevel)
 modular gcd over F_p[x]/(M) for not necessarily irreducible M. If a zero divisor is encountered fail is set to true. More...
 
static CanonicalForm myicontent (const CanonicalForm &f, const CanonicalForm &c)
 
static CanonicalForm myicontent (const CanonicalForm &f)
 
CanonicalForm QGCD (const CanonicalForm &F, const CanonicalForm &G)
 gcd over Q(a) More...
 
int * leadDeg (const CanonicalForm &f, int *degs)
 
bool isLess (int *a, int *b, int lower, int upper)
 
bool isEqual (int *a, int *b, int lower, int upper)
 
CanonicalForm firstLC (const CanonicalForm &f)
 

Variables

const CanonicalFormG
 
const CanonicalForm CFMapM
 
const CanonicalForm CFMap CFMapN
 
const CanonicalForm CFMap CFMap bool topLevel
 
int * degsf = NEW_ARRAY(int,n + 1)
 
int * degsg = NEW_ARRAY(int,n + 1)
 
int both_non_zero = 0
 
int f_zero = 0
 
int g_zero = 0
 
int both_zero = 0
 
int Flevel =F.level()
 
int Glevel =G.level()
 
 else
 
 return
 

Function Documentation

◆ DELETE_ARRAY()

DELETE_ARRAY ( degsg  )

◆ firstLC()

CanonicalForm firstLC ( const CanonicalForm f)

Definition at line 956 of file cfGcdAlgExt.cc.

957 { // returns the leading coefficient (LC) of level <= 1
958  CanonicalForm ret = f;
959  while(ret.level() > 1)
960  ret = LC(ret);
961  return ret;
962 }

◆ for()

for ( int  i = 0;i<=n;i++)

Definition at line 65 of file cfEzgcd.cc.

66  {
67  if (degsf[i] != 0 && degsg[i] != 0)
68  {
69  both_non_zero++;
70  continue;
71  }
72  if (degsf[i] == 0 && degsg[i] != 0 && i <= G.level())
73  {
74  f_zero++;
75  continue;
76  }
77  if (degsg[i] == 0 && degsf[i] && i <= F.level())
78  {
79  g_zero++;
80  continue;
81  }
82  }

◆ if()

if ( topLevel  )

Definition at line 75 of file cfGcdAlgExt.cc.

76  {
77  for (int i= 1; i <= n; i++)
78  {
79  if (degsf[i] != 0 && degsg[i] != 0)
80  {
81  both_non_zero++;
82  continue;
83  }
84  if (degsf[i] == 0 && degsg[i] != 0 && i <= Glevel)
85  {
86  f_zero++;
87  continue;
88  }
89  if (degsg[i] == 0 && degsf[i] && i <= Flevel)
90  {
91  g_zero++;
92  continue;
93  }
94  }
95 
96  if (both_non_zero == 0)
97  {
100  return 0;
101  }
102 
103  // map Variables which do not occur in both polynomials to higher levels
104  int k= 1;
105  int l= 1;
106  for (int i= 1; i <= n; i++)
107  {
108  if (degsf[i] != 0 && degsg[i] == 0 && i <= Flevel)
109  {
110  if (k + both_non_zero != i)
111  {
112  M.newpair (Variable (i), Variable (k + both_non_zero));
113  N.newpair (Variable (k + both_non_zero), Variable (i));
114  }
115  k++;
116  }
117  if (degsf[i] == 0 && degsg[i] != 0 && i <= Glevel)
118  {
119  if (l + g_zero + both_non_zero != i)
120  {
121  M.newpair (Variable (i), Variable (l + g_zero + both_non_zero));
122  N.newpair (Variable (l + g_zero + both_non_zero), Variable (i));
123  }
124  l++;
125  }
126  }
127 
128  // sort Variables x_{i} in increasing order of
129  // min(deg_{x_{i}}(f),deg_{x_{i}}(g))
130  int m= tmax (Flevel, Glevel);
131  int min_max_deg;
132  k= both_non_zero;
133  l= 0;
134  int i= 1;
135  while (k > 0)
136  {
137  if (degsf [i] != 0 && degsg [i] != 0)
138  min_max_deg= tmax (degsf[i], degsg[i]);
139  else
140  min_max_deg= 0;
141  while (min_max_deg == 0)
142  {
143  i++;
144  min_max_deg= tmax (degsf[i], degsg[i]);
145  if (degsf [i] != 0 && degsg [i] != 0)
146  min_max_deg= tmax (degsf[i], degsg[i]);
147  else
148  min_max_deg= 0;
149  }
150  for (int j= i + 1; j <= m; j++)
151  {
152  if (tmax (degsf[j],degsg[j]) <= min_max_deg && degsf[j] != 0 && degsg [j] != 0)
153  {
154  min_max_deg= tmax (degsf[j], degsg[j]);
155  l= j;
156  }
157  }
158  if (l != 0)
159  {
160  if (l != k)
161  {
162  M.newpair (Variable (l), Variable(k));
163  N.newpair (Variable (k), Variable(l));
164  degsf[l]= 0;
165  degsg[l]= 0;
166  l= 0;
167  }
168  else
169  {
170  degsf[l]= 0;
171  degsg[l]= 0;
172  l= 0;
173  }
174  }
175  else if (l == 0)
176  {
177  if (i != k)
178  {
179  M.newpair (Variable (i), Variable (k));
180  N.newpair (Variable (k), Variable (i));
181  degsf[i]= 0;
182  degsg[i]= 0;
183  }
184  else
185  {
186  degsf[i]= 0;
187  degsg[i]= 0;
188  }
189  i++;
190  }
191  k--;
192  }
193  }

◆ isEqual()

bool isEqual ( int *  a,
int *  b,
int  lower,
int  upper 
)

Definition at line 947 of file cfGcdAlgExt.cc.

948 { // compares the degree vectors a,b on the specified part. Note: x(i+1) > x(i)
949  for(int i=lower; i<=upper; i++)
950  if(a[i] != b[i])
951  return false;
952  return true;
953 }

◆ isLess()

bool isLess ( int *  a,
int *  b,
int  lower,
int  upper 
)

Definition at line 936 of file cfGcdAlgExt.cc.

937 { // compares the degree vectors a,b on the specified part. Note: x(i+1) > x(i)
938  for(int i=upper; i>=lower; i--)
939  if(a[i] == b[i])
940  continue;
941  else
942  return a[i] < b[i];
943  return true;
944 }

◆ leadDeg()

int* leadDeg ( const CanonicalForm f,
int *  degs 
)

Definition at line 919 of file cfGcdAlgExt.cc.

920 { // leading degree vector w.r.t. lex. monomial order x(i+1) > x(i)
921  // if f is in a coeff domain, the zero pointer is returned
922  // 'a' should point to an array of sufficient size level(f)+1
923  if(f.inCoeffDomain())
924  return 0;
925  CanonicalForm tmp = f;
926  do
927  {
928  degs[tmp.level()] = tmp.degree();
929  tmp = LC(tmp);
930  }
931  while(!tmp.inCoeffDomain());
932  return degs;
933 }

◆ myicontent() [1/2]

static CanonicalForm myicontent ( const CanonicalForm f)
static

Definition at line 706 of file cfGcdAlgExt.cc.

707 {
708 #ifdef HAVE_NTL
709  return myicontent( f, 0 );
710 #else
711  return 1;
712 #endif
713 }

◆ myicontent() [2/2]

static CanonicalForm myicontent ( const CanonicalForm f,
const CanonicalForm c 
)
static

Definition at line 656 of file cfGcdAlgExt.cc.

657 {
658 #ifdef HAVE_NTL
659  if (f.isOne() || c.isOne())
660  return 1;
661  if ( f.inBaseDomain() && c.inBaseDomain())
662  {
663  if (c.isZero()) return abs(f);
664  return bgcd( f, c );
665  }
666  else if ( (f.inCoeffDomain() && c.inCoeffDomain()) ||
667  (f.inCoeffDomain() && c.inBaseDomain()) ||
668  (f.inBaseDomain() && c.inCoeffDomain()))
669  {
670  if (c.isZero()) return abs (f);
671 #ifdef HAVE_FLINT
672  fmpz_poly_t FLINTf, FLINTc;
673  convertFacCF2Fmpz_poly_t (FLINTf, f);
674  convertFacCF2Fmpz_poly_t (FLINTc, c);
675  fmpz_poly_gcd (FLINTc, FLINTc, FLINTf);
677  if (f.inCoeffDomain())
678  result= convertFmpz_poly_t2FacCF (FLINTc, f.mvar());
679  else
680  result= convertFmpz_poly_t2FacCF (FLINTc, c.mvar());
681  fmpz_poly_clear (FLINTc);
682  fmpz_poly_clear (FLINTf);
683  return result;
684 #else
685  ZZX NTLf= convertFacCF2NTLZZX (f);
686  ZZX NTLc= convertFacCF2NTLZZX (c);
687  NTLc= GCD (NTLc, NTLf);
688  if (f.inCoeffDomain())
689  return convertNTLZZX2CF(NTLc,f.mvar());
690  else
691  return convertNTLZZX2CF(NTLc,c.mvar());
692 #endif
693  }
694  else
695  {
696  CanonicalForm g = c;
697  for ( CFIterator i = f; i.hasTerms() && ! g.isOne(); i++ )
698  g = myicontent( i.coeff(), g );
699  return g;
700  }
701 #else
702  return 1;
703 #endif
704 }

◆ QGCD()

gcd over Q(a)

Definition at line 715 of file cfGcdAlgExt.cc.

716 { // f,g in Q(a)[x1,...,xn]
717  if(F.isZero())
718  {
719  if(G.isZero())
720  return G; // G is zero
721  if(G.inCoeffDomain())
722  return CanonicalForm(1);
723  CanonicalForm lcinv= 1/Lc (G);
724  return G*lcinv; // return monic G
725  }
726  if(G.isZero()) // F is non-zero
727  {
728  if(F.inCoeffDomain())
729  return CanonicalForm(1);
730  CanonicalForm lcinv= 1/Lc (F);
731  return F*lcinv; // return monic F
732  }
733  if(F.inCoeffDomain() || G.inCoeffDomain())
734  return CanonicalForm(1);
735  // here: both NOT inCoeffDomain
736  CanonicalForm f, g, tmp, M, q, D, Dp, cl, newq, mipo;
737  int p, i;
738  int *bound, *other; // degree vectors
739  bool fail;
740  bool off_rational=!isOn(SW_RATIONAL);
741  On( SW_RATIONAL ); // needed by bCommonDen
742  f = F * bCommonDen(F);
743  g = G * bCommonDen(G);
745  CanonicalForm contf= myicontent (f);
746  CanonicalForm contg= myicontent (g);
747  f /= contf;
748  g /= contg;
749  CanonicalForm gcdcfcg= myicontent (contf, contg);
750  TIMING_END_AND_PRINT (alg_content, "time for content in alg gcd: ")
751  Variable a, b;
752  if(hasFirstAlgVar(f,a))
753  {
754  if(hasFirstAlgVar(g,b))
755  {
756  if(b.level() > a.level())
757  a = b;
758  }
759  }
760  else
761  {
762  if(!hasFirstAlgVar(g,a))// both not in extension
763  {
764  Off( SW_RATIONAL );
765  Off( SW_USE_QGCD );
766  tmp = gcdcfcg*gcd( f, g );
767  On( SW_USE_QGCD );
768  if (off_rational) Off(SW_RATIONAL);
769  return tmp;
770  }
771  }
772  // here: a is the biggest alg. var in f and g AND some of f,g is in extension
773  setReduce(a,false); // do not reduce expressions modulo mipo
774  tmp = getMipo(a);
775  M = tmp * bCommonDen(tmp);
776  // here: f, g in Z[a][x1,...,xn], M in Z[a] not necessarily monic
777  Off( SW_RATIONAL ); // needed by mod
778  // calculate upper bound for degree vector of gcd
779  int mv = f.level(); i = g.level();
780  if(i > mv)
781  mv = i;
782  // here: mv is level of the largest variable in f, g
783  bound = new int[mv+1]; // 'bound' could be indexed from 0 to mv, but we will only use from 1 to mv
784  other = new int[mv+1];
785  for(int i=1; i<=mv; i++) // initialize 'bound', 'other' with zeros
786  bound[i] = other[i] = 0;
787  bound = leadDeg(f,bound); // 'bound' is set the leading degree vector of f
788  other = leadDeg(g,other);
789  for(int i=1; i<=mv; i++) // entry at i=0 not visited
790  if(other[i] < bound[i])
791  bound[i] = other[i];
792  // now 'bound' is the smaller vector
793  cl = lc(M) * lc(f) * lc(g);
794  q = 1;
795  D = 0;
796  CanonicalForm test= 0;
797  bool equal= false;
798  for( i=cf_getNumBigPrimes()-1; i>-1; i-- )
799  {
800  p = cf_getBigPrime(i);
801  if( mod( cl, p ).isZero() ) // skip lc-bad primes
802  continue;
803  fail = false;
805  mipo = mapinto(M);
806  mipo /= mipo.lc();
807  // here: mipo is monic
808  TIMING_START (alg_gcd_p)
809  tryBrownGCD( mapinto(f), mapinto(g), mipo, Dp, fail );
810  TIMING_END_AND_PRINT (alg_gcd_p, "time for alg gcd mod p: ")
811  if( fail ) // mipo splits in char p
812  {
814  continue;
815  }
816  if( Dp.inCoeffDomain() ) // early termination
817  {
818  tryInvert(Dp,mipo,tmp,fail); // check if zero divisor
820  if(fail)
821  continue;
822  setReduce(a,true);
823  if (off_rational) Off(SW_RATIONAL); else On(SW_RATIONAL);
824  delete[] other;
825  delete[] bound;
826  return gcdcfcg;
827  }
829  // here: Dp NOT inCoeffDomain
830  for(int i=1; i<=mv; i++)
831  other[i] = 0; // reset (this is necessary, because some entries may not be updated by call to leadDeg)
832  other = leadDeg(Dp,other);
833 
834  if(isEqual(bound, other, 1, mv)) // equal
835  {
836  chineseRemainder( D, q, mapinto(Dp), p, tmp, newq );
837  // tmp = Dp mod p
838  // tmp = D mod q
839  // newq = p*q
840  q = newq;
841  if( D != tmp )
842  D = tmp;
843  On( SW_RATIONAL );
844  TIMING_START (alg_reconstruction)
845  tmp = Farey( D, q ); // Farey
846  tmp *= bCommonDen (tmp);
847  TIMING_END_AND_PRINT (alg_reconstruction,
848  "time for rational reconstruction in alg gcd: ")
849  setReduce(a,true); // reduce expressions modulo mipo
850  On( SW_RATIONAL ); // needed by fdivides
851  if (test != tmp)
852  test= tmp;
853  else
854  equal= true; // modular image did not add any new information
855  TIMING_START (alg_termination)
856 #ifdef HAVE_NTL
857 #ifdef HAVE_FLINT
858  if (equal && tmp.isUnivariate() && f.isUnivariate() && g.isUnivariate()
859  && f.level() == tmp.level() && tmp.level() == g.level())
860  {
861  CanonicalForm Q, R;
862  newtonDivrem (f, tmp, Q, R);
863  if (R.isZero())
864  {
865  newtonDivrem (g, tmp, Q, R);
866  if (R.isZero())
867  {
868  Off (SW_RATIONAL);
869  setReduce (a,true);
870  if (off_rational) Off(SW_RATIONAL); else On(SW_RATIONAL);
871  TIMING_END_AND_PRINT (alg_termination,
872  "time for successful termination test in alg gcd: ")
873  delete[] other;
874  delete[] bound;
875  return tmp*gcdcfcg;
876  }
877  }
878  }
879  else
880 #endif
881 #endif
882  if(equal && fdivides( tmp, f ) && fdivides( tmp, g )) // trial division
883  {
884  Off( SW_RATIONAL );
885  setReduce(a,true);
886  if (off_rational) Off(SW_RATIONAL); else On(SW_RATIONAL);
887  TIMING_END_AND_PRINT (alg_termination,
888  "time for successful termination test in alg gcd: ")
889  delete[] other;
890  delete[] bound;
891  return tmp*gcdcfcg;
892  }
893  TIMING_END_AND_PRINT (alg_termination,
894  "time for unsuccessful termination test in alg gcd: ")
895  Off( SW_RATIONAL );
896  setReduce(a,false); // do not reduce expressions modulo mipo
897  continue;
898  }
899  if( isLess(bound, other, 1, mv) ) // current prime unlucky
900  continue;
901  // here: isLess(other, bound, 1, mv) ) ==> all previous primes unlucky
902  q = p;
903  D = mapinto(Dp); // shortcut CRA // shortcut CRA
904  for(int i=1; i<=mv; i++) // tighten bound
905  bound[i] = other[i];
906  }
907  // hopefully, we never reach this point
908  setReduce(a,true);
909  delete[] other;
910  delete[] bound;
911  Off( SW_USE_QGCD );
912  D = gcdcfcg*gcd( f, g );
913  On( SW_USE_QGCD );
914  if (off_rational) Off(SW_RATIONAL); else On(SW_RATIONAL);
915  return D;
916 }

◆ TIMING_DEFINE_PRINT()

TIMING_DEFINE_PRINT ( alg_content_p  ) const &

compressing two polynomials F and G, M is used for compressing, N to reverse the compression

◆ tryBrownGCD()

void tryBrownGCD ( const CanonicalForm F,
const CanonicalForm G,
const CanonicalForm M,
CanonicalForm result,
bool &  fail,
bool  topLevel 
)

modular gcd over F_p[x]/(M) for not necessarily irreducible M. If a zero divisor is encountered fail is set to true.

Definition at line 372 of file cfGcdAlgExt.cc.

373 { // assume F,G are multivariate polys over Z/p(a) for big prime p, M "univariate" polynomial in an algebraic variable
374  // M is assumed to be monic
375  if(F.isZero())
376  {
377  if(G.isZero())
378  {
379  result = G; // G is zero
380  return;
381  }
382  if(G.inCoeffDomain())
383  {
384  tryInvert(G,M,result,fail);
385  if(fail)
386  return;
387  result = 1;
388  return;
389  }
390  // try to make G monic modulo M
391  CanonicalForm inv;
392  tryInvert(Lc(G),M,inv,fail);
393  if(fail)
394  return;
395  result = inv*G;
396  result= reduce (result, M);
397  return;
398  }
399  if(G.isZero()) // F is non-zero
400  {
401  if(F.inCoeffDomain())
402  {
403  tryInvert(F,M,result,fail);
404  if(fail)
405  return;
406  result = 1;
407  return;
408  }
409  // try to make F monic modulo M
410  CanonicalForm inv;
411  tryInvert(Lc(F),M,inv,fail);
412  if(fail)
413  return;
414  result = inv*F;
415  result= reduce (result, M);
416  return;
417  }
418  // here: F,G both nonzero
419  if(F.inCoeffDomain())
420  {
421  tryInvert(F,M,result,fail);
422  if(fail)
423  return;
424  result = 1;
425  return;
426  }
427  if(G.inCoeffDomain())
428  {
429  tryInvert(G,M,result,fail);
430  if(fail)
431  return;
432  result = 1;
433  return;
434  }
435  TIMING_START (alg_compress)
436  CFMap MM,NN;
437  int lev= myCompress (F, G, MM, NN, topLevel);
438  if (lev == 0)
439  {
440  result= 1;
441  return;
442  }
443  CanonicalForm f=MM(F);
444  CanonicalForm g=MM(G);
445  TIMING_END_AND_PRINT (alg_compress, "time to compress in alg gcd: ")
446  // here: f,g are compressed
447  // compute largest variable in f or g (least one is Variable(1))
448  int mv = f.level();
449  if(g.level() > mv)
450  mv = g.level();
451  // here: mv is level of the largest variable in f, g
452  Variable v1= Variable (1);
453 #ifdef HAVE_NTL
454  Variable v= M.mvar();
456  {
458  zz_p::init (getCharacteristic());
459  }
460  zz_pX NTLMipo= convertFacCF2NTLzzpX (M);
461  zz_pE::init (NTLMipo);
462  zz_pEX NTLResult;
463  zz_pEX NTLF;
464  zz_pEX NTLG;
465 #endif
466  if(mv == 1) // f,g univariate
467  {
468  TIMING_START (alg_euclid_p)
469 #ifdef HAVE_NTL
470  NTLF= convertFacCF2NTLzz_pEX (f, (NTLMipo);
462  {
466  a4f6f7993 bool &topLevel)
GCD of F and G over , l and topLevel aspan>  fac_NTL_char= 462Lconvertdiv>
CanonicalForm &v> delethref="cfEzgcd_8cc.html#a12fcb6adcb033a94e6014c377eb44bd9">N (d* 466  if(mv == 1) = 457div>
7>

7>

)> 1004 7>

7>

  }

7>

690 
690ª CanonicalForm lcinv= 1/ 852cl CanonicalForm lcinv= 1ec00bb456d43">g=

default)blow">if( 925  925Ca"classCanonicalForm.html#aabe42bce58279d873f73c1c05413b6e6"> 925Ca"c05413b6e6"> 925Ca"classCanonicalForm.html#aabe42b#aabe42bce58279d873f73c1c05413b6e6"e1ac16141c84e3e073">M, bool &fail)   727  {m, a,4v2);
727
  {m, a,4v2)lass="lineno"> 462Lconvertdiv>   {
671  /div> i= 1; 776  1/Variable ( 776  1/ 776 "code" h9ef6392">i] != 0)
Var="l012class="lineno"> 738  (922">c05413b6e6">m, a,4v2);
727  }
m, a,4v2);
continue;
  lcD = gcd/div>
  (SW_RATIONAL );lass="keywordflow">if (continue;
i])
< 791  185  {
1350 c9 d”DCp)˜öʼÀ¿a*c63f11ºk)4
Ny13div class="line"><5&span cdiv>
236 
<5&span cdiv>
Pound[* 727  {<5&span cdiv>
<5&span cdiv>
<5&span cdia)13baf84250240780">isLess(k++;<)div>
true);
428 div clss="line"> 428 div clss="line">