source: git/factory/libfac/charset/csutil.cc @ d21c2c

spielwiese
Last change on this file since d21c2c was d21c2c, checked in by Martin Lee <martinlee84@…>, 10 years ago
fix: handling of SW_RATIONAL in myfitting
  • 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     bool isRat= isOn (SW_RATIONAL);
258     if (!isRat)
259       On(SW_RATIONAL);
260     CanonicalForm temp= mapinto(rem);
261//      CERR << "temp= " << temp << "\n";
262//      CERR << "lc(temp)= " << lc(temp) << "\n";
263//      CERR << "temp/lc(temp)= " << temp/lc(temp) << "\n";
264//      CERR << "num(rem/lc(rem))= " << num(rem/lc(rem)) << "\n";
265
266     // If as is of length 1, and its polynomial is level 1, then
267     // we treat the first variable as algebraic and invert the leading
268     // coefficient where this variable is part of the coefficient domain.
269
270     if (as.length() == 1 && level(as.getFirst()) == 1)
271     {
272       CanonicalForm lcoeff = temp;
273       while (level(lcoeff) > 1)
274       {
275         lcoeff = LC(lcoeff);
276       }
277       // out_cf("myfitting: lcoeff = ", lcoeff, "\n");
278
279       CanonicalForm p = as.getFirst();
280       // out_cf("myfitting: p = ", p, "\n");
281
282       CanonicalForm unused, inverse;
283
284       extgcd(lcoeff, p, inverse, unused);
285       // out_cf("myfitting: inverse = ", inverse, "\n");
286
287       // This may leave temp with non-integral coefficients,
288       // which will be cleaned up below.
289       temp = temp * inverse;
290       // out_cf("myfitting: temp = ", temp, "\n");
291     }
292
293     temp= bCommonDen(temp/lc(temp))*(temp/lc(temp));
294     if (!isRat)
295       Off(SW_RATIONAL);
296     rem= mapinto(temp);
297     return rem;
298   }
299 }
300 else
301   return rem;
302}
303
304CanonicalForm
305Prem( const CanonicalForm &f, const CFList &L )
306{
307  CanonicalForm rem = f;
308  CFListIterator i = L;
309  for ( i.lastItem(); i.hasItem(); i-- )
310  {
311    //CERR << "   PREM: Prem(" << rem << "," ;
312    rem = Prem( rem, i.getItem() );
313    //CERR << "   PREM: Prem(" << rem << "," << i.getItem() << ")  = " << rem << "\n";
314  }
315  return myfitting(rem, CFList());
316}
317
318CanonicalForm
319Prem( const CanonicalForm &f, const CFList &L, const CFList &as )
320{
321  CanonicalForm rem = f;
322  CFListIterator i = L;
323  for ( i.lastItem(); i.hasItem(); i-- )
324  {
325    //CERR << "   PREM: Prem(" << rem << "," ;
326    rem = Prem( rem, i.getItem() );
327    //CERR << "   PREM: Prem(" << rem << "," << i.getItem() << ")  = " << rem << "\n";
328  }
329  return myfitting(rem, as);
330}
331
332CFList
333Prem( const CFList &AS, const CFList &L )
334{
335  CFList Output;
336
337  for ( CFListIterator i=AS; i.hasItem(); i++ )
338    Output = Union(CFList(Prem(i.getItem(),L)), Output);
339
340  return Output;
341}
342
343static CanonicalForm
344premasb( const CanonicalForm & f, const CFList & as)
345{
346  CanonicalForm remd=f;
347  CFList AS=as;
348
349  if ( as.length() > 1 )
350  {
351    AS.removeFirst(); // get rid of first elem
352    CanonicalForm elem;
353    while ( ! AS.isEmpty() )
354    { // thats true for at least the first iteration
355      elem= AS.getLast();
356      remd= Prem(remd,elem);
357      AS.removeLast();
358    }
359  }
360  CanonicalForm a,b;
361  if ( mydivremt(remd, as.getFirst(), a,b )){ remd= remd.genZero();}
362  else { remd= Prem(remd, as.getFirst()); }
363
364  return remd;
365}
366
367CFList
368remsetb( const CFList & ps, const CFList & as)
369{
370  CFList output;
371  CanonicalForm elem;
372  for (CFListIterator i=ps; i.hasItem(); i++)
373  {
374    elem= premasb(i.getItem(),as);
375    if ( !elem.isZero() ) output.append(elem);
376  }
377  return output;
378}
379
380// for characteristic sets
381//////////////////////////////////
382// replace the power of factors of polys in as by 1 if any
383static CFList
384nopower( const CanonicalForm & init )
385{
386  CFFList sqrfreelist;// = Factorize(init);//SqrFree(init);
387  CFList output;
388  CanonicalForm elem;
389  int count=0;
390
391  for ( CFIterator j=init; j.hasTerms(); j++ )
392    if (!(j.coeff().isOne()) ) count++;
393  //  if ( init != 1 ){
394  //  CERR << "nopower: f is " << init << "\n";
395  //  CERR << "nopower: count is " << count << "\n";}
396  if ( count > 1 ) sqrfreelist = CFFList( CFFactor(init,1));
397  else
398  {
399    sqrfreelist = Factorize(init);
400    //sqrfreelist.removeFirst();
401  }
402  for ( CFFListIterator i=sqrfreelist; i.hasItem(); i++ )
403  {
404    elem=i.getItem().factor();
405    if ( cls(elem) > 0 ) output.append(elem);
406  }
407  return output;
408}
409
410// remove the content of polys in PS; add the removed content to
411// Remembern.FS2 ( the set of removed factors )
412CFList
413removecontent ( const CFList & PS, PremForm & Remembern )
414{
415  CFListIterator i=PS;
416  if ((!i.hasItem()) || ( cls(PS.getFirst()) == 0 )) return PS;
417
418  CFList output;
419  CanonicalForm cc,elem;
420
421  for (; i.hasItem(); i++)
422  {
423    elem = i.getItem();
424    cc = content(elem, elem.mvar());
425    if ( cls(cc) > 0 )
426    {
427      output.append(elem/cc);
428      Remembern.FS2 = Union(CFList(cc), Remembern.FS2);
429    }
430    else{ output.append(elem); }
431  }
432  return output;
433}
434
435// remove possible factors in Remember.FS1 from poly r
436// Remember.FS2 contains all factors removed before
437void
438removefactor( CanonicalForm & r , PremForm & Remembern)
439{
440  int test;
441  CanonicalForm a,b,testelem;
442  CFList testlist;
443  int n=level(r);
444  CFListIterator j ;
445
446  for ( int J=1; J<= n ; J++ )
447  {
448    testlist.append(CanonicalForm(Variable(J)));
449  }
450
451  //  testlist = Union(Remembern.FS1, testlist); // add candidates
452
453  // remove already removed factors
454  for ( j = Remembern.FS2 ; j.hasItem(); j++ )
455  {
456    testelem = j.getItem();
457    while ( 1 )
458    {
459      test = mydivremt(r,testelem,a,b);
460      if ( test && b.isZero() ) r = a;
461      else break;
462    }
463  }
464
465  // Let's look if we have other canditates to remove
466  for ( j = testlist ; j.hasItem(); j++ )
467  {
468    testelem = j.getItem();
469//    if ( testelem != r && testelem != r.mvar() ){
470    if ( testelem != r )
471    {
472      while ( 1 )
473      {
474        test = divremt(r,testelem,a,b);
475        if ( test && b.isZero() )
476        {
477          Remembern.FS2= Union(Remembern.FS2, CFList(testelem));
478          r = a;
479          if ( r == 1 ) break;
480        }
481        else break;
482      }
483    }
484  }
485  //  CERR << "Remembern.FS1 = " << Remembern.FS1 << "\n";
486  //  CERR << "Remembern.FS2 = " << Remembern.FS2 << "\n";
487  //  Remembern.FS1 = Difference(Remembern.FS1, Remembern.FS2);
488  //  CERR << "  New Remembern.FS1 = " << Remembern.FS1 << "\n";
489}
490
491
492// all irreducible nonconstant factors of a set of polynomials
493CFList
494factorps( const CFList &ps )
495{
496  CFList qs;
497  CFFList q;
498  CanonicalForm elem;
499
500  for ( CFListIterator i=ps; i. hasItem(); i++ )
501  {
502    q=Factorize(i.getItem());
503    q.removeFirst();
504    // Next can be simplified ( first (already removed) elem in q is the only constant
505    for ( CFFListIterator j=q; j.hasItem(); j++ )
506    {
507      elem = j.getItem().factor();
508      if ( getNumVars(elem) > 0 )
509        qs= Union(qs, CFList(myfitting(elem, CFList())));
510    }
511  }
512  return qs;
513}
514
515// the initial of poly f wrt to the order of the variables
516static CanonicalForm
517inital( const CanonicalForm &f )
518{
519  CanonicalForm leadcoeff;
520
521  if ( cls(f) == 0 ) {return f.genOne(); }
522  else
523  {
524    leadcoeff = LC(f,lvar(f));
525    //    if ( leadcoeff != 0 )
526    return myfitting(leadcoeff, CFList()); //num(leadcoeff/lc(leadcoeff));
527    //    else return leadcoeff;
528  }
529}
530
531// the set of all nonconstant factors of initals of polys in as
532// CFList
533// initalset(const CFList &as){
534//   CanonicalForm elem;
535//   CFList is, iss,iniset;
536
537//   for ( CFListIterator i=as ; i.hasItem(); i++ ){
538//     elem = inital(i.getItem());
539//     if ( cls(elem) > 0 ) is.append(elem);
540//   }
541//   iss = factorps(is);
542//   for ( CFListIterator j=iss; j.hasItem();j++ ){
543//     elem = j.getItem();
544//     if ( cls(elem) > 0 ) iniset.append(num(elem/lc(elem)));
545//   }
546//   return iniset;
547// }
548
549// the set of nonconstant initials of Cset
550// with certain repeated factors cancelled
551CFList
552initalset1(const CFList & Cset)
553{
554  CFList temp;
555  CFList initals;
556  CanonicalForm init;
557
558  for ( CFListIterator i = Cset ; i.hasItem(); i++ )
559  {
560    initals= nopower( inital(i.getItem()) );
561    //    init= inital(i.getItem());
562    for ( CFListIterator j = initals; j.hasItem(); j++)
563    {
564      init = j.getItem();
565      if ( cls(init) > 0 )
566        temp= Union(temp, CFList(init));
567    }
568  }
569  return temp;
570}
571
572// the set of nonconstant initials of Cset of those polys
573// not having their cls higher than reducible
574// with certain repeated factors cancelled
575CFList
576initalset2(const CFList & Cset, const CanonicalForm & reducible)
577{
578  CFList temp;
579  CFList initals;
580  CanonicalForm init;
581  int clsred = cls(reducible);
582
583  for ( CFListIterator i = Cset ; i.hasItem(); i++ )
584  {
585    init = i.getItem();
586    if ( cls(init) < clsred )
587    {
588      initals= nopower( inital(init) );
589      //    init= inital(i.getItem());
590      for ( CFListIterator j = initals; j.hasItem(); j++)
591      {
592        init = j.getItem();
593        if ( cls(init) > 0 )
594          temp= Union(temp, CFList(init));
595      }
596    }
597  }
598  return temp;
599}
600
601//replace the power of factors of poly in CF init by 1 if any
602// and return the sqrfree poly
603// static CanonicalForm
604// nopower1( const CanonicalForm & init ){
605//   CFFList returnlist=Factorize(init);
606//   CanonicalForm elem, test=init.genOne();
607//   for ( CFFListIterator i= returnlist; i.hasItem(); i++){
608//     elem = i.getItem().factor();
609//     if ( cls(elem)>0 ) test *= elem;
610//   }
611//   return test;
612// }
613
614// the sequence of distinct factors of f
615//CF pfactor( ..... )
616
617// //////////////////////////////////////////
618// // for IrrCharSeries
619
620#ifdef IRRCHARSERIESDEBUG
621#  define DEBUGOUTPUT
622#else
623#  undef DEBUGOUTPUT
624#endif
625#include <libfac/factor/debug.h>
626// examine the irreducibility of as for IrrCharSeries
627int
628irreducible( const CFList & AS)
629{
630// AS is given by AS = { A1, A2, .. Ar }, d_i = degree(Ai)
631
632// 1) we test: if d_i > 1, d_j =1 for all j<>i, then AS is irreducible.
633  bool deg1=true;
634  for ( CFListIterator i = AS ; i.hasItem(); i++ )
635  {
636    if ( degree(i.getItem()) > 1 )
637    {
638      if ( deg1 ) deg1=0;
639      else return 0; // found 2nd poly with deg > 1
640    }
641  }
642  return 1;
643}
644
645
646// select an item from PS for irras
647CFList
648select( const ListCFList & PS)
649{
650  return PS.getFirst();
651}
652
653// divide list ppi in elems having length <= and > length
654void
655select( const ListCFList & ppi, int length, ListCFList & ppi1, ListCFList & ppi2)
656{
657  CFList elem;
658  for ( ListCFListIterator i=ppi ; i.hasItem(); i++ )
659  {
660    elem = i.getItem();
661    if ( ! elem.isEmpty() )
662    {
663      if ( length <= elem.length() ){ ppi2.append(elem); }
664      else { ppi1.append(elem); }
665    }
666  }
667}
668
669
670//////////////////////////////////////////////////////////////
671// help-functions for sets
672
673// is f in F ?
674static bool
675member( const CanonicalForm &f, const CFList &F)
676{
677  for ( CFListIterator i=F; i.hasItem(); i++ )
678    if ( i.getItem() == f ) return 1;
679  return 0;
680}
681
682// are list A and B the same?
683bool
684same( const CFList &A, const CFList &B )
685{
686  CFListIterator i;
687
688  for (i = A; i.hasItem(); i++)
689    if (! member(i.getItem(), B) )  return 0;
690  for (i = B; i.hasItem(); i++)
691    if (! member(i.getItem(), A) )  return 0;
692  return 1;
693}
694
695
696// is List cs contained in List of lists pi?
697bool
698member( const CFList & cs, const ListCFList & pi )
699{
700  ListCFListIterator i;
701  CFList elem;
702
703  for ( i=pi; i.hasItem(); i++)
704  {
705    elem = i.getItem();
706    if ( same(cs,elem) ) return 1;
707  }
708  return 0;
709}
710
711// is PS a subset of Cset ?
712bool
713subset( const CFList &PS, const CFList &Cset )
714{
715  //  CERR << "subset: called with: " << PS << "   " << Cset << "\n";
716  for ( CFListIterator i=PS; i.hasItem(); i++ )
717    if ( ! member(i.getItem(), Cset) )
718    {
719      //      CERR << "subset: " << i.getItem() << "  is not a member of " << Cset << "\n";
720      return 0;
721    }
722  return 1;
723}
724
725// Union of two List of Lists
726ListCFList
727MyUnion( const ListCFList & a, const ListCFList &b )
728{
729  ListCFList output;
730  ListCFListIterator i;
731  CFList elem;
732
733  for ( i = a ; i.hasItem(); i++ )
734  {
735    elem=i.getItem();
736    if ( (! elem.isEmpty()) && ( ! member(elem,output)) )
737    {
738      output.append(elem);
739    }
740  }
741
742  for ( i = b ; i.hasItem(); i++ )
743  {
744    elem=i.getItem();
745    if ( (! elem.isEmpty()) && ( ! member(elem,output)) )
746    {
747      output.append(elem);
748    }
749  }
750  return output;
751}
752
753//if list b is member of the list of lists remove b and return the rest
754ListCFList
755MyDifference( const ListCFList & a, const CFList &b)
756{
757  ListCFList output;
758  ListCFListIterator i;
759  CFList elem;
760
761  for ( i = a ; i.hasItem(); i++ )
762  {
763    elem=i.getItem();
764    if ( (! elem.isEmpty()) && ( ! same(elem,b)) )
765    {
766      output.append(elem);
767    }
768  }
769return output;
770}
771
772// remove all elements of b from list of lists a and return the rest
773ListCFList
774Minus( const ListCFList & a, const ListCFList & b)
775{
776  ListCFList output=a;
777
778  for ( ListCFListIterator i=b; i.hasItem(); i++ )
779    output = MyDifference(output, i.getItem() );
780
781  return output;
782}
783
784#if 0
785static CanonicalForm alg_lc(const CanonicalForm &f, const CFList as)
786{
787  for(CFListIterator i=as; i.hasItem(); i++)
788  {
789    if (f.mvar()==i.getItem().mvar()) return f;
790  }
791  if (f.level()>0)
792  {
793    return alg_lc(f.LC(),as);
794  }
795  return CanonicalForm(1);
796}
797#endif
798
799CanonicalForm
800alg_content (const CanonicalForm& f, const CFList& as)
801{
802  if (!f.inCoeffDomain())
803  {
804    CFIterator i= f;
805    CanonicalForm result= abs (i.coeff());
806    i++;
807    while (i.hasTerms() && !result.isOne())
808    {
809      result= alg_gcd (i.coeff(), result, as);
810      i++;
811    }
812    return result;
813  }
814
815  return abs (f);
816}
817
818CanonicalForm alg_gcd(const CanonicalForm & fff, const CanonicalForm &ggg,
819                      const CFList &as)
820{
821  if (fff.inCoeffDomain() || ggg.inCoeffDomain())
822    return 1;
823  bool isRat= isOn (SW_RATIONAL);
824  CanonicalForm f=fff;
825  CanonicalForm g=ggg;
826  f=Prem(f,as);
827  g=Prem(g,as);
828  if ( f.isZero() )
829  {
830    if ( g.lc().sign() < 0 ) return -g;
831    else                     return g;
832  }
833  else  if ( g.isZero() )
834  {
835    if ( f.lc().sign() < 0 ) return -f;
836    else                     return f;
837  }
838  //out_cf("alg_gcd fff(",fff," \n ");
839  //out_cf("ggg",ggg,")\n");
840  int v= as.getLast().level();
841  if (f.level() <= v || g.level() <= v)
842    return 1;
843
844  CanonicalForm res;
845  // does as appear in f and g ?
846  bool has_alg_var=false;
847  for ( CFListIterator j=as;j.hasItem(); j++ )
848  {
849    Variable v=j.getItem().mvar();
850    if (hasVar(f,v)) {has_alg_var=true; /*break;*/}
851    if (hasVar(g,v)) {has_alg_var=true; /*break;*/}
852    //out_cf("as:",j.getItem(),"\n");
853  }
854  if (!has_alg_var)
855  {
856    if ((hasAlgVar(f))
857    || (hasAlgVar(g)))
858    {
859      Varlist ord;
860      for ( CFListIterator j=as;j.hasItem(); j++ )
861        ord.append(j.getItem().mvar());
862      res=algcd(f,g,as,ord);
863    }
864    else
865      res=gcd(f,g);
866    //out_cf("gcd=",res,"\n");
867    //out_cf("of f=",fff," , ");
868    //out_cf("and g=",ggg,"\n");
869
870    return res;
871  }
872
873  int mvf=f.level();
874  int mvg=g.level();
875  if (mvg > mvf)
876  {
877    CanonicalForm tmp=f; f=g; g=tmp;
878    int tmp2=mvf; mvf=mvg; mvg=tmp2;
879  }
880  if (g.inBaseDomain() || f.inBaseDomain())
881  {
882    //printf("const\n");
883    //out_cf("of f=",fff," , ");
884    //out_cf("and g=",ggg,"\n");
885    return CanonicalForm(1);
886  }
887
888  // gcd of all coefficients:
889  CanonicalForm c_f= alg_content (f, as);
890
891  //printf("f.mvar=%d (%d), g.mvar=%d (%d)\n",f.level(),mvf,g.level(),mvg);
892  if (mvf != mvg) // => mvf > mvg
893  {
894    res= alg_gcd (g, c_f, as);
895    return res;
896  }
897  Variable x= f.mvar();
898  // now: mvf==mvg, f.level()==g.level()
899  // content of g
900  CanonicalForm c_g= alg_content (g, as);
901
902  int delta= degree (f) - degree (g);
903
904  //f/=c_gcd;
905  //g/=c_gcd;
906  f= divide (f, c_f, as);
907  g= divide (g, c_g, as);
908
909  // gcd of contents
910  CanonicalForm c_gcd= alg_gcd (c_f, c_g, as);
911  CanonicalForm tmp;
912
913  if (delta < 0)
914  {
915    tmp= f;
916    f= g;
917    g= tmp;
918    delta= -delta;
919  }
920
921  CanonicalForm r=1;
922
923  while (degree (g, x) > 0)
924  {
925    r= Prem (f, g, as);
926    r= Prem (r, as);
927    if (!r.isZero())
928    {
929      r= divide (r, alg_content (r,as), as);
930      r /= vcontent (r,Variable (v+1));
931    }
932    f= g;
933    g= r;
934  }
935
936  if (degree (g, x) == 0)
937    return c_gcd;
938
939  c_f= alg_content (f, as);
940
941  f= divide (f, c_f, as);
942
943  f *= c_gcd;
944  f /= vcontent (f, Variable (v+1));
945
946  return f;
947}
948
Note: See TracBrowser for help on using the repository browser.