Changeset 4a05ed in git


Ignore:
Timestamp:
Jul 28, 2011, 10:18:43 AM (12 years ago)
Author:
Martin Lee <martinlee84@…>
Branches:
(u'jengelh-datetime', 'ceac47cbc86fe4a15902392bdbb9bd2ae0ea02c6')(u'spielwiese', 'a800fe4b3e9d37a38c5a10cc0ae9dfa0c15a4ee6')
Children:
9b2c8a555e7d7ece9071e76ad8ec4d78ea3b9f01
Parents:
41b5c0dddd342e89c06e4c8949e8da57bf5031ca
Message:
added modular solving of diophantine equation for Hensel lifting over Q(a)
reduce result of tryExtgcd modulo minimal polynomial


git-svn-id: file:///usr/local/Singular/svn/trunk@14354 2c84dea3-7e68-4137-9b89-c4e89433aadc
Location:
factory
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • factory/algext.cc

    r41b5c0 r4a05ed  
    825825    {
    826826      s*=inv;
     827      s= reduce (s, M);
    827828      t*=inv;
     829      t= reduce (t, M);
    828830      result *= inv; // monify result
     831      result= reduce (result, M);
    829832      return;
    830833    }
     
    946949  result = reduce(result, M);
    947950  divides = true;
     951}
     952
     953void tryExtgcd( const CanonicalForm & F, const CanonicalForm & G, CanonicalForm & result, CanonicalForm & s, CanonicalForm & t, bool & fail )
     954{
     955  // F, G are univariate polynomials (i.e. they have exactly one polynomial variable)
     956  // F and G must have the same level AND level > 0
     957  // we try to calculate gcd(f,g) = s*F + t*G
     958  // if a zero divisor is encontered, 'fail' is set to one
     959  Variable a, b;
     960  if( !hasFirstAlgVar(F,a) && !hasFirstAlgVar(G,b) ) // note lazy evaluation
     961  {
     962    result = extgcd( F, G, s, t ); // no zero divisors possible
     963    return;
     964  }
     965  if( b.level() > a.level() )
     966    a = b;
     967  // here: a is the biggest alg. var in F and G
     968  CanonicalForm M = getMipo(a);
     969  CanonicalForm P;
     970  if( degree(F) > degree(G) )
     971  {
     972    P=F; result=G; s=0; t=1;
     973  }
     974  else
     975  {
     976    P=G; result=F; s=1; t=0;
     977  }
     978  CanonicalForm inv, rem, q, u, v;
     979  // here: degree(P) >= degree(result)
     980  while(true)
     981  {
     982    tryInvert( Lc(result), M, inv, fail );
     983    if(fail)
     984      return;
     985    // here: Lc(result) is invertible modulo M
     986    q = Lc(P)*inv * power( P.mvar(), degree(P)-degree(result) );
     987    rem = P - q*result;
     988    // here: s*F + t*G = result
     989    if( rem.isZero() )
     990    {
     991      s*=inv;
     992      t*=inv;
     993      result *= inv; // monify result
     994      return;
     995    }
     996    P=result;
     997    result=rem;
     998    rem=u-q*s;
     999    u=s;
     1000    s=rem;
     1001    rem=v-q*t;
     1002    v=t;
     1003    t=rem;
     1004  }
    9481005}
    9491006
     
    10681125}
    10691126
    1070 
    1071 void tryExtgcd( const CanonicalForm & F, const CanonicalForm & G, CanonicalForm & result, CanonicalForm & s, CanonicalForm & t, bool & fail )
    1072 {
    1073   // F, G are univariate polynomials (i.e. they have exactly one polynomial variable)
    1074   // F and G must have the same level AND level > 0
    1075   // we try to calculate gcd(f,g) = s*F + t*G
    1076   // if a zero divisor is encontered, 'fail' is set to one
    1077   Variable a, b;
    1078   if( !hasFirstAlgVar(F,a) && !hasFirstAlgVar(G,b) ) // note lazy evaluation
    1079   {
    1080     result = extgcd( F, G, s, t ); // no zero divisors possible
    1081     return;
    1082   }
    1083   if( b.level() > a.level() )
    1084     a = b;
    1085   // here: a is the biggest alg. var in F and G
    1086   CanonicalForm M = getMipo(a);
    1087   CanonicalForm P;
    1088   if( degree(F) > degree(G) )
    1089   {
    1090     P=F; result=G; s=0; t=1;
    1091   }
    1092   else
    1093   {
    1094     P=G; result=F; s=1; t=0;
    1095   }
    1096   CanonicalForm inv, rem, q, u, v;
    1097   // here: degree(P) >= degree(result)
    1098   while(true)
    1099   {
    1100     tryInvert( Lc(result), M, inv, fail );
    1101     if(fail)
    1102       return;
    1103     // here: Lc(result) is invertible modulo M
    1104     q = Lc(P)*inv * power( P.mvar(), degree(P)-degree(result) );
    1105     rem = P - q*result;
    1106     // here: s*F + t*G = result
    1107     if( rem.isZero() )
    1108     {
    1109       s*=inv;
    1110       t*=inv;
    1111       result *= inv; // monify result
    1112       return;
    1113     }
    1114     P=result;
    1115     result=rem;
    1116     rem=u-q*s;
    1117     u=s;
    1118     s=rem;
    1119     rem=v-q*t;
    1120     v=t;
    1121     t=rem;
    1122   }
    1123 }
  • factory/algext.h

    r41b5c0 r4a05ed  
    1515bool hasFirstAlgVar( const CanonicalForm &, Variable & );
    1616void tryBrownGCD( const CanonicalForm & F, const CanonicalForm & G, const CanonicalForm & M, CanonicalForm & result, bool & fail, bool topLevel= true );
    17 void tryExtgcd( const CanonicalForm & F, const CanonicalForm & G, CanonicalForm & result, CanonicalForm & s, CanonicalForm & t, bool & fail );
     17void tryExtgcd( const CanonicalForm & F, const CanonicalForm & G, const CanonicalForm& M, CanonicalForm & result, CanonicalForm & s, CanonicalForm & t, bool & fail );
    1818int * leadDeg(const CanonicalForm & f, int *degs);
    1919bool isLess(int *a, int *b, int lower, int upper);
  • factory/facHensel.cc

    r41b5c0 r4a05ed  
    2828#include "fac_util.h"
    2929#include "cf_algorithm.h"
     30#include "cf_primes.h"
    3031
    3132#ifdef HAVE_NTL
    3233#include <NTL/lzz_pEX.h>
    3334#include "NTLconvert.h"
     35
     36static
     37CFList productsNTL (const CFList& factors, const CanonicalForm& M)
     38{
     39  zz_p::init (getCharacteristic());
     40  zz_pX NTLMipo= convertFacCF2NTLzzpX (M);
     41  zz_pE::init (NTLMipo);
     42  zz_pEX prod;
     43  vec_zz_pEX v;
     44  v.SetLength (factors.length());
     45  int j= 0;
     46  for (CFListIterator i= factors; i.hasItem(); i++, j++)
     47  {
     48    if (i.getItem().inCoeffDomain())
     49      v[j]= to_zz_pEX (to_zz_pE (convertFacCF2NTLzzpX (i.getItem())));
     50    else
     51      v[j]= convertFacCF2NTLzz_pEX (i.getItem(), NTLMipo);
     52  }
     53  CFList result;
     54  Variable x= Variable (1);
     55  for (int j= 0; j < factors.length(); j++)
     56  {
     57    int k= 0;
     58    set(prod);
     59    for (int i= 0; i < factors.length(); i++, k++)
     60    {
     61      if (k == j)
     62        continue;
     63      prod *= v[i];
     64    }
     65    result.append (convertNTLzz_pEX2CF (prod, x, M.mvar()));
     66  }
     67  return result;
     68}
     69
     70static
     71void tryDiophantine (CFList& result, const CanonicalForm& F,
     72                     const CFList& factors, const CanonicalForm& M, bool& fail)
     73{
     74  ASSERT (M.isUnivariate(), "expected univariate poly");
     75
     76  CFList bufFactors= factors;
     77  bufFactors.removeFirst();
     78  bufFactors.insert (factors.getFirst () (0,2));
     79  CanonicalForm inv, leadingCoeff= Lc (F);
     80  CFListIterator i= bufFactors;
     81  if (bufFactors.getFirst().inCoeffDomain())
     82  {
     83    if (i.hasItem())
     84      i++;
     85  }
     86  for (; i.hasItem(); i++)
     87  {
     88    tryInvert (Lc (i.getItem()), M, inv ,fail);
     89    if (fail)
     90      return;
     91    i.getItem()= reduce (i.getItem()*inv, M);
     92  }
     93  bufFactors= productsNTL (bufFactors, M);
     94
     95  CanonicalForm buf1, buf2, buf3, S, T;
     96  i= bufFactors;
     97  if (i.hasItem())
     98    i++;
     99  buf1= bufFactors.getFirst();
     100  buf2= i.getItem();
     101  tryExtgcd (buf1, buf2, M, buf3, S, T, fail);
     102  if (fail)
     103    return;
     104  result.append (S);
     105  result.append (T);
     106  if (i.hasItem())
     107    i++;
     108  for (; i.hasItem(); i++)
     109  {
     110    buf1= i.getItem();
     111    CanonicalForm bb= buf3;
     112    tryExtgcd (buf3, buf1, M, buf3, S, T, fail);
     113    if (fail)
     114      return;
     115    CFListIterator k= factors;
     116    for (CFListIterator j= result; j.hasItem(); j++, k++)
     117    {
     118      j.getItem() *= S;
     119      CanonicalForm q;
     120      j.getItem()= mod (j.getItem(), k.getItem());
     121      j.getItem()= reduce (j.getItem(), M);
     122    }
     123    result.append (T);
     124  }
     125}
     126
     127static inline
     128CFList mapinto (const CFList& L)
     129{
     130  CFList result;
     131  for (CFListIterator i= L; i.hasItem(); i++)
     132    result.append (mapinto (i.getItem()));
     133  return result;
     134}
     135
     136static inline
     137int mod (const CFList& L, const CanonicalForm& p)
     138{
     139  for (CFListIterator i= L; i.hasItem(); i++)
     140  {
     141    if (mod (i.getItem(), p) == 0)
     142      return 0;
     143  }
     144  return 1;
     145}
     146
     147
     148static inline void
     149chineseRemainder (const CFList & x1, const CanonicalForm & q1,
     150                  const CFList & x2, const CanonicalForm & q2,
     151                  CFList & xnew, CanonicalForm & qnew)
     152{
     153  ASSERT (x1.length() == x2.length(), "expected lists of equal length");
     154  CanonicalForm tmp1, tmp2;
     155  CFListIterator j= x2;
     156  for (CFListIterator i= x1; i.hasItem() && j.hasItem(); i++, j++)
     157  {
     158    chineseRemainder (i.getItem(), q1, j.getItem(), q2, tmp1, tmp2);
     159    xnew.append (tmp1);
     160  }
     161  qnew= tmp2;
     162}
     163
     164static inline
     165CFList Farey (const CFList& L, const CanonicalForm& q)
     166{
     167  CFList result;
     168  for (CFListIterator i= L; i.hasItem(); i++)
     169    result.append (Farey (i.getItem(), q));
     170  return result;
     171}
     172
     173static inline
     174CFList replacevar (const CFList& L, const Variable& a, const Variable& b)
     175{
     176  CFList result;
     177  for (CFListIterator i= L; i.hasItem(); i++)
     178    result.append (replacevar (i.getItem(), a, b));
     179  return result;
     180}
     181
     182CFList
     183modularDiophant (const CanonicalForm& f, const CFList& factors,
     184                 const CanonicalForm& M)
     185{
     186  bool save_rat=!isOn (SW_RATIONAL);
     187  On (SW_RATIONAL);
     188  CanonicalForm F= f*bCommonDen (f);
     189  CFList products= factors;
     190  for (CFListIterator i= products; i.hasItem(); i++)
     191    i.getItem() *= bCommonDen (i.getItem());
     192  if (products.getFirst().level() == 1)
     193    products.insert (Lc (F));
     194  CanonicalForm bound= maxNorm (F);
     195  CFList leadingCoeffs;
     196  leadingCoeffs.append (lc (F));
     197  CanonicalForm dummy;
     198  for (CFListIterator i= products; i.hasItem(); i++)
     199  {
     200    leadingCoeffs.append (lc (i.getItem()));
     201    dummy= maxNorm (i.getItem());
     202    bound= (dummy > bound) ? dummy : bound;
     203  }
     204  bound *= maxNorm (Lc (F))*maxNorm (Lc(F))*bound;
     205  bound *= bound*bound;
     206  bound= power (bound, degree (M));
     207  bound *= power (CanonicalForm (2),degree (f));
     208  CanonicalForm bufBound= bound;
     209  int i = cf_getNumBigPrimes() - 1;
     210  int p;
     211  CFList resultModP, result, newResult;
     212  CanonicalForm q (0), newQ;
     213  bool fail= false;
     214  Variable a= M.mvar();
     215  Variable b= Variable (2);
     216  setReduce (M.mvar(), false);
     217  CanonicalForm mipo= bCommonDen (M)*M;
     218  Off (SW_RATIONAL);
     219  CanonicalForm modMipo;
     220  leadingCoeffs.append (lc (mipo));
     221  CFList tmp1, tmp2;
     222  bool equal= false;
     223  int count= 0;
     224  do
     225  {
     226    p = cf_getBigPrime( i );
     227    i--;
     228    while ( i >= 0 && mod( leadingCoeffs, p ) == 0)
     229    {
     230      p = cf_getBigPrime( i );
     231      i--;
     232    }
     233
     234    ASSERT (i >= 0, "ran out of primes"); //sic
     235
     236    setCharacteristic (p);
     237    modMipo= mapinto (mipo);
     238    modMipo /= lc (modMipo);
     239    resultModP= CFList();
     240    tryDiophantine (resultModP, mapinto (F), mapinto (products), modMipo, fail);
     241    setCharacteristic (0);
     242    if (fail)
     243    {
     244      fail= false;
     245      continue;
     246    }
     247
     248    if ( q.isZero() )
     249    {
     250      result= replacevar (mapinto(resultModP), a, b);
     251      q= p;
     252    }
     253    else
     254    {
     255      result= replacevar (result, a, b);
     256      newResult= CFList();
     257      chineseRemainder( result, q, replacevar (mapinto (resultModP), a, b),
     258                        p, newResult, newQ );
     259      q= newQ;
     260      result= newResult;
     261      if (newQ > bound)
     262      {
     263        count++;
     264        tmp1= replacevar (Farey (result, q), b, a);
     265        if (tmp2.isEmpty())
     266          tmp2= tmp1;
     267        else
     268        {
     269          equal= true;
     270          CFListIterator k= tmp1;
     271          for (CFListIterator j= tmp2; j.hasItem(); j++, k++)
     272          {
     273            if (j.getItem() != k.getItem())
     274              equal= false;
     275          }
     276          if (!equal)
     277            tmp2= tmp1;
     278        }
     279        if (count > 2)
     280        {
     281          bound *= bufBound;
     282          equal= false;
     283          count= 0;
     284        }
     285      }
     286      if (newQ > bound && equal)
     287      {
     288        On( SW_RATIONAL );
     289        result= tmp2;
     290        CFList bufResult= result;
     291        setReduce (M.mvar(), true);
     292        if (factors.getFirst().level() == 1)
     293        {
     294          result.removeFirst();
     295          CFListIterator j= factors;
     296          CanonicalForm denf= bCommonDen (f);
     297          for (CFListIterator i= result; i.hasItem(); i++, j++)
     298            i.getItem() *= Lc (j.getItem())*denf;
     299        }
     300        if (factors.getFirst().level() != 1 &&
     301            !bCommonDen (factors.getFirst()).isOne())
     302        {
     303          CanonicalForm denFirst= bCommonDen (factors.getFirst());
     304          for (CFListIterator i= result; i.hasItem(); i++)
     305            i.getItem() *= denFirst;
     306        }
     307
     308        CanonicalForm test= 0;
     309        CFListIterator jj= factors;
     310        for (CFListIterator ii= result; ii.hasItem(); ii++, jj++)
     311          test += ii.getItem()*(f/jj.getItem());
     312        if (!test.isOne())
     313        {
     314          bound *= bufBound;
     315          equal= false;
     316          count= 0;
     317          setReduce (M.mvar(), false);
     318          result= bufResult;
     319          Off (SW_RATIONAL);
     320        }
     321        else
     322          break;
     323      }
     324    }
     325  } while (1);
     326  if (save_rat) Off(SW_RATIONAL);
     327  return result;
     328}
    34329
    35330CanonicalForm
     
    14521747CFList diophantine (const CanonicalForm& F, const CFList& factors)
    14531748{
     1749  if (getCharacteristic() == 0)
     1750  {
     1751    Variable v;
     1752    bool hasAlgVar= hasFirstAlgVar (F, v);
     1753    for (CFListIterator i= factors; i.hasItem() && !hasAlgVar; i++)
     1754      hasAlgVar= hasFirstAlgVar (i.getItem(), v);
     1755    if (hasAlgVar)
     1756    {
     1757      CFList result= modularDiophant (F, factors, getMipo (v));
     1758      return result;
     1759    }
     1760  }
     1761
    14541762  CanonicalForm buf1, buf2, buf3, S, T;
    14551763  CFListIterator i= factors;
     
    24542762  CFList bufFactors2= factors;
    24552763  bufFactors2.removeFirst();
    2456   diophant.removeFirst();
    2457   CFListIterator iter= diophant;
    24582764  CanonicalForm s,t;
    24592765  extgcd (bufFactors2.getFirst(), bufFactors2.getLast(), s, t);
Note: See TracChangeset for help on using the changeset viewer.