source: git/factory/libfac/charset/csutil.cc @ 5337d7

spielwiese
Last change on this file since 5337d7 was 5337d7, checked in by Martin Lee <martinlee84@…>, 11 years ago
fix: dangling else
  • Property mode set to 100644
File size: 22.6 KB
RevLine 
[1a80b4]1////////////////////////////////////////////////////////////
2// emacs edit mode for this file is -*- C++ -*-
3/////////////////////////////////////////////////////////////
4// FACTORY - Includes
5#include <factory.h>
6// Factor - Includes
7#include <tmpl_inst.h>
8#include <Factor.h>
9#include <SqrFree.h>
[4a81ec]10#include <helpstuff.h>
11#include <homogfactor.h>
[1a80b4]12// Charset - Includes
13#include "csutil.h"
[9b25e7e]14extern void out_cf(char *s1,const CanonicalForm &f,char *s2);
[639047e]15extern CanonicalForm alg_lc(const CanonicalForm &f);
16extern int hasAlgVar(const CanonicalForm &f);
[1a80b4]17
18static bool
[4a81ec]19lowerRank ( const CanonicalForm & f, const CanonicalForm & g, int & ind )
[1a80b4]20{
21  int df, dg;
22  Variable vf = f.mvar(), vg = g.mvar();
[0be2bc]23
[56c5ce7]24  if ( f.inCoeffDomain() )
25  {
[0be2bc]26    if ( g.inCoeffDomain() ) ind= 1;
[4a81ec]27    return true;//( vg > vf );
28  }
29  else if ( g.inCoeffDomain() ) return false;
30  else if ( vf < vg ) return true;
[56c5ce7]31  else if ( vf == vg )
32  {
[4a81ec]33    df = degree( f ); dg = degree( g );
34    if ( df < dg ) return true;
35    else if ( df == dg ) return lowerRank( LC( f ), LC( g ) , ind);
36    else return false;
37  }
[1a80b4]38  return false;
39}
40
41CanonicalForm
42lowestRank( const CFList & F )
43{
44  CFListIterator i = F;
45  CanonicalForm f;
[4a81ec]46  int ind=0;
[0be2bc]47  if ( ! i.hasItem() )        return f;
[1a80b4]48  f = i.getItem(); ++i;
[56c5ce7]49  while ( i.hasItem() )
50  {
[e2ca88]51    //CERR << "comparing " << f << "  and " << i.getItem()
52    // << " == " << lowerRank( i.getItem(), f, ind ) << "\n";
[56c5ce7]53    if ( lowerRank( i.getItem(), f, ind ) )
54    {
55      if ( ind )
56      {
[0be2bc]57        CFList Itemlist= get_Terms(i.getItem());
58        CFList Flist= get_Terms(f);
59
60        // Have to further compare number of terms!
[e2ca88]61        //CERR << "compare terms! f= " << Flist.length() << "  item= "
62        //     << Itemlist.length() <<"\n";
[0be2bc]63        if ( Itemlist.length() < Flist.length()) f = i.getItem();
64        ind=0;
[4a81ec]65      }
[56c5ce7]66      else
67      {
[0be2bc]68        f = i.getItem();
[4a81ec]69      }
70    }
[1a80b4]71    ++i;
72  }
73  return f;
74}
75
76// old version
77// CanonicalForm
78// prem ( const CanonicalForm &f, const CanonicalForm &g )
79// {
80//   CanonicalForm ff, gg, cg;
81//   int df, dg;
82//   bool reord;
83//   Variable vf, vg, v;
84//
85//   if ( (vf = f.mvar()) < (vg = g.mvar()) ) return f;
86//   else {
87//     if ( vf == vg ) {
88//       ff = f; gg = g;
89//       reord = false;
90//       v = vg;
91//     }
[0be2bc]92//     else {
[1a80b4]93//       v = Variable(level(f.mvar()) + 1);
94//       ff = swapvar(f,vg,v);
95//       gg = swapvar(g,vg,v);
96//       reord=true;
97//     }
98//     cg = ini( gg, v );
99//     dg = degree( gg, v );
100//     while ( ( df = degree( ff, v ) ) >= dg )
101//       ff = cg * ff - power( v, df-dg ) * gg * LC( ff, v );
102//     if ( reord ) {
103//       return swapvar( ff, vg, v );
104//     }
105//     else
106//       return ff;
107//   }
108// }
109
110CanonicalForm
[56c5ce7]111Prem ( const CanonicalForm &f, const CanonicalForm &g )
112{
[4a81ec]113  CanonicalForm ff, gg, l, test, lu, lv, t, retvalue;
[1a80b4]114  int df, dg;
115  bool reord;
116  Variable vf, vg, v;
[4a81ec]117
[1a80b4]118  if ( (vf = f.mvar()) < (vg = g.mvar()) ) return f;
[56c5ce7]119  else
120  {
121    if ( vf == vg )
122    {
[1a80b4]123      ff = f; gg = g;
124      reord = false;
125      v = vg;
126    }
[56c5ce7]127    else
128    {
[1a80b4]129      v = Variable(level(f.mvar()) + 1);
130      ff = swapvar(f,vg,v);
131      gg = swapvar(g,vg,v);
132      reord=true;
133    }
134    dg = degree( gg, v );
135    df = degree( ff, v );
136    if (dg <= df) {l=LC(gg); gg = gg -LC(gg)*power(v,dg);}
137    else { l = 1; }
[6f801b]138    while ( ( dg <= df  ) && ( !ff.isZero()) )
[56c5ce7]139    {
[e2ca88]140      // CERR << "Start gcd..." << "\n";
[1a80b4]141      test = gcd(l,LC(ff));
[e2ca88]142      //CERR << "gcd(" << l << "," << LC(ff) << ")= " << test << "\n";
[1a80b4]143      lu = l/test; lv = LC(ff)/test;
144      t = power(v,df-dg) * gg * lv;
145      if ( df == 0 ){ ff = ff.genZero(); }
146      else { ff = ff - LC(ff)*power(v,df); }
147      ff = lu*ff - t;
148      df = degree( ff, v );
149    }
[56c5ce7]150    if ( reord )
151    {
152      retvalue= swapvar( ff, vg, v );
[4a81ec]153    }
[56c5ce7]154    else
155    {
156      retvalue= ff;
[4a81ec]157    }
158    return retvalue;
159  }
160}
161
162static CanonicalForm
[56c5ce7]163Sprem ( const CanonicalForm &f, const CanonicalForm &g, CanonicalForm & m, CanonicalForm & q )
164{
[4a81ec]165  CanonicalForm ff, gg, l, test, retvalue;
166  int df, dg,n;
167  bool reord;
168  Variable vf, vg, v;
169
[56c5ce7]170  if ( (vf = f.mvar()) < (vg = g.mvar()) )
171  {
[0be2bc]172    m=CanonicalForm(0); q=CanonicalForm(0);
[4a81ec]173    return f;
174  }
[56c5ce7]175  else
176  {
177    if ( vf == vg )
178    {
[4a81ec]179      ff = f; gg = g;
180      reord = false;
181      v = vg; // == x
182    }
[56c5ce7]183    else
184    {
[4a81ec]185      v = Variable(level(f.mvar()) + 1);
186      ff = swapvar(f,vg,v); // == r
187      gg = swapvar(g,vg,v); // == v
188      reord=true;
189    }
[0be2bc]190    dg = degree( gg, v ); // == dv
[4a81ec]191    df = degree( ff, v ); // == dr
192    if (dg <= df) {l=LC(gg); gg = gg -LC(gg)*power(v,dg);}
193    else { l = 1; }
194    n= 0;
[6f801b]195    while ( ( dg <= df  ) && ( !ff.isZero()) )
[56c5ce7]196    {
[4a81ec]197      test= power(v,df-dg) * gg * LC(ff);
198      if ( df == 0 ){ff= ff.genZero();}
199      else {ff= ff - LC(ff)*power(v,df);}
200      ff = l*ff-test;
201      df= degree(ff,v);
202      n++;
203    }
[56c5ce7]204    if ( reord )
205    {
206      retvalue= swapvar( ff, vg, v );
[4a81ec]207    }
[56c5ce7]208    else
209    {
210      retvalue= ff;
[4a81ec]211    }
212    m= power(l,n);
[dbcf42a]213    if ( fdivides(g,m*f-retvalue) )
[4a81ec]214      q= (m*f-retvalue)/g;
[56c5ce7]215    else
[4a81ec]216      q= CanonicalForm(0);
217    return retvalue;
[1a80b4]218  }
219}
220
[4a81ec]221CanonicalForm
[38e7b3]222divide( const CanonicalForm & ff, const CanonicalForm & f, const CFList & as)
223{
[4a81ec]224  CanonicalForm r,m,q;
225
[fb4f62e]226  //out_cf("divide f=",ff,"\n");
227  //out_cf("divide g=",f,"\n");
228  if (f.inCoeffDomain())
229  {
[56c5ce7]230    bool b=!isOn(SW_RATIONAL);
231    On(SW_RATIONAL);
[fb4f62e]232    q=ff/f;
233    if (b) Off(SW_RATIONAL);
[56c5ce7]234  }
[fb4f62e]235  else
236    r= Sprem(ff,f,m,q); //result in q, ignore r,m
[e2ca88]237  //CERR << "r= " << r << "  , m= " << m << "  , q= " << q << "\n";
[4a81ec]238  r= Prem(q,as);
[e2ca88]239  //CERR << "r= " << r << "\n";
[fb4f62e]240  //out_cf(" ->",r,"\n");
[4a81ec]241  return r;
242}
243
[56c5ce7]244// This function allows as to be empty; in that case, it is equivalent
245// to the previous version (treating no variables as algebraic).
[4a81ec]246static CanonicalForm
[56c5ce7]247myfitting( const CanonicalForm &f, const CFList &as )
[38e7b3]248{
[4a81ec]249 CanonicalForm rem=f;
250
[38e7b3]251 if ( !(rem.isZero()) )
252 {
[4a81ec]253   if ( getCharacteristic() > 0 )
254     return num((rem/lc(rem)));
[38e7b3]255   else
256   {
[4a81ec]257     On(SW_RATIONAL);
258     CanonicalForm temp= mapinto(rem);
[e2ca88]259//      CERR << "temp= " << temp << "\n";
260//      CERR << "lc(temp)= " << lc(temp) << "\n";
261//      CERR << "temp/lc(temp)= " << temp/lc(temp) << "\n";
262//      CERR << "num(rem/lc(rem))= " << num(rem/lc(rem)) << "\n";
[56c5ce7]263
264     // If as is of length 1, and its polynomial is level 1, then
265     // we treat the first variable as algebraic and invert the leading
266     // coefficient where this variable is part of the coefficient domain.
267
268     if (as.length() == 1 && level(as.getFirst()) == 1)
269     {
270       CanonicalForm lcoeff = temp;
271       while (level(lcoeff) > 1)
272       {
273         lcoeff = LC(lcoeff);
274       }
275       // out_cf("myfitting: lcoeff = ", lcoeff, "\n");
276
277       CanonicalForm p = as.getFirst();
278       // out_cf("myfitting: p = ", p, "\n");
279
280       CanonicalForm unused, inverse;
281
282       extgcd(lcoeff, p, inverse, unused);
283       // out_cf("myfitting: inverse = ", inverse, "\n");
284
285       // This may leave temp with non-integral coefficients,
286       // which will be cleaned up below.
287       temp = temp * inverse;
288       // out_cf("myfitting: temp = ", temp, "\n");
289     }
290
[17ce9d]291     temp= bCommonDen(temp/lc(temp))*(temp/lc(temp));
[4a81ec]292     Off(SW_RATIONAL);
293     rem= mapinto(temp);
294     return rem;
295   }
296 }
297 else
298   return rem;
299}
300
[1a80b4]301CanonicalForm
[56c5ce7]302Prem( const CanonicalForm &f, const CFList &L )
303{
[1a80b4]304  CanonicalForm rem = f;
305  CFListIterator i = L;
[56c5ce7]306  for ( i.lastItem(); i.hasItem(); i-- )
307  {
308    //CERR << "   PREM: Prem(" << rem << "," ;
[1a80b4]309    rem = Prem( rem, i.getItem() );
[56c5ce7]310    //CERR << "   PREM: Prem(" << rem << "," << i.getItem() << ")  = " << rem << "\n";
[1a80b4]311  }
[56c5ce7]312  return myfitting(rem, CFList());
313}
314
315CanonicalForm
316Prem( const CanonicalForm &f, const CFList &L, const CFList &as )
317{
318  CanonicalForm rem = f;
319  CFListIterator i = L;
320  for ( i.lastItem(); i.hasItem(); i-- )
321  {
322    //CERR << "   PREM: Prem(" << rem << "," ;
323    rem = Prem( rem, i.getItem() );
324    //CERR << "   PREM: Prem(" << rem << "," << i.getItem() << ")  = " << rem << "\n";
325  }
326  return myfitting(rem, as);
[1a80b4]327}
328
329CFList
[56c5ce7]330Prem( const CFList &AS, const CFList &L )
331{
[1a80b4]332  CFList Output;
[4a81ec]333
[1a80b4]334  for ( CFListIterator i=AS; i.hasItem(); i++ )
335    Output = Union(CFList(Prem(i.getItem(),L)), Output);
[4a81ec]336
[1a80b4]337  return Output;
338}
339
[4a81ec]340static CanonicalForm
[38e7b3]341premasb( const CanonicalForm & f, const CFList & as)
342{
[4a81ec]343  CanonicalForm remd=f;
344  CFList AS=as;
345
[38e7b3]346  if ( as.length() > 1 )
347  {
[4a81ec]348    AS.removeFirst(); // get rid of first elem
349    CanonicalForm elem;
[38e7b3]350    while ( ! AS.isEmpty() )
351    { // thats true for at least the first iteration
[4a81ec]352      elem= AS.getLast();
353      remd= Prem(remd,elem);
354      AS.removeLast();
355    }
356  }
357  CanonicalForm a,b;
358  if ( mydivremt(remd, as.getFirst(), a,b )){ remd= remd.genZero();}
359  else { remd= Prem(remd, as.getFirst()); }
360
361  return remd;
362}
363
364CFList
[38e7b3]365remsetb( const CFList & ps, const CFList & as)
366{
[4a81ec]367  CFList output;
368  CanonicalForm elem;
[38e7b3]369  for (CFListIterator i=ps; i.hasItem(); i++)
370  {
[4a81ec]371    elem= premasb(i.getItem(),as);
[6f801b]372    if ( !elem.isZero() ) output.append(elem);
[4a81ec]373  }
374  return output;
375}
376
[1a80b4]377// for characteristic sets
378//////////////////////////////////
379// replace the power of factors of polys in as by 1 if any
380static CFList
[38e7b3]381nopower( const CanonicalForm & init )
382{
[1a80b4]383  CFFList sqrfreelist;// = Factorize(init);//SqrFree(init);
384  CFList output;
385  CanonicalForm elem;
386  int count=0;
[0be2bc]387
[1a80b4]388  for ( CFIterator j=init; j.hasTerms(); j++ )
[56c5ce7]389    if (!(j.coeff().isOne()) ) count++;
[1a80b4]390  //  if ( init != 1 ){
[e2ca88]391  //  CERR << "nopower: f is " << init << "\n";
392  //  CERR << "nopower: count is " << count << "\n";}
[1a80b4]393  if ( count > 1 ) sqrfreelist = CFFList( CFFactor(init,1));
[38e7b3]394  else
395  {
[5e1226]396    sqrfreelist = Factorize(init);
[1a80b4]397    //sqrfreelist.removeFirst();
398  }
[38e7b3]399  for ( CFFListIterator i=sqrfreelist; i.hasItem(); i++ )
400  {
[1a80b4]401    elem=i.getItem().factor();
402    if ( cls(elem) > 0 ) output.append(elem);
403  }
404  return output;
405}
406
407// remove the content of polys in PS; add the removed content to
408// Remembern.FS2 ( the set of removed factors )
[0be2bc]409CFList
[d704fa]410removecontent ( const CFList & PS, PremForm & Remembern )
411{
412  CFListIterator i=PS;
413  if ((!i.hasItem()) || ( cls(PS.getFirst()) == 0 )) return PS;
414
[1a80b4]415  CFList output;
416  CanonicalForm cc,elem;
417
[d704fa]418  for (; i.hasItem(); i++)
419  {
[1a80b4]420    elem = i.getItem();
421    cc = content(elem, elem.mvar());
[d704fa]422    if ( cls(cc) > 0 )
423    {
[0be2bc]424      output.append(elem/cc);
425      Remembern.FS2 = Union(CFList(cc), Remembern.FS2);
[1a80b4]426    }
427    else{ output.append(elem); }
428  }
429  return output;
430}
431
432// remove possible factors in Remember.FS1 from poly r
433// Remember.FS2 contains all factors removed before
[0be2bc]434void
[56c5ce7]435removefactor( CanonicalForm & r , PremForm & Remembern)
436{
[1a80b4]437  int test;
438  CanonicalForm a,b,testelem;
439  CFList testlist;
440  int n=level(r);
441  CFListIterator j ;
442
[38e7b3]443  for ( int J=1; J<= n ; J++ )
444  {
[1a80b4]445    testlist.append(CanonicalForm(Variable(J)));
446  }
[0be2bc]447
[4a81ec]448  //  testlist = Union(Remembern.FS1, testlist); // add candidates
[1a80b4]449
450  // remove already removed factors
[38e7b3]451  for ( j = Remembern.FS2 ; j.hasItem(); j++ )
452  {
[1a80b4]453    testelem = j.getItem();
[38e7b3]454    while ( 1 )
455    {
[4a81ec]456      test = mydivremt(r,testelem,a,b);
[6f801b]457      if ( test && b.isZero() ) r = a;
[1a80b4]458      else break;
459    }
460  }
[4a81ec]461
[1a80b4]462  // Let's look if we have other canditates to remove
[38e7b3]463  for ( j = testlist ; j.hasItem(); j++ )
464  {
[1a80b4]465    testelem = j.getItem();
[4a81ec]466//    if ( testelem != r && testelem != r.mvar() ){
[38e7b3]467    if ( testelem != r )
468    {
469      while ( 1 )
470      {
[0be2bc]471        test = divremt(r,testelem,a,b);
[6f801b]472        if ( test && b.isZero() )
[38e7b3]473        {
[0be2bc]474          Remembern.FS2= Union(Remembern.FS2, CFList(testelem));
475          r = a;
476          if ( r == 1 ) break;
477        }
478        else break;
[1a80b4]479      }
480    }
481  }
[e2ca88]482  //  CERR << "Remembern.FS1 = " << Remembern.FS1 << "\n";
483  //  CERR << "Remembern.FS2 = " << Remembern.FS2 << "\n";
[4a81ec]484  //  Remembern.FS1 = Difference(Remembern.FS1, Remembern.FS2);
[e2ca88]485  //  CERR << "  New Remembern.FS1 = " << Remembern.FS1 << "\n";
[1a80b4]486}
487
488
489// all irreducible nonconstant factors of a set of polynomials
490CFList
[38e7b3]491factorps( const CFList &ps )
492{
[1a80b4]493  CFList qs;
494  CFFList q;
495  CanonicalForm elem;
[0be2bc]496
[38e7b3]497  for ( CFListIterator i=ps; i. hasItem(); i++ )
498  {
[5e1226]499    q=Factorize(i.getItem());
[1a80b4]500    q.removeFirst();
[0be2bc]501    // Next can be simplified ( first (already removed) elem in q is the only constant
[38e7b3]502    for ( CFFListIterator j=q; j.hasItem(); j++ )
503    {
[1a80b4]504      elem = j.getItem().factor();
505      if ( getNumVars(elem) > 0 )
[56c5ce7]506        qs= Union(qs, CFList(myfitting(elem, CFList())));
[1a80b4]507    }
508  }
509  return qs;
510}
511
512// the initial of poly f wrt to the order of the variables
513static CanonicalForm
[38e7b3]514inital( const CanonicalForm &f )
515{
[1a80b4]516  CanonicalForm leadcoeff;
517
518  if ( cls(f) == 0 ) {return f.genOne(); }
[38e7b3]519  else
520  {
[1a80b4]521    leadcoeff = LC(f,lvar(f));
[0be2bc]522    //    if ( leadcoeff != 0 )
[56c5ce7]523    return myfitting(leadcoeff, CFList()); //num(leadcoeff/lc(leadcoeff));
[4a81ec]524    //    else return leadcoeff;
[1a80b4]525  }
526}
527
528// the set of all nonconstant factors of initals of polys in as
529// CFList
530// initalset(const CFList &as){
531//   CanonicalForm elem;
532//   CFList is, iss,iniset;
533
534//   for ( CFListIterator i=as ; i.hasItem(); i++ ){
535//     elem = inital(i.getItem());
536//     if ( cls(elem) > 0 ) is.append(elem);
537//   }
538//   iss = factorps(is);
539//   for ( CFListIterator j=iss; j.hasItem();j++ ){
540//     elem = j.getItem();
541//     if ( cls(elem) > 0 ) iniset.append(num(elem/lc(elem)));
542//   }
543//   return iniset;
544// }
545
[fdf28d]546// the set of nonconstant initials of Cset
[1a80b4]547// with certain repeated factors cancelled
548CFList
[56c5ce7]549initalset1(const CFList & Cset)
550{
[1a80b4]551  CFList temp;
552  CFList initals;
553  CanonicalForm init;
554
[56c5ce7]555  for ( CFListIterator i = Cset ; i.hasItem(); i++ )
556  {
[1a80b4]557    initals= nopower( inital(i.getItem()) );
558    //    init= inital(i.getItem());
[56c5ce7]559    for ( CFListIterator j = initals; j.hasItem(); j++)
560    {
[1a80b4]561      init = j.getItem();
562      if ( cls(init) > 0 )
[0be2bc]563        temp= Union(temp, CFList(init));
[1a80b4]564    }
565  }
566  return temp;
567}
568
[fdf28d]569// the set of nonconstant initials of Cset of those polys
[1a80b4]570// not having their cls higher than reducible
571// with certain repeated factors cancelled
572CFList
[56c5ce7]573initalset2(const CFList & Cset, const CanonicalForm & reducible)
574{
[1a80b4]575  CFList temp;
576  CFList initals;
577  CanonicalForm init;
578  int clsred = cls(reducible);
579
[56c5ce7]580  for ( CFListIterator i = Cset ; i.hasItem(); i++ )
581  {
[1a80b4]582    init = i.getItem();
[56c5ce7]583    if ( cls(init) < clsred )
584    {
[1a80b4]585      initals= nopower( inital(init) );
586      //    init= inital(i.getItem());
[56c5ce7]587      for ( CFListIterator j = initals; j.hasItem(); j++)
588      {
[0be2bc]589        init = j.getItem();
590        if ( cls(init) > 0 )
591          temp= Union(temp, CFList(init));
[1a80b4]592      }
593    }
594  }
595  return temp;
596}
597
598//replace the power of factors of poly in CF init by 1 if any
599// and return the sqrfree poly
600// static CanonicalForm
601// nopower1( const CanonicalForm & init ){
602//   CFFList returnlist=Factorize(init);
603//   CanonicalForm elem, test=init.genOne();
604//   for ( CFFListIterator i= returnlist; i.hasItem(); i++){
605//     elem = i.getItem().factor();
606//     if ( cls(elem)>0 ) test *= elem;
607//   }
608//   return test;
609// }
610
611// the sequence of distinct factors of f
[0be2bc]612//CF pfactor( ..... )
[1a80b4]613
[4a81ec]614// //////////////////////////////////////////
615// // for IrrCharSeries
[1a80b4]616
617#ifdef IRRCHARSERIESDEBUG
618#  define DEBUGOUTPUT
619#else
620#  undef DEBUGOUTPUT
621#endif
[d92d71]622#include <libfac/factor/debug.h>
[1a80b4]623// examine the irreducibility of as for IrrCharSeries
624int
[56c5ce7]625irreducible( const CFList & AS)
626{
[1a80b4]627// AS is given by AS = { A1, A2, .. Ar }, d_i = degree(Ai)
628
629// 1) we test: if d_i > 1, d_j =1 for all j<>i, then AS is irreducible.
[56c5ce7]630  bool deg1=true;
631  for ( CFListIterator i = AS ; i.hasItem(); i++ )
632  {
633    if ( degree(i.getItem()) > 1 )
634    {
[1a80b4]635      if ( deg1 ) deg1=0;
636      else return 0; // found 2nd poly with deg > 1
637    }
638  }
639  return 1;
640}
641
642
643// select an item from PS for irras
644CFList
[56c5ce7]645select( const ListCFList & PS)
646{
[1a80b4]647  return PS.getFirst();
648}
649
650// divide list ppi in elems having length <= and > length
651void
[56c5ce7]652select( const ListCFList & ppi, int length, ListCFList & ppi1, ListCFList & ppi2)
653{
[1a80b4]654  CFList elem;
[56c5ce7]655  for ( ListCFListIterator i=ppi ; i.hasItem(); i++ )
656  {
[1a80b4]657    elem = i.getItem();
658    if ( ! elem.isEmpty() )
[5337d7]659    {
[1a80b4]660      if ( length <= elem.length() ){ ppi2.append(elem); }
661      else { ppi1.append(elem); }
[5337d7]662    }
[1a80b4]663  }
664}
665
666
667//////////////////////////////////////////////////////////////
668// help-functions for sets
669
670// is f in F ?
671static bool
[56c5ce7]672member( const CanonicalForm &f, const CFList &F)
673{
[1a80b4]674  for ( CFListIterator i=F; i.hasItem(); i++ )
675    if ( i.getItem() == f ) return 1;
676  return 0;
677}
678
679// are list A and B the same?
680bool
[56c5ce7]681same( const CFList &A, const CFList &B )
682{
[1a80b4]683  CFListIterator i;
684
685  for (i = A; i.hasItem(); i++)
686    if (! member(i.getItem(), B) )  return 0;
687  for (i = B; i.hasItem(); i++)
688    if (! member(i.getItem(), A) )  return 0;
689  return 1;
690}
691
692
693// is List cs contained in List of lists pi?
694bool
[56c5ce7]695member( const CFList & cs, const ListCFList & pi )
696{
[1a80b4]697  ListCFListIterator i;
698  CFList elem;
699
[56c5ce7]700  for ( i=pi; i.hasItem(); i++)
701  {
[1a80b4]702    elem = i.getItem();
703    if ( same(cs,elem) ) return 1;
704  }
705  return 0;
706}
707
[fdf28d]708// is PS a subset of Cset ?
[1a80b4]709bool
[56c5ce7]710subset( const CFList &PS, const CFList &Cset )
711{
[fdf28d]712  //  CERR << "subset: called with: " << PS << "   " << Cset << "\n";
[1a80b4]713  for ( CFListIterator i=PS; i.hasItem(); i++ )
[56c5ce7]714    if ( ! member(i.getItem(), Cset) )
715    {
[fdf28d]716      //      CERR << "subset: " << i.getItem() << "  is not a member of " << Cset << "\n";
[1a80b4]717      return 0;
718    }
719  return 1;
720}
721
722// Union of two List of Lists
723ListCFList
[56c5ce7]724MyUnion( const ListCFList & a, const ListCFList &b )
725{
[1a80b4]726  ListCFList output;
727  ListCFListIterator i;
728  CFList elem;
[0be2bc]729
[56c5ce7]730  for ( i = a ; i.hasItem(); i++ )
731  {
[1a80b4]732    elem=i.getItem();
[56c5ce7]733    if ( (! elem.isEmpty()) && ( ! member(elem,output)) )
734    {
[1a80b4]735      output.append(elem);
736    }
737  }
[0be2bc]738
[56c5ce7]739  for ( i = b ; i.hasItem(); i++ )
740  {
[1a80b4]741    elem=i.getItem();
[56c5ce7]742    if ( (! elem.isEmpty()) && ( ! member(elem,output)) )
743    {
[1a80b4]744      output.append(elem);
745    }
746  }
747  return output;
748}
749
750//if list b is member of the list of lists remove b and return the rest
751ListCFList
[56c5ce7]752MyDifference( const ListCFList & a, const CFList &b)
753{
[1a80b4]754  ListCFList output;
755  ListCFListIterator i;
756  CFList elem;
757
[56c5ce7]758  for ( i = a ; i.hasItem(); i++ )
759  {
[1a80b4]760    elem=i.getItem();
[56c5ce7]761    if ( (! elem.isEmpty()) && ( ! same(elem,b)) )
762    {
[1a80b4]763      output.append(elem);
764    }
765  }
766return output;
767}
768
769// remove all elements of b from list of lists a and return the rest
770ListCFList
[56c5ce7]771Minus( const ListCFList & a, const ListCFList & b)
772{
[1a80b4]773  ListCFList output=a;
774
775  for ( ListCFListIterator i=b; i.hasItem(); i++ )
776    output = MyDifference(output, i.getItem() );
777
778  return output;
779}
780
[639047e]781#if 0
782static CanonicalForm alg_lc(const CanonicalForm &f, const CFList as)
783{
784  for(CFListIterator i=as; i.hasItem(); i++)
785  {
786    if (f.mvar()==i.getItem().mvar()) return f;
[9b25e7e]787  }
[639047e]788  if (f.level()>0)
789  {
790    return alg_lc(f.LC(),as);
791  }
792  return CanonicalForm(1);
793}
794#endif
795
796CanonicalForm alg_gcd(const CanonicalForm & fff, const CanonicalForm &ggg,
797                      const CFList &as)
798{
799  CanonicalForm f=fff;
800  CanonicalForm g=ggg;
[9b25e7e]801  f=Prem(f,as);
802  g=Prem(g,as);
803  if ( f.isZero() )
804  {
805    if ( g.lc().sign() < 0 ) return -g;
806    else                     return g;
807  }
808  else  if ( g.isZero() )
809  {
810    if ( f.lc().sign() < 0 ) return -f;
811    else                     return f;
812  }
813  //out_cf("alg_gcd(",fff," , ");
814  //out_cf("",ggg,")\n");
[639047e]815  CanonicalForm res;
816  // does as appear in f and g ?
817  bool has_alg_var=false;
818  for ( CFListIterator j=as;j.hasItem(); j++ )
819  {
820    Variable v=j.getItem().mvar();
[9b25e7e]821    if (hasVar(f,v)) {has_alg_var=true; /*break;*/}
822    if (hasVar(g,v)) {has_alg_var=true; /*break;*/}
823    //out_cf("as:",j.getItem(),"\n");
824  }
[639047e]825  if (!has_alg_var)
826  {
827    if ((hasAlgVar(f))
828    || (hasAlgVar(g)))
829    {
830      Varlist ord;
831      for ( CFListIterator j=as;j.hasItem(); j++ )
832        ord.append(j.getItem().mvar());
833      res=algcd(f,g,as,ord);
834    }
835    else
836      res=gcd(f,g);
837    //out_cf("gcd=",res,"\n");
[9b25e7e]838    //out_cf("of f=",fff," , ");
839    //out_cf("and g=",ggg,"\n");
840
[639047e]841    return res;
[9b25e7e]842  }
[639047e]843
844  int mvf=f.level();
845  int mvg=g.level();
846  if (mvg > mvf)
[9b25e7e]847  {
[639047e]848    CanonicalForm tmp=f; f=g; g=tmp;
849    int tmp2=mvf; mvf=mvg; mvg=tmp2;
[9b25e7e]850  }
[639047e]851  if (g.inBaseDomain() || f.inBaseDomain())
852  {
853    //printf("const\n");
[9b25e7e]854    //out_cf("of f=",fff," , ");
855    //out_cf("and g=",ggg,"\n");
[639047e]856    return CanonicalForm(1);
[9b25e7e]857  }
858
[639047e]859  // gcd of all coefficients:
860  CFIterator i=f;
861  CanonicalForm c_gcd=i.coeff(); i++;
862  while( i.hasTerms())
863  {
864    c_gcd=alg_gcd(i.coeff(),c_gcd,as);
865    if (c_gcd.inBaseDomain()) break;
866    i++;
867  }
868  //printf("f.mvar=%d (%d), g.mvar=%d (%d)\n",f.level(),mvf,g.level(),mvg);
869  if (mvf!=mvg) // => mvf > mvg
870  {
871    res=alg_gcd(g,c_gcd,as);
872    //out_cf("alg_gcd1=",res,"\n");
[9b25e7e]873    //out_cf("of f=",fff," , ");
874    //out_cf("and g=",ggg,"\n");
[639047e]875    return res;
876  }
[9b25e7e]877  // now: mvf==mvg, f.level()==g.level()
[639047e]878  if (!c_gcd.inBaseDomain())
879  {
880    i=g;
881    while( i.hasTerms())
882    {
883      c_gcd=alg_gcd(i.coeff(),c_gcd,as);
884      if (c_gcd.inBaseDomain()) break;
885      i++;
886    }
[9b25e7e]887  }
[639047e]888
[fb4f62e]889  //f/=c_gcd;
890  //g/=c_gcd;
891  if (!c_gcd.isOne())
[56c5ce7]892  {
[fb4f62e]893    f=divide(f,c_gcd,as);
894    g=divide(g,c_gcd,as);
895  }
[639047e]896
897  CFList gg;
[9b25e7e]898  CanonicalForm r=1;
899  while (1)
[639047e]900  {
901    //printf("f.mvar=%d, g.mvar=%d\n",f.level(),g.level());
902    gg=as;
[9b25e7e]903    if (!g.inCoeffDomain()) gg.append(g);
[639047e]904    //out_cf("Prem(",f," , ");
905    //out_cf("",g,")\n");
[9b25e7e]906    if (g.inCoeffDomain()|| g.isZero())
907    {
908      //printf("in coeff domain:");
909      if (g.isZero()) { //printf("0\n");
910        i=f;
911        CanonicalForm f_gcd=i.coeff(); i++;
912        while( i.hasTerms())
913        {
914          f_gcd=alg_gcd(i.coeff(),f_gcd,as);
915          if (f_gcd.inBaseDomain()) break;
916          i++;
[56c5ce7]917        }
918        //out_cf("g=0 -> f:",f,"\n");
919        //out_cf("f_gcd:",f_gcd,"\n");
920        //out_cf("c_gcd:",c_gcd,"\n");
921        //f/=f_gcd;
922        f=divide(f,f_gcd,as);
923        //out_cf("f/f_gcd:",f,"\n");
924        f*=c_gcd;
925        //out_cf("f*c_gcd:",f,"\n");
[fb4f62e]926        CanonicalForm r_lc=alg_lc(f);
[56c5ce7]927        //out_cf("r_lc:",r_lc,"\n");
928        //f/=r_lc;
929        f=divide(f,r_lc,as);
930        //out_cf(" -> gcd:",f,"\n");
[fb4f62e]931        return f;
[9b25e7e]932      }
[56c5ce7]933      else { //printf("c\n");
934        return c_gcd;}
935    }
936    else if (g.level()==f.level()) r=Prem(f,gg,as);
[639047e]937    else
938    {
[9b25e7e]939      //printf("diff. level: %d, %d\n", f.level(), g.level());
[639047e]940      // g and f have different levels
[9b25e7e]941      //out_cf("c_gcd=",c_gcd,"\n");
942    //out_cf("of f=",fff," , ");
943    //out_cf("and g=",ggg,"\n");
944      return c_gcd;
[639047e]945    }
946    //out_cf("->",r,"\n");
947    f=g;
948    g=r;
949  }
[9b25e7e]950  if (degree(f,Variable(mvg))==0)
[639047e]951  {
952  // remark: mvf == mvg == f.level() ==g.level()
953    //out_cf("c_gcd=",c_gcd,"\n");
[9b25e7e]954    //out_cf("of f=",fff," , ");
955    //out_cf("and g=",ggg,"\n");
[639047e]956    return c_gcd;
[9b25e7e]957  }
[639047e]958  //out_cf("f=",f,"\n");
959  i=f;
960  CanonicalForm k=i.coeff(); i++;
961  //out_cf("k=",k,"\n");
962  while( i.hasTerms())
963  {
964    if (k.inCoeffDomain()) break;
965    k=alg_gcd(i.coeff(),k,as);
966    //out_cf("k=",k,"\n");
967    i++;
968  }
[9b25e7e]969  //out_cf("end-k=",k,"\n");
[639047e]970  f/=k;
[9b25e7e]971  //out_cf("f/k=",f,"\n");
[639047e]972  res=c_gcd*f;
973  CanonicalForm r_lc=alg_lc(res);
974  res/=r_lc;
975  //CanonicalForm r_lc=alg_lc(res,as);
976  //res/=r_lc;
977  //out_cf("alg_gcd2=",res,"\n");
[9b25e7e]978  //  out_cf("of f=",fff," , ");
979  //  out_cf("and g=",ggg,"\n");
980  //return res;
981  //if (res.level()<fff.level() && res.level() < ggg.level())
982  //  return alg_gcd(alg_gcd(fff,res,as),ggg,as);
983  //else
984    return res;
[639047e]985}
Note: See TracBrowser for help on using the repository browser.