Changeset dec1024 in git


Ignore:
Timestamp:
Sep 20, 2010, 5:17:36 PM (13 years ago)
Author:
Martin Lee <martinlee84@…>
Branches:
(u'spielwiese', '8d54773d6c9e2f1d2593a28bc68b7eeab54ed529')
Children:
a0b5e27a5fb475f020a02a82976ffe87d3c097ae
Parents:
3f46965e1ad849ccb6d39d9e57cca2ecbbf10d86
Message:
added heuristics to modular gcd


git-svn-id: file:///usr/local/Singular/svn/trunk@13230 2c84dea3-7e68-4137-9b89-c4e89433aadc
File:
1 edited

Legend:

Unmodified
Added
Removed
  • factory/cf_gcd_smallp.cc

    r3f4696 rdec1024  
    5050static inline
    5151int myCompress (const CanonicalForm& F, const CanonicalForm& G, CFMap & M,
    52                 CFMap & N, bool& top_level)
     52                CFMap & N, bool& topLevel)
    5353{
    5454  int n= tmax (F.level(), G.level());
     
    6767  int both_zero= 0;
    6868
    69   if (top_level)
     69  if (topLevel)
    7070  {
    7171    for (int i= 1; i <= n; i++)
     
    8888    }
    8989
    90     if (both_non_zero == 0) return 0;
     90    if (both_non_zero == 0)
     91    {
     92      delete [] degsf;
     93      delete [] degsg;
     94      return 0;
     95    }
    9196
    9297    // map Variables which do not occur in both polynomials to higher levels
     
    201206}
    202207
     208int
     209substituteCheck (const CanonicalForm& F, const CanonicalForm& G)
     210{
     211  if (F.inCoeffDomain() || G.inCoeffDomain())
     212    return 0;
     213  Variable x= Variable (1);
     214  if (degree (F, x) <= 1 || degree (G, x) <= 1)
     215    return 0;
     216  CanonicalForm f= swapvar (F, F.mvar(), x); //TODO swapping seems to be pretty expensive
     217  CanonicalForm g= swapvar (G, G.mvar(), x);
     218  int sizef= 0;
     219  int sizeg= 0;
     220  for (CFIterator i= f; i.hasTerms(); i++, sizef++)
     221  {
     222    if (i.exp() == 1)
     223      return 0;
     224  }
     225  for (CFIterator i= g; i.hasTerms(); i++, sizeg++)
     226  {
     227    if (i.exp() == 1)
     228      return 0;
     229  }
     230  int * expf= new int [sizef];
     231  int * expg= new int [sizeg];
     232  int j= 0;
     233  for (CFIterator i= f; i.hasTerms(); i++, j++)
     234  {
     235    expf [j]= i.exp();
     236  }
     237  j= 0;
     238  for (CFIterator i= g; i.hasTerms(); i++, j++)
     239  {
     240    expg [j]= i.exp();
     241  }
     242 
     243  int indf= sizef - 1;
     244  int indg= sizeg - 1;
     245  if (expf[indf] == 0)
     246    indf--;
     247  if (expg[indg] == 0)
     248    indg--;
     249   
     250  if (expg[indg] != expf [indf] || (expg[indg] == 1 && expf[indf] == 1))
     251  {
     252    delete [] expg;
     253    delete [] expf;
     254    return 0;
     255  }
     256  // expf[indg] == expf[indf] after here
     257  int result= expg[indg];
     258  for (int i= indf - 1; i >= 0; i--)
     259  {
     260    if (expf [i]%result != 0)
     261    {
     262      delete [] expg;
     263      delete [] expf;
     264      return 0;
     265    }
     266  }
     267 
     268  for (int i= indg - 1; i >= 0; i--)
     269  {
     270    if (expg [i]%result != 0)
     271    {
     272      delete [] expg;
     273      delete [] expf;
     274      return 0;
     275    }
     276  }
     277
     278  delete [] expg;
     279  delete [] expf;
     280  return result;
     281}
     282
     283// substiution
     284void
     285subst (const CanonicalForm& F, const CanonicalForm& G, CanonicalForm& A,
     286       CanonicalForm& B, const int d
     287      )
     288{
     289  if (d == 1)
     290  {
     291    A= F;
     292    B= G;
     293    return;
     294  }
     295 
     296  CanonicalForm C= 0;
     297  CanonicalForm D= 0; 
     298  Variable x= Variable (1);
     299  CanonicalForm f= swapvar (F, x, F.mvar());
     300  CanonicalForm g= swapvar (G, x, G.mvar());
     301  for (CFIterator i= f; i.hasTerms(); i++)
     302    C += i.coeff()*power (f.mvar(), i.exp()/ d);
     303  for (CFIterator i= g; i.hasTerms(); i++)
     304    D += i.coeff()*power (g.mvar(), i.exp()/ d);
     305  A= swapvar (C, x, F.mvar());
     306  B= swapvar (D, x, G.mvar());
     307}
     308
     309CanonicalForm
     310reverseSubst (const CanonicalForm& F, const int d)
     311{
     312  if (d == 1)
     313    return F;
     314 
     315  Variable x= Variable (1);
     316  if (degree (F, x) <= 0)
     317    return F;
     318  CanonicalForm f= swapvar (F, x, F.mvar());
     319  CanonicalForm result= 0;
     320  for (CFIterator i= f; i.hasTerms(); i++)
     321    result += i.coeff()*power (f.mvar(), d*i.exp());
     322  return swapvar (result, x, F.mvar());   
     323}
     324
     325static inline CanonicalForm
     326uni_content (const CanonicalForm & F);
     327
     328CanonicalForm
     329uni_content (const CanonicalForm& F, const Variable& x)
     330{
     331  if (F.inCoeffDomain())
     332    return F.genOne();
     333  if (F.level() == x.level() && F.isUnivariate())
     334    return F;
     335  if (F.level() != x.level() && F.isUnivariate())
     336    return F.genOne();
     337   
     338  if (x.level() != 1)
     339  {
     340    CanonicalForm f= swapvar (F, x, Variable (1));
     341    CanonicalForm result= uni_content (f);
     342    return swapvar (result, x, Variable (1));
     343  }
     344  else
     345    return uni_content (F);
     346}
     347
    203348/// compute the content of F, where F is considered as an element of
    204349/// \f$ R[x_{1}][x_{2},\ldots ,x_{n}] \f$
     
    231376    return c;
    232377  }
     378}
     379
     380CanonicalForm
     381extractContents (const CanonicalForm& F, const CanonicalForm& G,
     382                 CanonicalForm& contentF, CanonicalForm& contentG,
     383                 CanonicalForm& ppF, CanonicalForm& ppG, const int d)
     384{
     385  CanonicalForm uniContentF, uniContentG, gcdcFcG;
     386  contentF= 1;
     387  contentG= 1;
     388  ppF= F;
     389  ppG= G;
     390  CanonicalForm result= 1;
     391  for (int i= 1; i <= d; i++)
     392  {
     393    uniContentF= uni_content (F, Variable (i));
     394    uniContentG= uni_content (G, Variable (i));
     395    gcdcFcG= gcd (uniContentF, uniContentG);
     396    contentF *= uniContentF;
     397    contentG *= uniContentG;
     398    ppF /= uniContentF;
     399    ppG /= uniContentG;
     400    result *= gcdcFcG;
     401  }
     402  return result;
    233403}
    234404
     
    336506
    337507/// GCD of F and G over \f$ F_{p}(\alpha ) \f$ ,
    338 /// l and top_level are only used internally, output is monic
     508/// l and topLevel are only used internally, output is monic
    339509/// based on Alg. 7.2. as described in "Algorithms for
    340510/// Computer Algebra" by Geddes, Czapor, Labahn
    341511CanonicalForm
    342512GCD_Fp_extension (const CanonicalForm& F, const CanonicalForm& G,
    343                   Variable & alpha, CFList& l, bool& top_level)
     513                  Variable & alpha, CFList& l, bool& topLevel)
    344514{
    345515  CanonicalForm A= F;
     
    354524 
    355525  CFMap M,N;
    356   int best_level= myCompress (A, B, M, N, top_level);
     526  int best_level= myCompress (A, B, M, N, topLevel);
    357527
    358528  if (best_level == 0) return B.genOne();
     
    367537    return N (gcd(A,B));
    368538 
     539  int substitute= substituteCheck (A, B);
     540 
     541  if (substitute > 1)
     542    subst (A, B, A, B, substitute);
     543
    369544  CanonicalForm cA, cB;    // content of A and B
    370545  CanonicalForm ppA, ppB;    // primitive part of A and B
    371546  CanonicalForm gcdcAcB;
    372547
    373   cA = uni_content (A);
    374   cB = uni_content (B);
    375 
    376   gcdcAcB= gcd (cA, cB);
    377 
    378   ppA= A/cA;
    379   ppB= B/cB;
     548  if (topLevel)
     549  {
     550    if (best_level <= 2)
     551      gcdcAcB= extractContents (A, B, cA, cB, ppA, ppB, best_level);
     552    else
     553      gcdcAcB= extractContents (A, B, cA, cB, ppA, ppB, 2); 
     554  }
     555  else
     556  {
     557    cA = uni_content (A);
     558    cB = uni_content (B);
     559    gcdcAcB= gcd (cA, cB);
     560    ppA= A/cA;
     561    ppB= B/cB;
     562  }
    380563
    381564  CanonicalForm lcA, lcB;  // leading coefficients of A and B
     
    385568  lcB= uni_lcoeff (ppB);
    386569 
    387   if (fdivides (lcA, lcB)) {
     570  if (fdivides (lcA, lcB))
     571  {
    388572    if (fdivides (A, B))
    389573      return F/Lc(F);   
     
    399583  int d= totaldegree (ppA, Variable(2), Variable (ppA.level()));
    400584
    401   if (d == 0) return N(gcdcAcB);
     585  if (d == 0)
     586  {
     587    if (substitute > 1)
     588      return N (reverseSubst (gcdcAcB, substitute));
     589    else
     590      return N(gcdcAcB);
     591  }
    402592  int d0= totaldegree (ppB, Variable(2), Variable (ppB.level()));
    403593  if (d0 < d)
    404594    d= d0;
    405   if (d == 0) return N(gcdcAcB);
     595  if (d == 0)
     596  {
     597    if (substitute > 1)
     598      return N (reverseSubst (gcdcAcB, substitute));
     599    else
     600      return N(gcdcAcB);
     601  }
    406602
    407603  CanonicalForm m, random_element, G_m, G_random_element, H, cH, ppH;
     
    413609  H= 0;
    414610  bool fail= false;
    415   top_level= false;
     611  topLevel= false;
    416612  bool inextension= false;
    417613  Variable V_buf= alpha;
     
    461657      G_random_element=
    462658      GCD_Fp_extension (ppA (random_element, x), ppB (random_element, x), V_buf,
    463                         list, top_level);
     659                        list, topLevel);
    464660      TIMING_END_AND_PRINT (gcd_recursion,
    465661                            "time for recursive call: ");
     
    472668      G_random_element=
    473669      GCD_Fp_extension (ppA(random_element, x), ppB(random_element, x), V_buf,
    474                         list, top_level);
     670                        list, topLevel);
    475671      TIMING_END_AND_PRINT (gcd_recursion,
    476672                            "time for recursive call: ");
     
    480676    d0= totaldegree (G_random_element, Variable(2),
    481677                     Variable (G_random_element.level()));
    482     if (d0 == 0) return N(gcdcAcB);
     678    if (d0 == 0)
     679    {
     680      if (substitute > 1)
     681        return N (reverseSubst (gcdcAcB, substitute));
     682      else
     683        return N(gcdcAcB);
     684    }
    483685    if (d0 >  d)
    484686    {
     
    522724        DEBOUTLN (cerr, "ppH after mapDown= " << ppH);
    523725        if (fdivides (ppH, A) && fdivides (ppH, B))         
     726        {
     727          if (substitute > 1)
     728          {
     729            ppH= reverseSubst (ppH, substitute);
     730            gcdcAcB= reverseSubst (gcdcAcB, substitute);
     731          }
    524732          return N(gcdcAcB*ppH);
     733        }
    525734      }
    526735      else if (fdivides (ppH, A) && fdivides (ppH, B))
    527         return N(gcdcAcB*(ppH/Lc(ppH)));
     736      {
     737        if (substitute > 1)
     738        {
     739          ppH= reverseSubst (ppH, substitute);
     740          gcdcAcB= reverseSubst (gcdcAcB, substitute);
     741        }
     742        return N(gcdcAcB*ppH);
     743      }
    528744    }
    529745
     
    580796/// the size of the base field is bounded by 2^16, output is monic
    581797CanonicalForm GCD_GF (const CanonicalForm& F, const CanonicalForm& G,
    582         CFList& l, bool& top_level)
     798        CFList& l, bool& topLevel)
    583799{
    584800  CanonicalForm A= F;
     
    593809 
    594810  CFMap M,N;
    595   int best_level= myCompress (A, B, M, N, top_level);
     811  int best_level= myCompress (A, B, M, N, topLevel);
    596812
    597813  if (best_level == 0) return B.genOne();
     
    606822    return N (gcd (A, B));
    607823
     824  int substitute= substituteCheck (A, B);
     825 
     826  if (substitute > 1)
     827    subst (A, B, A, B, substitute);
     828
    608829  CanonicalForm cA, cB;    // content of A and B
    609830  CanonicalForm ppA, ppB;    // primitive part of A and B
    610831  CanonicalForm gcdcAcB;
    611832
    612   cA = uni_content (A);
    613   cB = uni_content (B);
    614 
    615   gcdcAcB= gcd (cA, cB);
    616 
    617   ppA= A/cA;
    618   ppB= B/cB;
     833  if (topLevel)
     834  {
     835    if (best_level <= 2)
     836      gcdcAcB= extractContents (A, B, cA, cB, ppA, ppB, best_level);
     837    else
     838      gcdcAcB= extractContents (A, B, cA, cB, ppA, ppB, 2); 
     839  }
     840  else
     841  {
     842    cA = uni_content (A);
     843    cB = uni_content (B);
     844    gcdcAcB= gcd (cA, cB);
     845    ppA= A/cA;
     846    ppB= B/cB;
     847  }
    619848
    620849  CanonicalForm lcA, lcB;  // leading coefficients of A and B
     
    638867
    639868  int d= totaldegree (ppA, Variable(2), Variable (ppA.level()));
    640   if (d == 0) return N(gcdcAcB);
     869  if (d == 0)
     870  {
     871    if (substitute > 1)
     872      return N (reverseSubst (gcdcAcB, substitute));
     873    else
     874      return N(gcdcAcB);
     875  }
    641876  int d0= totaldegree (ppB, Variable(2), Variable (ppB.level()));
    642877  if (d0 < d)
    643878    d= d0;
    644   if (d == 0) return N(gcdcAcB);
     879  if (d == 0)
     880  {
     881    if (substitute > 1)
     882      return N (reverseSubst (gcdcAcB, substitute));
     883    else
     884      return N(gcdcAcB);
     885  }
    645886
    646887  CanonicalForm m, random_element, G_m, G_random_element, H, cH, ppH;
     
    652893  H= 0;
    653894  bool fail= false;
    654   top_level= false;
     895  topLevel= false;
    655896  bool inextension= false;
    656897  int p;
     
    694935      TIMING_START (gcd_recursion);
    695936      G_random_element= GCD_GF (ppA(random_element, x), ppB(random_element, x),
    696                                 list, top_level);
     937                                list, topLevel);
    697938      TIMING_END_AND_PRINT (gcd_recursion,
    698939                            "time for recursive call: ");
     
    704945      TIMING_START (gcd_recursion);
    705946      G_random_element= GCD_GF (ppA(random_element, x), ppB(random_element, x),
    706                                 list, top_level);
     947                                list, topLevel);
    707948      TIMING_END_AND_PRINT (gcd_recursion,
    708949                            "time for recursive call: ");
     
    717958      {
    718959        setCharacteristic (p, k, gf_name_buf);
    719         return N(gcdcAcB);
     960        {
     961          if (substitute > 1)
     962            return N (reverseSubst (gcdcAcB, substitute));
     963          else
     964            return N(gcdcAcB);
     965        }
    720966      }
    721967      else
    722         return N(gcdcAcB);
     968      {
     969        if (substitute > 1)
     970          return N (reverseSubst (gcdcAcB, substitute));
     971        else
     972          return N(gcdcAcB);
     973      }
    723974    }
    724975    if (d0 >  d)
     
    7591010          ppH= GFMapDown (ppH, k);
    7601011          DEBOUTLN (cerr, "ppH after mapDown= " << ppH);
     1012          if (substitute > 1)
     1013          {
     1014            ppH= reverseSubst (ppH, substitute);
     1015            gcdcAcB= reverseSubst (gcdcAcB, substitute);
     1016          }
    7611017          setCharacteristic (p, k, gf_name_buf);
    7621018          return N(gcdcAcB*ppH);
     
    7661022      {
    7671023        if (fdivides (ppH, A) && fdivides (ppH, B))
     1024        {
     1025          if (substitute > 1)
     1026          {
     1027            ppH= reverseSubst (ppH, substitute);
     1028            gcdcAcB= reverseSubst (gcdcAcB, substitute);
     1029          }
    7681030          return N(gcdcAcB*ppH);
     1031        }
    7691032      }
    7701033    }
     
    8291092
    8301093CanonicalForm GCD_small_p (const CanonicalForm& F, const CanonicalForm&  G,
    831                            bool& top_level, CFList& l)
     1094                           bool& topLevel, CFList& l)
    8321095{
    8331096  CanonicalForm A= F;
     
    8421105
    8431106  CFMap M,N;
    844   int best_level= myCompress (A, B, M, N, top_level);
     1107  int best_level= myCompress (A, B, M, N, topLevel);
    8451108
    8461109  if (best_level == 0) return B.genOne();
     
    8551118    return N (gcd (A, B));
    8561119
     1120  int substitute= substituteCheck (A, B);
     1121 
     1122  if (substitute > 1)
     1123    subst (A, B, A, B, substitute);
     1124
    8571125  CanonicalForm cA, cB;    // content of A and B
    8581126  CanonicalForm ppA, ppB;    // primitive part of A and B
    8591127  CanonicalForm gcdcAcB;
    860   cA = uni_content (A);
    861   cB = uni_content (B);
    862   gcdcAcB= gcd (cA, cB);
    863   ppA= A/cA;
    864   ppB= B/cB;
     1128
     1129  if (topLevel)
     1130  {
     1131    if (best_level <= 2)
     1132      gcdcAcB= extractContents (A, B, cA, cB, ppA, ppB, best_level);
     1133    else
     1134      gcdcAcB= extractContents (A, B, cA, cB, ppA, ppB, 2); 
     1135  }
     1136  else
     1137  {
     1138    cA = uni_content (A);
     1139    cB = uni_content (B);
     1140    gcdcAcB= gcd (cA, cB);
     1141    ppA= A/cA;
     1142    ppB= B/cB;
     1143  }
    8651144
    8661145  CanonicalForm lcA, lcB;  // leading coefficients of A and B
     
    8851164  int d0;
    8861165
    887   if (d == 0) return N(gcdcAcB);
     1166  if (d == 0)
     1167  {
     1168    if (substitute > 1)
     1169      return N (reverseSubst (gcdcAcB, substitute));
     1170    else
     1171      return N(gcdcAcB);
     1172  }
    8881173  d0= totaldegree (ppB, Variable (2), Variable (ppB.level()));
    8891174
     
    8911176    d= d0;
    8921177
    893   if (d == 0) return N(gcdcAcB);
     1178  if (d == 0)
     1179  {
     1180    if (substitute > 1)
     1181      return N (reverseSubst (gcdcAcB, substitute));
     1182    else
     1183      return N(gcdcAcB);
     1184  }
    8941185
    8951186  CanonicalForm m, random_element, G_m, G_random_element, H, cH, ppH;
     
    8991190  G_m= 0;
    9001191  Variable alpha, V_buf;
    901   int p, k;
    9021192  bool fail= false;
    9031193  bool inextension= false;
    9041194  bool inextensionextension= false;
    905   top_level= false;
    906   CanonicalForm CF_buf;
     1195  topLevel= false;
    9071196  CFList source, dest;
    908   CanonicalForm gcdcheck;
    9091197  do
    9101198  {
     
    9191207      TIMING_START (gcd_recursion);
    9201208      G_random_element=
    921       GCD_small_p (ppA (random_element,x), ppB (random_element,x), top_level,
     1209      GCD_small_p (ppA (random_element,x), ppB (random_element,x), topLevel,
    9221210      list);
    9231211      TIMING_END_AND_PRINT (gcd_recursion,
     
    9311219      G_random_element=
    9321220      GCD_Fp_extension (ppA (random_element, x), ppB (random_element, x), alpha,
    933                         list, top_level);
     1221                        list, topLevel);
    9341222      TIMING_END_AND_PRINT (gcd_recursion,
    9351223                            "time for recursive call: ");
     
    9421230      CFList list;
    9431231      CanonicalForm mipo;
    944       int deg= 3;
     1232      int deg= 2;
    9451233      do {
    9461234        mipo= randomIrredpoly (deg, x);
     
    9551243      G_random_element=
    9561244      GCD_Fp_extension (ppA (random_element, x), ppB (random_element, x), alpha,
    957                         list, top_level);
     1245                        list, topLevel);
    9581246      TIMING_END_AND_PRINT (gcd_recursion,
    9591247                            "time for recursive call: ");
     
    10011289      G_random_element=
    10021290      GCD_Fp_extension (ppA (random_element, x), ppB (random_element, x), V_buf,
    1003                         list, top_level);
     1291                        list, topLevel);
    10041292      TIMING_END_AND_PRINT (gcd_recursion,
    10051293                            "time for recursive call: ");
     
    10131301    if (d0 == 0)
    10141302    {
    1015       return N(gcdcAcB);
     1303      if (substitute > 1)
     1304        return N (reverseSubst (gcdcAcB, substitute));
     1305      else
     1306        return N(gcdcAcB);
    10161307    }
    10171308    if (d0 >  d)
     
    10501341      DEBOUTLN (cerr, "ppH= " << ppH);
    10511342      if (fdivides (ppH, A) && fdivides (ppH, B))
     1343      {
     1344        if (substitute > 1)
     1345        {
     1346          ppH= reverseSubst (ppH, substitute);
     1347          gcdcAcB= reverseSubst (gcdcAcB, substitute);
     1348        }
    10521349        return N(gcdcAcB*ppH);
     1350      }
    10531351    }
    10541352
Note: See TracChangeset for help on using the changeset viewer.