source: git/factory/libfac/charset/csutil.cc @ 0b6efd

spielwiese
Last change on this file since 0b6efd was 0b6efd, checked in by Martin Lee <martinlee84@…>, 10 years ago
chg: use primitive psr gcd
  • Property mode set to 100644
File size: 21.2 KB
Line 
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>
10#include <helpstuff.h>
11#include <homogfactor.h>
12// Charset - Includes
13#include "csutil.h"
14extern void out_cf(const char *s1,const CanonicalForm &f,const char *s2);
15extern CanonicalForm alg_lc(const CanonicalForm &f);
16extern int hasAlgVar(const CanonicalForm &f);
17
18static bool
19lowerRank ( const CanonicalForm & f, const CanonicalForm & g, int & ind )
20{
21  int df, dg;
22  Variable vf = f.mvar(), vg = g.mvar();
23
24  if ( f.inCoeffDomain() )
25  {
26    if ( g.inCoeffDomain() ) ind= 1;
27    return true;//( vg > vf );
28  }
29  else if ( g.inCoeffDomain() ) return false;
30  else if ( vf < vg ) return true;
31  else if ( vf == vg )
32  {
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  }
38  return false;
39}
40
41CanonicalForm
42lowestRank( const CFList & F )
43{
44  CFListIterator i = F;
45  CanonicalForm f;
46  int ind=0;
47  if ( ! i.hasItem() )        return f;
48  f = i.getItem(); ++i;
49  while ( i.hasItem() )
50  {
51    //CERR << "comparing " << f << "  and " << i.getItem()
52    // << " == " << lowerRank( i.getItem(), f, ind ) << "\n";
53    if ( lowerRank( i.getItem(), f, ind ) )
54    {
55      if ( ind )
56      {
57        CFList Itemlist= get_Terms(i.getItem());
58        CFList Flist= get_Terms(f);
59
60        // Have to further compare number of terms!
61        //CERR << "compare terms! f= " << Flist.length() << "  item= "
62        //     << Itemlist.length() <<"\n";
63        if ( Itemlist.length() < Flist.length()) f = i.getItem();
64        ind=0;
65      }
66      else
67      {
68        f = i.getItem();
69      }
70    }
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//     }
92//     else {
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
111Prem ( const CanonicalForm &f, const CanonicalForm &g )
112{
113  CanonicalForm ff, gg, l, test, lu, lv, t, retvalue;
114  int df, dg;
115  bool reord;
116  Variable vf, vg, v;
117
118  if ( (vf = f.mvar()) < (vg = g.mvar()) ) return f;
119  else
120  {
121    if ( vf == vg )
122    {
123      ff = f; gg = g;
124      reord = false;
125      v = vg;
126    }
127    else
128    {
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; }
138    while ( ( dg <= df  ) && ( !ff.isZero()) )
139    {
140      // CERR << "Start gcd..." << "\n";
141      test = gcd(l,LC(ff));
142      //CERR << "gcd(" << l << "," << LC(ff) << ")= " << test << "\n";
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    }
150    if ( reord )
151    {
152      retvalue= swapvar( ff, vg, v );
153    }
154    else
155    {
156      retvalue= ff;
157    }
158    return retvalue;
159  }
160}
161
162static CanonicalForm
163Sprem ( const CanonicalForm &f, const CanonicalForm &g, CanonicalForm & m, CanonicalForm & q )
164{
165  CanonicalForm ff, gg, l, test, retvalue;
166  int df, dg,n;
167  bool reord;
168  Variable vf, vg, v;
169
170  if ( (vf = f.mvar()) < (vg = g.mvar()) )
171  {
172    m=CanonicalForm(0); q=CanonicalForm(0);
173    return f;
174  }
175  else
176  {
177    if ( vf == vg )
178    {
179      ff = f; gg = g;
180      reord = false;
181      v = vg; // == x
182    }
183    else
184    {
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    }
190    dg = degree( gg, v ); // == dv
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;
195    while ( ( dg <= df  ) && ( !ff.isZero()) )
196    {
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    }
204    if ( reord )
205    {
206      retvalue= swapvar( ff, vg, v );
207    }
208    else
209    {
210      retvalue= ff;
211    }
212    m= power(l,n);
213    if ( fdivides(g,m*f-retvalue) )
214      q= (m*f-retvalue)/g;
215    else
216      q= CanonicalForm(0);
217    return retvalue;
218  }
219}
220
221CanonicalForm
222divide( const CanonicalForm & ff, const CanonicalForm & f, const CFList & as)
223{
224  CanonicalForm r,m,q;
225
226  //out_cf("divide f=",ff,"\n");
227  //out_cf("divide g=",f,"\n");
228  if (f.inCoeffDomain())
229  {
230    bool b=!isOn(SW_RATIONAL);
231    On(SW_RATIONAL);
232    q=ff/f;
233    if (b) Off(SW_RATIONAL);
234  }
235  else
236    r= Sprem(ff,f,m,q); //result in q, ignore r,m
237  //CERR << "r= " << r << "  , m= " << m << "  , q= " << q << "\n";
238  r= Prem(q,as);
239  //CERR << "r= " << r << "\n";
240  //out_cf(" ->",r,"\n");
241  return r;
242}
243
244// This function allows as to be empty; in that case, it is equivalent
245// to the previous version (treating no variables as algebraic).
246static CanonicalForm
247myfitting( const CanonicalForm &f, const CFList &as )
248{
249 CanonicalForm rem=f;
250
251 if ( !(rem.isZero()) )
252 {
253   if ( getCharacteristic() > 0 )
254     return num((rem/lc(rem)));
255   else
256   {
257     On(SW_RATIONAL);
258     CanonicalForm temp= mapinto(rem);
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";
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
291     temp= bCommonDen(temp/lc(temp))*(temp/lc(temp));
292     Off(SW_RATIONAL);
293     rem= mapinto(temp);
294     return rem;
295   }
296 }
297 else
298   return rem;
299}
300
301CanonicalForm
302Prem( const CanonicalForm &f, const CFList &L )
303{
304  CanonicalForm rem = f;
305  CFListIterator i = L;
306  for ( i.lastItem(); i.hasItem(); i-- )
307  {
308    //CERR << "   PREM: Prem(" << rem << "," ;
309    rem = Prem( rem, i.getItem() );
310    //CERR << "   PREM: Prem(" << rem << "," << i.getItem() << ")  = " << rem << "\n";
311  }
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);
327}
328
329CFList
330Prem( const CFList &AS, const CFList &L )
331{
332  CFList Output;
333
334  for ( CFListIterator i=AS; i.hasItem(); i++ )
335    Output = Union(CFList(Prem(i.getItem(),L)), Output);
336
337  return Output;
338}
339
340static CanonicalForm
341premasb( const CanonicalForm & f, const CFList & as)
342{
343  CanonicalForm remd=f;
344  CFList AS=as;
345
346  if ( as.length() > 1 )
347  {
348    AS.removeFirst(); // get rid of first elem
349    CanonicalForm elem;
350    while ( ! AS.isEmpty() )
351    { // thats true for at least the first iteration
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
365remsetb( const CFList & ps, const CFList & as)
366{
367  CFList output;
368  CanonicalForm elem;
369  for (CFListIterator i=ps; i.hasItem(); i++)
370  {
371    elem= premasb(i.getItem(),as);
372    if ( !elem.isZero() ) output.append(elem);
373  }
374  return output;
375}
376
377// for characteristic sets
378//////////////////////////////////
379// replace the power of factors of polys in as by 1 if any
380static CFList
381nopower( const CanonicalForm & init )
382{
383  CFFList sqrfreelist;// = Factorize(init);//SqrFree(init);
384  CFList output;
385  CanonicalForm elem;
386  int count=0;
387
388  for ( CFIterator j=init; j.hasTerms(); j++ )
389    if (!(j.coeff().isOne()) ) count++;
390  //  if ( init != 1 ){
391  //  CERR << "nopower: f is " << init << "\n";
392  //  CERR << "nopower: count is " << count << "\n";}
393  if ( count > 1 ) sqrfreelist = CFFList( CFFactor(init,1));
394  else
395  {
396    sqrfreelist = Factorize(init);
397    //sqrfreelist.removeFirst();
398  }
399  for ( CFFListIterator i=sqrfreelist; i.hasItem(); i++ )
400  {
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 )
409CFList
410removecontent ( const CFList & PS, PremForm & Remembern )
411{
412  CFListIterator i=PS;
413  if ((!i.hasItem()) || ( cls(PS.getFirst()) == 0 )) return PS;
414
415  CFList output;
416  CanonicalForm cc,elem;
417
418  for (; i.hasItem(); i++)
419  {
420    elem = i.getItem();
421    cc = content(elem, elem.mvar());
422    if ( cls(cc) > 0 )
423    {
424      output.append(elem/cc);
425      Remembern.FS2 = Union(CFList(cc), Remembern.FS2);
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
434void
435removefactor( CanonicalForm & r , PremForm & Remembern)
436{
437  int test;
438  CanonicalForm a,b,testelem;
439  CFList testlist;
440  int n=level(r);
441  CFListIterator j ;
442
443  for ( int J=1; J<= n ; J++ )
444  {
445    testlist.append(CanonicalForm(Variable(J)));
446  }
447
448  //  testlist = Union(Remembern.FS1, testlist); // add candidates
449
450  // remove already removed factors
451  for ( j = Remembern.FS2 ; j.hasItem(); j++ )
452  {
453    testelem = j.getItem();
454    while ( 1 )
455    {
456      test = mydivremt(r,testelem,a,b);
457      if ( test && b.isZero() ) r = a;
458      else break;
459    }
460  }
461
462  // Let's look if we have other canditates to remove
463  for ( j = testlist ; j.hasItem(); j++ )
464  {
465    testelem = j.getItem();
466//    if ( testelem != r && testelem != r.mvar() ){
467    if ( testelem != r )
468    {
469      while ( 1 )
470      {
471        test = divremt(r,testelem,a,b);
472        if ( test && b.isZero() )
473        {
474          Remembern.FS2= Union(Remembern.FS2, CFList(testelem));
475          r = a;
476          if ( r == 1 ) break;
477        }
478        else break;
479      }
480    }
481  }
482  //  CERR << "Remembern.FS1 = " << Remembern.FS1 << "\n";
483  //  CERR << "Remembern.FS2 = " << Remembern.FS2 << "\n";
484  //  Remembern.FS1 = Difference(Remembern.FS1, Remembern.FS2);
485  //  CERR << "  New Remembern.FS1 = " << Remembern.FS1 << "\n";
486}
487
488
489// all irreducible nonconstant factors of a set of polynomials
490CFList
491factorps( const CFList &ps )
492{
493  CFList qs;
494  CFFList q;
495  CanonicalForm elem;
496
497  for ( CFListIterator i=ps; i. hasItem(); i++ )
498  {
499    q=Factorize(i.getItem());
500    q.removeFirst();
501    // Next can be simplified ( first (already removed) elem in q is the only constant
502    for ( CFFListIterator j=q; j.hasItem(); j++ )
503    {
504      elem = j.getItem().factor();
505      if ( getNumVars(elem) > 0 )
506        qs= Union(qs, CFList(myfitting(elem, CFList())));
507    }
508  }
509  return qs;
510}
511
512// the initial of poly f wrt to the order of the variables
513static CanonicalForm
514inital( const CanonicalForm &f )
515{
516  CanonicalForm leadcoeff;
517
518  if ( cls(f) == 0 ) {return f.genOne(); }
519  else
520  {
521    leadcoeff = LC(f,lvar(f));
522    //    if ( leadcoeff != 0 )
523    return myfitting(leadcoeff, CFList()); //num(leadcoeff/lc(leadcoeff));
524    //    else return leadcoeff;
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
546// the set of nonconstant initials of Cset
547// with certain repeated factors cancelled
548CFList
549initalset1(const CFList & Cset)
550{
551  CFList temp;
552  CFList initals;
553  CanonicalForm init;
554
555  for ( CFListIterator i = Cset ; i.hasItem(); i++ )
556  {
557    initals= nopower( inital(i.getItem()) );
558    //    init= inital(i.getItem());
559    for ( CFListIterator j = initals; j.hasItem(); j++)
560    {
561      init = j.getItem();
562      if ( cls(init) > 0 )
563        temp= Union(temp, CFList(init));
564    }
565  }
566  return temp;
567}
568
569// the set of nonconstant initials of Cset of those polys
570// not having their cls higher than reducible
571// with certain repeated factors cancelled
572CFList
573initalset2(const CFList & Cset, const CanonicalForm & reducible)
574{
575  CFList temp;
576  CFList initals;
577  CanonicalForm init;
578  int clsred = cls(reducible);
579
580  for ( CFListIterator i = Cset ; i.hasItem(); i++ )
581  {
582    init = i.getItem();
583    if ( cls(init) < clsred )
584    {
585      initals= nopower( inital(init) );
586      //    init= inital(i.getItem());
587      for ( CFListIterator j = initals; j.hasItem(); j++)
588      {
589        init = j.getItem();
590        if ( cls(init) > 0 )
591          temp= Union(temp, CFList(init));
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
612//CF pfactor( ..... )
613
614// //////////////////////////////////////////
615// // for IrrCharSeries
616
617#ifdef IRRCHARSERIESDEBUG
618#  define DEBUGOUTPUT
619#else
620#  undef DEBUGOUTPUT
621#endif
622#include <libfac/factor/debug.h>
623// examine the irreducibility of as for IrrCharSeries
624int
625irreducible( const CFList & AS)
626{
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.
630  bool deg1=true;
631  for ( CFListIterator i = AS ; i.hasItem(); i++ )
632  {
633    if ( degree(i.getItem()) > 1 )
634    {
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
645select( const ListCFList & PS)
646{
647  return PS.getFirst();
648}
649
650// divide list ppi in elems having length <= and > length
651void
652select( const ListCFList & ppi, int length, ListCFList & ppi1, ListCFList & ppi2)
653{
654  CFList elem;
655  for ( ListCFListIterator i=ppi ; i.hasItem(); i++ )
656  {
657    elem = i.getItem();
658    if ( ! elem.isEmpty() )
659    {
660      if ( length <= elem.length() ){ ppi2.append(elem); }
661      else { ppi1.append(elem); }
662    }
663  }
664}
665
666
667//////////////////////////////////////////////////////////////
668// help-functions for sets
669
670// is f in F ?
671static bool
672member( const CanonicalForm &f, const CFList &F)
673{
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
681same( const CFList &A, const CFList &B )
682{
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
695member( const CFList & cs, const ListCFList & pi )
696{
697  ListCFListIterator i;
698  CFList elem;
699
700  for ( i=pi; i.hasItem(); i++)
701  {
702    elem = i.getItem();
703    if ( same(cs,elem) ) return 1;
704  }
705  return 0;
706}
707
708// is PS a subset of Cset ?
709bool
710subset( const CFList &PS, const CFList &Cset )
711{
712  //  CERR << "subset: called with: " << PS << "   " << Cset << "\n";
713  for ( CFListIterator i=PS; i.hasItem(); i++ )
714    if ( ! member(i.getItem(), Cset) )
715    {
716      //      CERR << "subset: " << i.getItem() << "  is not a member of " << Cset << "\n";
717      return 0;
718    }
719  return 1;
720}
721
722// Union of two List of Lists
723ListCFList
724MyUnion( const ListCFList & a, const ListCFList &b )
725{
726  ListCFList output;
727  ListCFListIterator i;
728  CFList elem;
729
730  for ( i = a ; i.hasItem(); i++ )
731  {
732    elem=i.getItem();
733    if ( (! elem.isEmpty()) && ( ! member(elem,output)) )
734    {
735      output.append(elem);
736    }
737  }
738
739  for ( i = b ; i.hasItem(); i++ )
740  {
741    elem=i.getItem();
742    if ( (! elem.isEmpty()) && ( ! member(elem,output)) )
743    {
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
752MyDifference( const ListCFList & a, const CFList &b)
753{
754  ListCFList output;
755  ListCFListIterator i;
756  CFList elem;
757
758  for ( i = a ; i.hasItem(); i++ )
759  {
760    elem=i.getItem();
761    if ( (! elem.isEmpty()) && ( ! same(elem,b)) )
762    {
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
771Minus( const ListCFList & a, const ListCFList & b)
772{
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
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;
787  }
788  if (f.level()>0)
789  {
790    return alg_lc(f.LC(),as);
791  }
792  return CanonicalForm(1);
793}
794#endif
795
796CanonicalForm
797alg_content (const CanonicalForm& f, const CFList& as)
798{
799  if (!f.inCoeffDomain())
800  {
801    CFIterator i= f;
802    CanonicalForm result= abs (i.coeff());
803    i++;
804    while (i.hasTerms() && !result.isOne())
805    {
806      result= alg_gcd (i.coeff(), result, as);
807      i++;
808    }
809    return result;
810  }
811
812  return abs (f);
813}
814
815CanonicalForm alg_gcd(const CanonicalForm & fff, const CanonicalForm &ggg,
816                      const CFList &as)
817{
818  if (fff.inCoeffDomain() || ggg.inCoeffDomain())
819    return 1;
820  bool isRat= isOn (SW_RATIONAL);
821  CanonicalForm f=fff;
822  CanonicalForm g=ggg;
823  f=Prem(f,as);
824  g=Prem(g,as);
825  if ( f.isZero() )
826  {
827    if ( g.lc().sign() < 0 ) return -g;
828    else                     return g;
829  }
830  else  if ( g.isZero() )
831  {
832    if ( f.lc().sign() < 0 ) return -f;
833    else                     return f;
834  }
835  //out_cf("alg_gcd fff(",fff," \n ");
836  //out_cf("ggg",ggg,")\n");
837  int v= as.getLast().level();
838  if (f.level() <= v || g.level() <= v)
839    return 1;
840
841  CanonicalForm res;
842  // does as appear in f and g ?
843  bool has_alg_var=false;
844  for ( CFListIterator j=as;j.hasItem(); j++ )
845  {
846    Variable v=j.getItem().mvar();
847    if (hasVar(f,v)) {has_alg_var=true; /*break;*/}
848    if (hasVar(g,v)) {has_alg_var=true; /*break;*/}
849    //out_cf("as:",j.getItem(),"\n");
850  }
851  if (!has_alg_var)
852  {
853    if ((hasAlgVar(f))
854    || (hasAlgVar(g)))
855    {
856      Varlist ord;
857      for ( CFListIterator j=as;j.hasItem(); j++ )
858        ord.append(j.getItem().mvar());
859      res=algcd(f,g,as,ord);
860    }
861    else
862      res=gcd(f,g);
863    //out_cf("gcd=",res,"\n");
864    //out_cf("of f=",fff," , ");
865    //out_cf("and g=",ggg,"\n");
866
867    return res;
868  }
869
870  int mvf=f.level();
871  int mvg=g.level();
872  if (mvg > mvf)
873  {
874    CanonicalForm tmp=f; f=g; g=tmp;
875    int tmp2=mvf; mvf=mvg; mvg=tmp2;
876  }
877  if (g.inBaseDomain() || f.inBaseDomain())
878  {
879    //printf("const\n");
880    //out_cf("of f=",fff," , ");
881    //out_cf("and g=",ggg,"\n");
882    return CanonicalForm(1);
883  }
884
885  // gcd of all coefficients:
886  CanonicalForm c_f= alg_content (f, as);
887
888  //printf("f.mvar=%d (%d), g.mvar=%d (%d)\n",f.level(),mvf,g.level(),mvg);
889  if (mvf != mvg) // => mvf > mvg
890  {
891    res= alg_gcd (g, c_f, as);
892    return res;
893  }
894  Variable x= f.mvar();
895  // now: mvf==mvg, f.level()==g.level()
896  // content of g
897  CanonicalForm c_g= alg_content (g, as);
898
899  int delta= degree (f) - degree (g);
900
901  //f/=c_gcd;
902  //g/=c_gcd;
903  f= divide (f, c_f, as);
904  g= divide (g, c_g, as);
905
906  // gcd of contents
907  CanonicalForm c_gcd= alg_gcd (c_f, c_g, as);
908  CanonicalForm tmp;
909
910  if (delta < 0)
911  {
912    tmp= f;
913    f= g;
914    g= tmp;
915    delta= -delta;
916  }
917
918  CanonicalForm r=1;
919
920  while (degree (g, x) > 0)
921  {
922    r= Prem (f, g, as);
923    r= Prem (r, as);
924    if (!r.isZero())
925    {
926      r= divide (r, alg_content (r,as), as);
927      r /= vcontent (r,Variable (v+1));
928    }
929    f= g;
930    g= r;
931  }
932
933  if (degree (g, x) == 0)
934    return c_gcd;
935
936  c_f= alg_content (f, as);
937
938  f= divide (f, c_f, as);
939
940  f *= c_gcd;
941  f /= vcontent (f, Variable (v+1));
942
943  return f;
944}
945
Note: See TracBrowser for help on using the repository browser.