source: git/factory/cfCharSetsUtil.cc @ 3fd99f1

spielwiese
Last change on this file since 3fd99f1 was 3fd99f1, checked in by Martin Lee <martinlee84@…>, 10 years ago
chg: more normalization
  • Property mode set to 100644
File size: 22.6 KB
Line 
1/*****************************************************************************\
2 * Computer Algebra System SINGULAR
3\*****************************************************************************/
4/** @file cfCharSetsUtil.cc
5 *
6 * This file provides utility functions to compute characteristic sets
7 *
8 * @note some of the code is code from libfac or derived from code from libfac.
9 * Libfac is written by M. Messollen. See also COPYING for license information
10 * and README for general information on characteristic sets.
11 *
12 * @authors Martin Lee
13 *
14 **/
15/*****************************************************************************/
16
17#include "config.h"
18
19#include "canonicalform.h"
20#include "cf_algorithm.h"
21#include "cfCharSetsUtil.h"
22
23#define __ARRAY_INIT__ -1
24
25// the maximal degree of polys in PS wrt. variable x
26int
27degpsmax (const CFList & PS, const Variable & x,
28          Intarray & A, Intarray & C)
29{
30  int varlevel= level(x);
31  if (A[varlevel] != __ARRAY_INIT__)
32    return A[varlevel];
33  int max= 0, temp, count= 0;
34 
35  for (CFListIterator i= PS; i.hasItem(); i++)
36  {
37    temp= degree (i.getItem(), x);
38    if (temp > max) 
39    {
40      max= temp;
41      count = 0;
42    }
43    if (temp == max)
44      count += max;  // we count the number of polys
45  }
46  A[varlevel]= max;
47  C[varlevel]= count;
48  return max;
49}
50
51// the minimal non-zero degree of polys in PS wrt. x
52// returns 0 if variable x doesn't occure in any of the polys
53int
54degpsmin (const CFList & PS, const Variable & x, Intarray & A, Intarray & B,
55          Intarray & C, Intarray & D)
56{
57  int varlevel= level(x);
58  if (B[varlevel] != __ARRAY_INIT__ )
59    return B[varlevel];
60  int min= degpsmax (PS, x, A, C), temp, count= 0;
61
62  if (min == 0)
63  {
64    B[varlevel]= min;
65    D[varlevel]= min;
66    return min;
67  }
68  else
69  {
70    for (CFListIterator i= PS; i.hasItem(); i++)
71    {
72      temp= degree (i.getItem(), x);
73      if (temp < min && temp != 0)
74      {
75        min= temp;
76        count= 0;
77      }
78      if (temp == min)
79        count += min; // we count the number of polys
80    }
81  }
82  B[varlevel]= min;
83  D[varlevel]= count;
84  return min;
85}
86
87// the minimal total degree of lcoeffs of polys in PS wrt. x
88// for those polys having degree degpsmin in x.
89// F will be assigned the minimal number of terms of those lcoeffs
90int
91Tdeg (const CFList & PS, const Variable & x, Intarray & A, Intarray & B,
92      Intarray & C, Intarray & D, Intarray & E, Intarray & F)
93{
94  int k= degpsmin (PS, x, A, B, C, D), varlevel= level(x), min= 0;
95
96  if (E[varlevel] != __ARRAY_INIT__)
97    return E [varlevel];
98  if (k == 0)
99  {
100    E[varlevel]= 0;
101    F[varlevel]= 0;
102  }
103  else
104  {
105    int nopslc= 0;
106    CFList LCdegList;
107    CanonicalForm elem;
108    CFListIterator i;
109
110    for (i= PS; i.hasItem(); i++)
111    {
112      elem= i.getItem();
113      if (degree (elem, x) == k)
114        LCdegList.append (LC (elem, x));
115    }
116   
117    if (LCdegList.length() > 0)
118    {
119      CFList TermList;
120      int newmin, newnopslc;
121
122      min= totaldegree (LCdegList.getFirst());
123      TermList= get_Terms (LCdegList.getFirst()); 
124      nopslc= TermList.length();
125      for (i= LCdegList; i.hasItem(); i++)
126      {
127        elem= i.getItem();
128        newmin= totaldegree(elem);
129        TermList= get_Terms(elem);
130        newnopslc= TermList.length();
131        if (newmin < min)
132          min= newmin; 
133        if (newnopslc < nopslc)
134          nopslc= newnopslc;
135      }
136     
137    }
138    E[varlevel]= min;
139    F[varlevel]= nopslc;
140  }
141  return min;
142}
143
144// The number of the poly in which Variable x first occures
145int
146nr_of_poly( const CFList & PS, const Variable & x, Intarray & G)
147{
148  int min= 0, varlevel= level(x);
149  if (G[varlevel] != __ARRAY_INIT__)
150    return G[varlevel];
151  for (CFListIterator i= PS; i.hasItem(); i++)
152  {
153    min += 1;
154    if (degree (i.getItem(), x) > 0)
155      break;
156  }
157  G[varlevel]= min;
158  return min;
159}
160
161int
162degord (const Variable & x, const Variable & y, const CFList & PS,
163        Intarray & A, Intarray & B, Intarray & C, Intarray & D,
164        Intarray & E, Intarray & F, Intarray & G)
165{
166  int xlevel= level(x), ylevel= level(y);
167
168  if      (degpsmax(PS,y,A,C) < degpsmax(PS,x,A,C))         return 1;
169  else if (degpsmax(PS,x,A,C) < degpsmax(PS,y,A,C) )        return 0;
170  else if (C[ylevel] < C[xlevel])                           return 1;
171  else if (C[xlevel] < C[ylevel])                           return 0;
172  else if (degpsmin(PS,x,A,B,C,D) < degpsmin(PS,y,A,B,C,D)) return 1;
173  else if (degpsmin(PS,y,A,B,C,D) < degpsmin(PS,x,A,B,C,D)) return 0;
174  else if (D[ylevel] < D[xlevel])                           return 1;
175  else if (D[xlevel] < D[ylevel])                           return 0;
176  else if (Tdeg(PS,y,A,B,C,D,E,F) < Tdeg(PS,x,A,B,C,D,E,F)) return 1;
177  else if (Tdeg(PS,x,A,B,C,D,E,F) < Tdeg(PS,y,A,B,C,D,E,F)) return 0;
178  else if (F[ylevel] < F[xlevel])                           return 1;
179  else if (F[xlevel] < F[ylevel])                           return 0;
180  else if (nr_of_poly(PS,x,G) <= nr_of_poly(PS,y,G))        return 1;
181  else return 0;
182}
183
184// determine the highest variable of all involved Variables in PS
185// NOTE:
186//    this doesn't give always the correct answer:
187//    If a variable is assigned the highest level in the definition of the
188//    original ring, but doesn't occure in any of the
189//    polynomials, get_max_var returns the variable with a level lower than
190//    the highest level.
191//    Is there a workaround?
192// But for the redefinition of the ring this doesn't matter due to the
193// implementation of neworder().
194
195Variable
196get_max_var (const CFList & PS)
197{
198  Variable x= PS.getFirst().mvar(), y;
199  for (CFListIterator i= PS; i.hasItem(); i++)
200  {
201    y= i.getItem().mvar();
202    if (y > x)
203      x= y;
204  }
205  return x;
206}
207
208
209// determine if variable x is in one and only one of the polynomials in PS
210// first criterion for neworder
211CFList
212only_in_one (const CFList & PS, const Variable & x)
213{
214  CFList output;
215
216  for (CFListIterator i= PS; i.hasItem(); i++ )
217  {
218    if (degree (i.getItem(), x) >= 1)
219      output.insert (i.getItem());
220    if (output.length() >= 2)
221      break;
222  }
223  return output;
224}
225
226// initialize all Arrays (of same range) with __ARRAY_INIT__
227void
228initArray (const int highest_level, Intarray & A, Intarray & B, Intarray & C,
229           Intarray & D, Intarray & E, Intarray & F, Intarray & G)
230{
231  for (int i=1 ; i <= highest_level; i ++)
232  {
233    A[i]= __ARRAY_INIT__;
234    B[i]= __ARRAY_INIT__;
235    C[i]= __ARRAY_INIT__;
236    D[i]= __ARRAY_INIT__;
237    E[i]= __ARRAY_INIT__;
238    F[i]= __ARRAY_INIT__;
239    G[i]= __ARRAY_INIT__;
240  }
241}
242
243// now for the second criterion; a little more complex
244//
245// idea: set up seven arrays of lenth highest_level
246//       (of which some entries may be empty, because of only_in_one!)
247//   A saves maxdegree of Variable x in A(level(x))
248//   B saves mindegree of Variable x in B(level(x))
249//   C saves the number of polys in PS which have degree A(level(x)) in
250//     D(level(x))
251//   D saves the number of polys in PS which have degree B(level(x)) in
252//     D(level(x))
253//   E saves the minimal total degree of lcoeffs of polys wrt x in E(level(x))
254//   F saves the minimal number of terms of lcoeffs of E(level(x)) in F(~)
255//   G saves nr of poly Variable x has first deg <> 0
256
257#define __INIT_GAP__ 3
258Varlist
259reorderb (const Varlist & difference, const CFList & PS,
260          const int highest_level)
261{
262  Intarray A(1, highest_level), B(1, highest_level), C(1, highest_level),
263           D(1, highest_level), E(1, highest_level), F(1, highest_level),
264           G(1, highest_level);
265  initArray (highest_level, A, B, C, D, E, F, G);
266  int i= 0, j, n= difference.length(), gap= 1 + __INIT_GAP__;
267  Variable temp;
268  Array<Variable> v(0, n);
269  VarlistIterator J;
270
271  for (J= difference; J.hasItem(); J++ )
272  {
273    v[i]= J.getItem();
274    i++;
275  }
276 
277  while (gap <= n)
278    gap = __INIT_GAP__ * gap + 1;
279  gap /= __INIT_GAP__;
280 
281  while (gap > 0)
282  {
283    for (i= gap; i <= n - 1; i++)
284    {
285      temp= v[i];
286      for (j= i - gap; j >=0 ; j -= gap)
287      {
288        if (degord (v[j], temp, PS, A, B, C, D, E, F, G))
289          break;
290        v[j + gap]= v[j];
291      }
292      v[j + gap]= temp;
293    }
294    gap /= __INIT_GAP__;
295  }
296  Varlist output;
297  for (i= 0; i <= n - 1; i++)
298    output.append (v[i]);
299  return output;
300}
301
302/// swapvar a whole list of CanonicalForms
303CFList
304swapvar (const CFList & PS, const Variable & x, const Variable & y)
305{
306  CFList ps;
307
308  for (CFListIterator i= PS; i.hasItem(); i++)
309    ps.append (swapvar (i.getItem(), x, y));
310  return ps;
311}
312
313CFFList
314swapvar (const CFFList & PS, const Variable & x, const Variable & y)
315{
316  CFFList ps;
317
318  for (CFFListIterator i= PS; i.hasItem(); i++)
319    ps.append (CFFactor (swapvar (i.getItem().factor(), x, y),
320                         i.getItem().exp()));
321  return ps;
322}
323
324bool
325lowerRank (const CanonicalForm & F, const CanonicalForm & G, int & ind)
326{
327  int degF, degG, levelF, levelG;
328
329  levelF= F.level();
330  levelG= G.level();
331  if (F.inCoeffDomain())
332  {
333    if (G.inCoeffDomain())
334      ind= 1;
335    return true;
336  }
337  else if (G.inCoeffDomain())
338    return false;
339  else if (levelF < levelG)
340    return true;
341  else if (levelF == levelG)
342  {
343    degF= degree(F);
344    degG= degree(G);
345    if (degF < degG)
346      return true;
347    else if (degF == degG)
348      return lowerRank (LC (F), LC (G), ind);
349    else
350      return false;
351  }
352  return false;
353}
354
355
356CanonicalForm
357lowestRank (const CFList & L)
358{
359  CFListIterator i= L;
360  CanonicalForm f;
361  int ind= 0;
362  if (!i.hasItem())
363    return f;
364
365  f= i.getItem();
366  i++;
367
368  while (i.hasItem())
369  {
370    if (lowerRank (i.getItem(), f, ind))
371    {
372      if (ind)
373      {
374        if (size (i.getItem()) < size (f))
375          f= i.getItem();
376        ind= 0;
377      }
378      else
379        f= i.getItem();
380    }
381    i++;
382  }
383  return f;
384}
385
386int minLevel (const CFList& L)
387{
388  if (L.isEmpty())
389    return 0;
390  int min= size (L.getFirst());
391  return min;
392}
393
394/// sort in descending order of length of elements
395void
396sortListCFList (ListCFList& list)
397{
398  int l= 1;
399  int k= 1;
400  CFList buf;
401  ListCFListIterator m;
402  for (ListCFListIterator i= list; l <= list.length(); i++, l++)
403  {
404    for (ListCFListIterator j= list; k <= list.length() - l; k++)
405    {
406      m= j;
407      m++;
408      if ((j.getItem().length() < m.getItem().length()) ||
409          (j.getItem().length() == m.getItem().length() &&
410           minLevel (j.getItem()) > minLevel (m.getItem())))
411      {
412        buf= m.getItem();
413        m.getItem()= j.getItem();
414        j.getItem()= buf;
415        j++;
416        j.getItem()= m.getItem();
417      }
418      else
419        j++;
420    }
421    k= 1;
422  }
423}
424
425
426/// sort in descending order of level of elements
427void
428sortCFListByLevel (CFList& list)
429{
430  int l= 1;
431  int k= 1;
432  CanonicalForm buf;
433  CFListIterator m;
434  for (CFListIterator i= list; l <= list.length(); i++, l++)
435  {
436    for (CFListIterator j= list; k <= list.length() - l; k++)
437    {
438      m= j;
439      m++;
440      if ((size (j.getItem()) < size (m.getItem())) ||
441          ((size (j.getItem()) == size (m.getItem()))
442            && (j.getItem().level() < m.getItem().level())))
443      {
444        buf= m.getItem();
445        m.getItem()= j.getItem();
446        j.getItem()= buf;
447        j++;
448        j.getItem()= m.getItem();
449      }
450      else
451        j++;
452    }
453    k= 1;
454  }
455}
456
457
458/* basic operations on lists */
459
460bool
461isMember (const CanonicalForm& f, const CFList& F)
462{
463  for (CFListIterator i= F; i.hasItem(); i++)
464  {
465    if (i.getItem().mapinto() == f.mapinto())
466      return 1;
467  }
468  return 0;
469}
470
471/// are list A and B the same?
472bool
473isSame (const CFList& A, const CFList& B)
474{
475  if (A.length() != B.length())
476    return 0;
477
478  CFListIterator i;
479
480  for (i= A; i.hasItem(); i++)
481  {
482    if (!isMember (i.getItem(), B))
483      return 0;
484  }
485  for (i= B; i.hasItem(); i++)
486  {
487    if (!isMember (i.getItem(), A))
488      return 0;
489  }
490  return 1;
491}
492
493
494/// is List cs contained in List of lists pi?
495bool
496isMember (const CFList& cs, const ListCFList& pi)
497{
498  if (pi.isEmpty())
499    return 0;
500
501  ListCFListIterator i;
502
503  for (i= pi; i.hasItem(); i++)
504  {
505    if (i.getItem().length() != cs.length())
506      continue;
507    if (isSame (cs, i.getItem()))
508      return 1;
509  }
510  return 0;
511}
512
513/// is PS a subset of Cset ?
514bool
515isSubset (const CFList &PS, const CFList& Cset)
516{
517  for (CFListIterator i= PS; i.hasItem(); i++)
518  {
519    if (!isMember (i.getItem(), Cset))
520      return 0;
521  }
522  return 1;
523}
524
525/// Union of two List of Lists
526ListCFList
527MyUnion (const ListCFList& a, const ListCFList& b)
528{
529  if (a.isEmpty())
530    return b;
531  if (b.isEmpty())
532    return a;
533
534  ListCFList output;
535  ListCFListIterator i;
536  CFList elem;
537
538  for (i= a; i.hasItem(); i++)
539  {
540    elem= i.getItem();
541    if ((!elem.isEmpty()) && (!isMember (elem, output)))
542      output.append(elem);
543  }
544
545  for (i= b; i.hasItem(); i++)
546  {
547    elem= i.getItem();
548    if ((!elem.isEmpty()) && (!isMember (elem, output)))
549      output.append(elem);
550  }
551  return output;
552}
553
554/// Union of a and b stored in b
555void
556inplaceUnion (const ListCFList& a, ListCFList& b)
557{
558  if (a.isEmpty())
559    return;
560  if (b.isEmpty())
561  {
562    b= a;
563    return;
564  }
565
566  ListCFListIterator i;
567  CFList elem;
568
569  for (i= a; i.hasItem(); i++)
570  {
571    elem= i.getItem();
572    if ((!elem.isEmpty()) && (!isMember (elem, b)))
573      b.insert(elem);
574  }
575}
576
577///if list b is member of the list of lists a remove b and return the rest
578ListCFList
579minus (const ListCFList& a, const CFList& b)
580{
581  ListCFList output;
582  ListCFListIterator i;
583  CFList elem;
584
585  for (i= a; i.hasItem(); i++)
586  {
587    elem= i.getItem();
588    if ((!elem.isEmpty()) && (!isSame (elem, b)))
589      output.append (elem);
590  }
591  return output;
592}
593
594/// remove all elements of b from list of lists a and return the rest
595ListCFList
596minus (const ListCFList& a, const ListCFList& b)
597{
598  ListCFList output= a;
599
600  for (ListCFListIterator i= b; i.hasItem(); i++)
601    output = minus (output, i.getItem());
602
603  return output;
604}
605
606ListCFList
607adjoin (const CFList& is, const CFList& qs, const ListCFList& qh)
608{
609  ListCFList iss, qhi;
610  ListCFListIterator j;
611  CFList iscopy, itt;
612  CFListIterator i;
613  int ind, length;
614
615  for (i= is; i.hasItem(); i++)
616  {
617    if (i.getItem().level() > 0)
618      iscopy= Union (CFList (i.getItem()), iscopy);
619  }
620  if (iscopy.isEmpty())
621    return iss;
622
623  qhi= minus (qh, qs);
624  length= qhi.length();
625
626  for (i= iscopy; i.hasItem(); i++)
627  {
628    itt= Union (qs, CFList (i.getItem()));
629    ind= 0;
630    if (length > 0)
631    {
632      for (j= qhi; j.hasItem(); j++)
633      {
634        if (isSubset (j.getItem(), itt))
635          ind= 1;
636      }
637    }
638    if (ind == 0)
639      iss.append (itt);
640  }
641  return iss;
642}
643
644ListCFList
645adjoinb (const CFList & is, const CFList & qs, const ListCFList & qh,
646         const CFList & cs)
647{
648  ListCFList iss, qhi;
649  ListCFListIterator j;
650  CFList iscopy, itt;
651  CFListIterator i;
652  int ind, length;
653
654  for (i= is ; i.hasItem(); i++)
655  {
656    if (i.getItem().level() > 0)
657      iscopy= Union (CFList (i.getItem()), iscopy);
658  }
659  if (iscopy.isEmpty())
660    return iss;
661  qhi= minus (qh, qs);
662  length= qhi.length();
663  for (i= iscopy; i.hasItem(); i++)
664  {
665    itt= Union (Union (qs, CFList (i.getItem())), cs);
666    ind= 0;
667    if (length > 0)
668    {
669      for (j= qhi; j.hasItem(); j++)
670      {
671        if (isSubset (j.getItem(), itt))
672          ind= 1;
673      }
674    }
675    if (ind == 0)
676      iss.append(itt);
677  }
678  return iss;
679}
680
681void
682select (const ListCFList& ppi, int length, ListCFList& ppi1, ListCFList& ppi2)
683{
684  CFList elem;
685  for (ListCFListIterator i= ppi; i.hasItem(); i++)
686  {
687    elem= i.getItem();
688    if (!elem.isEmpty())
689    {
690      if (length <= elem.length())
691        ppi2.append(elem);
692      else
693        ppi1.append(elem);
694    }
695  }
696}
697
698/* end basic operations on lists */
699
700/// normalize a poly, i.e. in char 0 clear denominators, remove integer content
701/// in char p divide by leading coeff
702CanonicalForm normalize (const CanonicalForm& F)
703{
704  if (F.isZero())
705    return F;
706  if (getCharacteristic() == 0)
707  {
708    CanonicalForm G;
709    bool isRat= isOn (SW_RATIONAL);
710    if (!isRat)
711      On (SW_RATIONAL);
712    G= F;
713    G *= bCommonDen (G);
714    if (!isRat)
715      Off (SW_RATIONAL);
716    if (isRat)
717      Off (SW_RATIONAL);
718    G= F/icontent (F);
719    if (isRat)
720      On (SW_RATIONAL);
721    if (lc(G) < 0)
722      G= -G;
723    return G;
724  }
725
726  return F/lc (F);
727}
728
729/// pseudo remainder of F by G with certain factors of LC (g) cancelled
730CanonicalForm
731Prem (const CanonicalForm& F, const CanonicalForm& G)
732{
733  CanonicalForm f, g, l, test, lu, lv, t, retvalue;
734  int degF, degG, levelF, levelG;
735  bool reord;
736  Variable v, vg= G.mvar();
737
738  if ( (levelF= F.level()) < (levelG= G.level()))
739    return F;
740  else
741  {
742    if ( levelF == levelG )
743    {
744      f= F;
745      g= G;
746      reord= false;
747      v= F.mvar();
748    }
749    else
750    {
751      v= Variable (levelF + 1);
752      f= swapvar (F, vg, v);
753      g= swapvar (G, vg, v);
754      reord= true;
755    }
756    degG= degree (g, v );
757    degF= degree (f, v );
758    if (degG <= degF)
759    {
760      l= LC (g);
761      g= g - l*power (v, degG);
762    }
763    else
764      l= 1;
765    while ((degG <= degF) && (!f.isZero()))
766    {
767      test= gcd (l, LC(f));
768      lu= l / test;
769      lv= LC(f) / test;
770      t= g*lv*power (v, degF - degG);
771
772      if (degF == 0)
773        f= 0;
774      else
775        f= f - LC (f)*power (v, degF);
776
777      f= f*lu - t;
778      degF= degree (f, v);
779    }
780
781    if (reord)
782      retvalue= swapvar (f, vg, v);
783    else
784      retvalue= f;
785
786    return retvalue;
787  }
788}
789
790/// pseudo remainder of f by L with faster test for remainder being zero
791CanonicalForm
792Premb (const CanonicalForm &f, const CFList &L)
793{
794  CanonicalForm rem= f;
795  CFList l= L;
796  l.removeFirst();
797  CFListIterator i= l;
798
799  for (i.lastItem(); i.hasItem(); i--)
800    rem= normalize (Prem (rem, i.getItem()));
801
802  CanonicalForm tmp= L.getFirst()/content (L.getFirst());
803
804  bool isRat= isOn (SW_RATIONAL);
805  if (getCharacteristic() == 0 && !isRat)
806    On (SW_RATIONAL);
807  if (fdivides (tmp, rem))
808  {
809    if (getCharacteristic() == 0 && !isRat)
810      Off (SW_RATIONAL);
811    return 0;
812  }
813
814  if (getCharacteristic() == 0 && !isRat)
815    Off (SW_RATIONAL);
816
817  rem= normalize (Prem (rem, L.getFirst()));
818
819  return rem;
820}
821
822/// pseudo remainder of f by L
823CanonicalForm
824Prem (const CanonicalForm &f, const CFList &L)
825{
826  CanonicalForm rem= f;
827  CFListIterator i= L;
828
829  for (i.lastItem(); i.hasItem(); i--)
830    rem= normalize (Prem (rem, i.getItem()));
831
832  return rem;
833}
834
835CFList uniGcd (const CFList& L)
836{
837  CFList tmp;
838  CanonicalForm g;
839  CFListIterator i;
840  for (i= L; i.hasItem(); i++)
841  {
842    if (i.getItem().isUnivariate() && i.getItem().level() == 1)
843      tmp.append (i.getItem());
844  }
845  if (tmp.length() <= 2)
846    return L;
847  i= tmp;
848  g= i.getItem();
849  i++;
850  g= gcd (g,i.getItem());
851  i++;
852  for (; i.hasItem(); i++)
853    g= gcd (g, i.getItem());
854  return Union (Difference (L, tmp), CFList (g));
855}
856
857CFList initials (const CFList& L)
858{
859  CFList result;
860  for (CFListIterator iter= L; iter.hasItem(); iter++)
861  {
862    if (!LC(iter.getItem()).inCoeffDomain())
863      result.append (LC (iter.getItem()));
864  }
865  return result;
866}
867
868CFList
869factorsOfInitials(const CFList & L)
870{
871  CFList result;
872  CFFList factors;
873  CanonicalForm tmp;
874
875  for (CFListIterator i= L; i.hasItem(); i++)
876  {
877    factors= factorize (LC (i.getItem()));
878    for (CFFListIterator j= factors; j.hasItem(); j++)
879    {
880      tmp= j.getItem().factor();
881      if (!tmp.inCoeffDomain())
882        result= Union (result, CFList (normalize (tmp)));
883    }
884  }
885
886  return result;
887}
888
889void
890removeContent (CanonicalForm& F, CanonicalForm& cF)
891{
892  if (size (F) == 1)
893  {
894    CanonicalForm tmp= F;
895    F= F.mvar();
896    cF= tmp/F;
897    if (!cF.inCoeffDomain())
898      cF= normalize (cF);
899    else
900      cF= 0;
901    F= normalize (F);
902
903    return;
904  }
905
906  cF= content (F);
907
908  if (cF.inCoeffDomain())
909    cF= 0;
910  else
911  {
912    cF= normalize (cF);
913    F /= cF;
914    F= normalize (F);
915  }
916}
917
918CFList
919factorPSet (const CFList& PS)
920{
921  CFList result;
922  CFFList factors;
923  CFFListIterator j;
924
925  for (CFListIterator i= PS; i. hasItem(); i++)
926  {
927    factors= factorize (i.getItem());
928    if (factors.getFirst().factor().inCoeffDomain())
929      factors.removeFirst();
930    for (j= factors; j.hasItem(); j++ )
931      result= Union (result, CFList (normalize (j.getItem().factor())));
932  }
933  return result;
934}
935
936void
937removeFactors (CanonicalForm& r, StoreFactors& StoredFactors,
938               CFList& removedFactors)
939{
940  CanonicalForm quot;
941  CFList testlist;
942  int n= level(r);
943  bool divides;
944  CFListIterator j;
945
946  for (int i=1; i<= n; i++)
947    testlist.append (CanonicalForm (Variable (i)));
948
949  // remove already removed factors
950  for (j= StoredFactors.FS1; j.hasItem(); j++)
951  {
952    while (fdivides (j.getItem(), r, quot))
953    {
954      r= quot;
955    }
956  }
957
958  for (j= StoredFactors.FS2; j.hasItem(); j++)
959  {
960    divides= false;
961    if (j.getItem() != r)
962    {
963      while (fdivides (j.getItem(), r, quot))
964      {
965        divides= true;
966        r= quot;
967      }
968      if (divides)
969        removedFactors= Union (removedFactors, CFList (j.getItem()));
970    }
971  }
972  r= normalize (r);
973
974  // remove variables
975  for (j= testlist; j.hasItem() && !r.isOne(); j++)
976  {
977    divides= false;
978    if (j.getItem() != r)
979    {
980      while (fdivides (j.getItem(), r, quot))
981      {
982        divides= true;
983        r= quot;
984      }
985      if (divides)
986        removedFactors= Union (removedFactors, CFList (j.getItem()));
987     }
988  }
989  r= normalize (r);
990}
991
992CFList
993removeContent (const CFList & PS, StoreFactors & StoredFactors)
994{
995  CFListIterator i= PS;
996  if ((!i.hasItem()) || (PS.getFirst().level() == 0 ))
997    return PS;
998
999  CFList output;
1000  CanonicalForm cc,elem;
1001
1002  for (; i.hasItem(); i++)
1003  {
1004    elem= i.getItem();
1005    cc= content (elem, elem.mvar());
1006    if (cc.level() > 0 )
1007    {
1008      output.append (normalize (elem / cc));
1009      StoredFactors.FS1 = Union (CFList (normalize (cc)), StoredFactors.FS1);
1010    }
1011    else
1012      output.append(normalize (elem));
1013  }
1014  return output;
1015}
1016
1017bool
1018contractsub (const CFList& cs1, const CFList& cs2)
1019{
1020  CFListIterator i;
1021
1022  CanonicalForm r;
1023  for (i= cs1; i.hasItem(); i++)
1024  {
1025    if (Prem (i.getItem(), cs2) != 0)
1026      return false;
1027  }
1028
1029  CFList is= factorsOfInitials (cs1);
1030
1031  for (i= is; i.hasItem(); i++)
1032  {
1033    if (Prem (i.getItem(), cs2) == 0)
1034      return false;
1035  }
1036  return true;
1037}
1038
1039ListCFList
1040contract (const ListCFList& cs)
1041{
1042  ListCFList mem, ts;
1043  CFList iitem, jitem;
1044
1045  if (cs.length() < 2)
1046    return cs;
1047
1048  int l= cs.length();
1049  int ii= 1;
1050  ListCFListIterator j;
1051  for (ListCFListIterator i= cs; i.hasItem() && ii < l; i++, ii++)
1052  {
1053    iitem= i.getItem();
1054    if (!isMember (iitem, mem))
1055    {
1056      j= i;
1057      j++;
1058      for (; j.hasItem(); j++)
1059      {
1060        jitem= j.getItem();
1061        if (!isMember (jitem, mem))
1062        {
1063          if (contractsub (iitem, jitem))
1064          {
1065            ts.append (jitem);
1066            mem.append (jitem);
1067          }
1068          else
1069          {
1070            if (contractsub (jitem, iitem))
1071              ts.append (iitem); // no mem.append (item) because we assume cs does not contain duplicate entries
1072          }
1073        }
1074      }
1075    }
1076  }
1077  return minus (cs,ts);
1078}
1079
Note: See TracBrowser for help on using the repository browser.