source: git/factory/cfCharSets.cc @ 8a90cd

spielwiese
Last change on this file since 8a90cd was 8a90cd, checked in by Martin Lee <martinlee84@…>, 10 years ago
chg: deleted unused function and correct inclusion order
  • Property mode set to 100644
File size: 33.6 KB
Line 
1/*****************************************************************************\
2 * Computer Algebra System SINGULAR
3\*****************************************************************************/
4/** @file cfCharSets.cc
5 *
6 * This file provides functions to compute characteristic sets
7 *
8 * ABSTRACT: Descriptions can be found in Wang "On the Parallelization of
9 * characteristic-set based algorithms" or Greuel/Pfister "A Singular
10 * Introduction to Commutative Algebra".
11 *
12 * @authors Martin Lee, Michael Messollen
13 *
14 **/
15/*****************************************************************************/
16
17#include "timing.h"
18
19#include "cfCharSets.h"
20#include "canonicalform.h"
21#include "cf_algorithm.h"
22#include "facAlgFunc.h"
23
24TIMING_DEFINE_PRINT(neworder_time)
25
26#define __ARRAY_INIT__ -1
27
28// the maximal degree of polys in PS wrt. variable x
29static int
30degpsmax (const CFList & PS, const Variable & x,
31          Intarray & A, Intarray & C)
32{
33  int varlevel= level(x);
34  if (A[varlevel] != __ARRAY_INIT__)
35    return A[varlevel];
36  int max= 0, temp, count= 0;
37 
38  for (CFListIterator i= PS; i.hasItem(); i++)
39  {
40    temp= degree (i.getItem(), x);
41    if (temp > max) 
42    {
43      max= temp;
44      count = 0;
45    }
46    if (temp == max)
47      count += max;  // we count the number of polys
48  }
49  A[varlevel]= max;
50  C[varlevel]= count;
51  return max;
52}
53
54// the minimal non-zero degree of polys in PS wrt. x
55// returns 0 if variable x doesn't occure in any of the polys
56static int
57degpsmin (const CFList & PS, const Variable & x, Intarray & A, Intarray & B,
58          Intarray & C, Intarray & D)
59{
60  int varlevel= level(x);
61  if (B[varlevel] != __ARRAY_INIT__ )
62    return B[varlevel];
63  int min= degpsmax (PS, x, A, C), temp, count= 0;
64
65  if (min == 0)
66  {
67    B[varlevel]= min;
68    D[varlevel]= min;
69    return min;
70  }
71  else
72  {
73    for (CFListIterator i= PS; i.hasItem(); i++)
74    {
75      temp= degree (i.getItem(), x);
76      if (temp < min && temp != 0)
77      {
78        min= temp;
79        count= 0;
80      }
81      if (temp == min)
82        count += min; // we count the number of polys
83    }
84  }
85  B[varlevel]= min;
86  D[varlevel]= count;
87  return min;
88}
89
90// the minimal total degree of lcoeffs of polys in PS wrt. x
91// for those polys having degree degpsmin in x.
92// F will be assigned the minimal number of terms of those lcoeffs
93static int
94Tdeg (const CFList & PS, const Variable & x, Intarray & A, Intarray & B,
95      Intarray & C, Intarray & D, Intarray & E, Intarray & F)
96{
97  int k= degpsmin (PS, x, A, B, C, D), varlevel= level(x), min= 0;
98
99  if (E[varlevel] != __ARRAY_INIT__)
100    return E [varlevel];
101  if (k == 0)
102  {
103    E[varlevel]= 0;
104    F[varlevel]= 0;
105  }
106  else
107  {
108    int nopslc= 0;
109    CFList LCdegList;
110    CanonicalForm elem;
111    CFListIterator i;
112
113    for (i= PS; i.hasItem(); i++)
114    {
115      elem= i.getItem();
116      if (degree (elem, x) == k)
117        LCdegList.append (LC (elem, x));
118    }
119   
120    if (LCdegList.length() > 0)
121    {
122      CFList TermList;
123      int newmin, newnopslc;
124
125      min= totaldegree (LCdegList.getFirst());
126      TermList= get_Terms (LCdegList.getFirst()); 
127      nopslc= TermList.length();
128      for (i= LCdegList; i.hasItem(); i++)
129      {
130        elem= i.getItem();
131        newmin= totaldegree(elem);
132        TermList= get_Terms(elem);
133        newnopslc= TermList.length();
134        if (newmin < min)
135          min= newmin; 
136        if (newnopslc < nopslc)
137          nopslc= newnopslc;
138      }
139     
140    }
141    E[varlevel]= min;
142    F[varlevel]= nopslc;
143  }
144  return min;
145}
146
147// The number of the poly in which Variable x first occures
148static int
149nr_of_poly( const CFList & PS, const Variable & x, Intarray & G)
150{
151  int min= 0, varlevel= level(x);
152  if (G[varlevel] != __ARRAY_INIT__)
153    return G[varlevel];
154  for (CFListIterator i= PS; i.hasItem(); i++)
155  {
156    min += 1;
157    if (degree (i.getItem(), x) > 0)
158      break;
159  }
160  G[varlevel]= min;
161  return min;
162}
163
164static int
165degord (const Variable & x, const Variable & y, const CFList & PS,
166        Intarray & A, Intarray & B, Intarray & C, Intarray & D,
167        Intarray & E, Intarray & F, Intarray & G)
168{
169  int xlevel= level(x), ylevel= level(y);
170
171  if      (degpsmax(PS,y,A,C) < degpsmax(PS,x,A,C))         return 1;
172  else if (degpsmax(PS,x,A,C) < degpsmax(PS,y,A,C) )        return 0;
173  else if (C[ylevel] < C[xlevel])                           return 1;
174  else if (C[xlevel] < C[ylevel])                           return 0;
175  else if (degpsmin(PS,x,A,B,C,D) < degpsmin(PS,y,A,B,C,D)) return 1;
176  else if (degpsmin(PS,y,A,B,C,D) < degpsmin(PS,x,A,B,C,D)) return 0;
177  else if (D[ylevel] < D[xlevel])                           return 1;
178  else if (D[xlevel] < D[ylevel])                           return 0;
179  else if (Tdeg(PS,y,A,B,C,D,E,F) < Tdeg(PS,x,A,B,C,D,E,F)) return 1;
180  else if (Tdeg(PS,x,A,B,C,D,E,F) < Tdeg(PS,y,A,B,C,D,E,F)) return 0;
181  else if (F[ylevel] < F[xlevel])                           return 1;
182  else if (F[xlevel] < F[ylevel])                           return 0;
183  else if (nr_of_poly(PS,x,G) <= nr_of_poly(PS,y,G))        return 1;
184  else return 0;
185}
186
187// determine the highest variable of all involved Variables in PS
188// NOTE:
189//    this doesn't give always the correct answer:
190//    If a variable is assigned the highest level in the definition of the
191//    original ring, but doesn't occure in any of the
192//    polynomials, get_max_var returns the variable with a level lower than
193//    the highest level.
194//    Is there a workaround?
195// But for the redefinition of the ring this doesn't matter due to the
196// implementation of neworder().
197
198static Variable
199get_max_var(const CFList & PS)
200{
201  Variable x= PS.getFirst().mvar(), y;
202  for (CFListIterator i= PS; i.hasItem(); i++)
203  {
204    y= i.getItem().mvar();
205    if (y > x)
206      x= y;
207  }
208  return x;
209}
210
211
212// determine if variable x is in one and only one of the polynomials in PS
213// first criterion for neworder
214static CFList
215only_in_one (const CFList & PS, const Variable & x)
216{
217  CFList output;
218
219  for (CFListIterator i= PS; i.hasItem(); i++ )
220  {
221    if (degree (i.getItem(), x) >= 1)
222      output.insert (i.getItem());
223    if (output.length() >= 2)
224      break;
225  }
226  return output;
227}
228
229// initialize all Arrays (of same range) with __ARRAY_INIT__
230static void
231initArray (const int highest_level, Intarray & A, Intarray & B, Intarray & C,
232           Intarray & D, Intarray & E, Intarray & F, Intarray & G)
233{
234  for (int i=1 ; i <= highest_level; i ++)
235  {
236    A[i]= __ARRAY_INIT__;
237    B[i]= __ARRAY_INIT__;
238    C[i]= __ARRAY_INIT__;
239    D[i]= __ARRAY_INIT__;
240    E[i]= __ARRAY_INIT__;
241    F[i]= __ARRAY_INIT__;
242    G[i]= __ARRAY_INIT__;
243  }
244}
245
246// now for the second criterion; a little more complex
247//
248// idea: set up seven arrays of lenth highest_level
249//       (of which some entries may be empty, because of only_in_one!)
250//   A saves maxdegree of Variable x in A(level(x))
251//   B saves mindegree of Variable x in B(level(x))
252//   C saves the number of polys in PS which have degree A(level(x)) in
253//     D(level(x))
254//   D saves the number of polys in PS which have degree B(level(x)) in
255//     D(level(x))
256//   E saves the minimal total degree of lcoeffs of polys wrt x in E(level(x))
257//   F saves the minimal number of terms of lcoeffs of E(level(x)) in F(~)
258//   G saves nr of poly Variable x has first deg <> 0
259
260#define __INIT_GAP__ 3
261static Varlist
262reorderb (const Varlist & difference, const CFList & PS,
263          const int highest_level)
264{
265  Intarray A(1, highest_level), B(1, highest_level), C(1, highest_level),
266           D(1, highest_level), E(1, highest_level), F(1, highest_level),
267           G(1, highest_level);
268  initArray (highest_level, A, B, C, D, E, F, G);
269  int i= 0, j, n= difference.length(), gap= 1 + __INIT_GAP__;
270  Variable temp;
271  Array<Variable> v(0, n);
272  VarlistIterator J;
273
274  for (J= difference; J.hasItem(); J++ )
275  {
276    v[i]= J.getItem();
277    i++;
278  }
279 
280  while (gap <= n)
281    gap = __INIT_GAP__ * gap + 1;
282  gap /= __INIT_GAP__;
283 
284  while (gap > 0)
285  {
286    for (i= gap; i <= n - 1; i++)
287    {
288      temp= v[i];
289      for (j= i - gap; j >=0 ; j -= gap)
290      {
291        if (degord (v[j], temp, PS, A, B, C, D, E, F, G))
292          break;
293        v[j + gap]= v[j];
294      }
295      v[j + gap]= temp;
296    }
297    gap /= __INIT_GAP__;
298  }
299  Varlist output;
300  for (i= 0; i <= n - 1; i++)
301    output.append (v[i]);
302  return output;
303}
304
305// set up a new orderd list of Variables.
306// we try to reorder the variables heuristically optimal.
307Varlist
308neworder( const CFList & PolyList )
309{
310  CFList PS= PolyList, PS1=PolyList;
311  Varlist oldorder, reorder, difference;
312
313  TIMING_START(neworder_time);
314
315  int highest_level= level(get_max_var(PS));
316
317  // set up oldorder and first criterion: only_in_one
318  for (int i= highest_level; i>=1; i--)
319  {
320    oldorder.insert (Variable(i));
321    CFList is_one= only_in_one (PS1, Variable(i)); 
322    if (is_one.length() == 1)
323    {
324      reorder.insert (Variable(i));
325      PS1= Difference (PS1, is_one);
326    }
327    else if (is_one.length() == 0)
328    {
329      reorder.append (Variable (i)); // assigne it the highest level
330      PS1= Difference (PS1, is_one); 
331    }
332  }
333  difference= Difference (oldorder, reorder);
334
335  // rearrange the ordering of the variables!
336  difference= reorderb (difference, PS, highest_level);
337  reorder= Union (reorder, difference);
338  TIMING_END(neworder_time);
339
340  TIMING_PRINT(neworder_time, "\ntime used for neworder   : ");
341
342  return Union (reorder, Difference (oldorder, reorder));
343}
344
345// the same as above, only returning a list of CanonicalForms
346CFList
347newordercf(const CFList & PolyList )
348{
349  Varlist reorder= neworder (PolyList);
350  CFList output;
351
352  for (VarlistIterator i=reorder; i.hasItem(); i++)
353    output.append (CanonicalForm (i.getItem()));
354
355  return output;
356}
357
358// the same as above, only returning a list of ints
359IntList
360neworderint(const CFList & PolyList )
361{
362  Varlist reorder= neworder (PolyList);
363  IntList output;
364
365  for (VarlistIterator i= reorder; i.hasItem(); i++)
366    output.append (level (i.getItem()));
367
368  return output;
369}
370
371// swapvar a whole list of CanonicalForms
372static CFList
373swapvar( const CFList & PS, const Variable & x, const Variable & y)
374{
375  CFList ps;
376
377  for (CFListIterator i = PS; i.hasItem(); i++)
378    ps.append (swapvar (i.getItem(), x, y));
379  return ps;
380}
381
382static CFFList
383swapvar( const CFFList & PS, const Variable & x, const Variable & y)
384{
385  CFFList ps;
386
387  for (CFFListIterator i= PS; i.hasItem(); i++)
388    ps.append (CFFactor(swapvar (i.getItem().factor(), x, y), i.getItem().exp()));
389  return ps;
390}
391
392// a library function: we reorganize the global variable ordering
393CFList
394reorder (const Varlist & betterorder, const CFList & PS)
395{
396  int i= 1, n= betterorder.length();
397  Intarray v (1, n);
398  CFList ps= PS;
399
400  //initalize:
401  for (VarlistIterator j= betterorder; j.hasItem(); j++)
402  {
403    v[i]= level (j.getItem());
404    i++;
405  }
406  // reorder:
407  for (i= 1; i <= n; i++)
408    ps= swapvar (ps, Variable (v[i]), Variable (n + i));
409  return ps;
410}
411
412CFFList
413reorder( const Varlist & betterorder, const CFFList & PS)
414{
415  int i= 1, n= betterorder.length();
416  Intarray v (1, n);
417  CFFList ps= PS;
418
419  //initalize:
420  for (VarlistIterator j= betterorder; j.hasItem(); j++)
421  {
422    v[i]= level (j.getItem());
423    i++;
424  }
425
426  // reorder:
427  for (i= 1; i <= n; i++)
428    ps= swapvar (ps, Variable (v[i]), Variable (n + i));
429  return ps;
430}
431
432ListCFList
433reorder (const Varlist & betterorder, const ListCFList & Q)
434{
435  ListCFList Q1;
436
437  for (ListCFListIterator i= Q; i.hasItem(); i++)
438    Q1.append (reorder (betterorder, i.getItem()));
439  return Q1;
440}
441
442static bool
443lowerRank (const CanonicalForm & F, const CanonicalForm & G, int & ind)
444{
445  int degF, degG, levelF, levelG;
446
447  levelF= F.level();
448  levelG= G.level();
449  if (F.inCoeffDomain())
450  {
451    if (G.inCoeffDomain())
452      ind= 1;
453    return true;
454  }
455  else if (G.inCoeffDomain())
456    return false;
457  else if (levelF < levelG)
458    return true;
459  else if (levelF == levelG)
460  {
461    degF= degree(F);
462    degG= degree(G);
463    if (degF < degG)
464      return true;
465    else if (degF == degG)
466      return lowerRank (LC (F), LC (G), ind);
467    else
468      return false;
469  }
470  return false;
471}
472
473static
474CanonicalForm
475lowestRank (const CFList & L)
476{
477  CFListIterator i= L;
478  CanonicalForm f;
479  int ind= 0;
480  if (!i.hasItem())
481    return f;
482
483  f= i.getItem();
484  i++;
485
486  while (i.hasItem())
487  {
488    if (lowerRank (i.getItem(), f, ind))
489    {
490      if (ind)
491      {
492        if (size (i.getItem()) < size (f))
493          f= i.getItem();
494        ind= 0;
495      }
496      else
497        f= i.getItem();
498    }
499    i++;
500  }
501  return f;
502}
503
504CFList initials (const CFList& L)
505{
506  CFList result;
507  for (CFListIterator iter= L; iter.hasItem(); iter++)
508  {
509    if (!LC(iter.getItem()).inCoeffDomain())
510      result.append (LC (iter.getItem()));
511  }
512  return result;
513}
514
515// sort in descending order of length of elements
516void
517sortListCFList (ListCFList& list)
518{
519  int l= 1;
520  int k= 1;
521  CFList buf;
522  ListCFListIterator m;
523  for (ListCFListIterator i= list; l <= list.length(); i++, l++)
524  {
525    for (ListCFListIterator j= list; k <= list.length() - l; k++)
526    {
527      m= j;
528      m++;
529      if (j.getItem().length() < m.getItem().length())
530      {
531        buf= m.getItem();
532        m.getItem()= j.getItem();
533        j.getItem()= buf;
534        j++;
535        j.getItem()= m.getItem();
536      }
537      else
538        j++;
539    }
540    k= 1;
541  }
542}
543
544
545// sort in descending order of level of elements
546void
547sortCFListByLevel (CFList& list)
548{
549  int l= 1;
550  int k= 1;
551  CanonicalForm buf;
552  CFListIterator m;
553  for (CFListIterator i= list; l <= list.length(); i++, l++)
554  {
555    for (CFListIterator j= list; k <= list.length() - l; k++)
556    {
557      m= j;
558      m++;
559      if ((size (j.getItem()) < size (m.getItem())) ||
560          ((size (j.getItem()) == size (m.getItem()))
561            && (j.getItem().level() < m.getItem().level())))
562      {
563        buf= m.getItem();
564        m.getItem()= j.getItem();
565        j.getItem()= buf;
566        j++;
567        j.getItem()= m.getItem();
568      }
569      else
570        j++;
571    }
572    k= 1;
573  }
574}
575
576static bool
577member (const CanonicalForm& f, const CFList& F)
578{
579  for (CFListIterator i= F; i.hasItem(); i++)
580  {
581    if (i.getItem().mapinto() == f.mapinto())
582      return 1;
583  }
584  return 0;
585}
586
587// are list A and B the same?
588static bool
589same (const CFList& A, const CFList& B)
590{
591  if (A.length() != B.length())
592    return 0;
593
594  CFListIterator i;
595
596  for (i= A; i.hasItem(); i++)
597  {
598    if (!member (i.getItem(), B))
599      return 0;
600  }
601  for (i= B; i.hasItem(); i++)
602  {
603    if (!member (i.getItem(), A))
604      return 0;
605  }
606  return 1;
607}
608
609
610// is List cs contained in List of lists pi?
611static bool
612member (const CFList& cs, const ListCFList& pi)
613{
614  if (pi.isEmpty())
615    return 0;
616
617  ListCFListIterator i;
618
619  for (i= pi; i.hasItem(); i++)
620  {
621    if (i.getItem().length() != cs.length())
622      continue;
623    if (same (cs, i.getItem()))
624      return 1;
625  }
626  return 0;
627}
628
629// is PS a subset of Cset ?
630static bool
631subset (const CFList &PS, const CFList& Cset)
632{
633  for (CFListIterator i= PS; i.hasItem(); i++)
634  {
635    if (!member (i.getItem(), Cset))
636      return 0;
637  }
638  return 1;
639}
640
641// Union of two List of Lists
642static ListCFList
643MyUnion (const ListCFList& a, const ListCFList& b)
644{
645  if (a.isEmpty())
646    return b;
647  if (b.isEmpty())
648    return a;
649
650  ListCFList output;
651  ListCFListIterator i;
652  CFList elem;
653
654  for (i= a; i.hasItem(); i++)
655  {
656    elem= i.getItem();
657    if ((!elem.isEmpty()) && (!member (elem, output)))
658      output.append(elem);
659  }
660
661  for (i= b; i.hasItem(); i++)
662  {
663    elem= i.getItem();
664    if ((!elem.isEmpty()) && (!member (elem, output)))
665      output.append(elem);
666  }
667  return output;
668}
669
670// Union of a and b stored in b
671void
672MyUnion2 (const ListCFList& a, ListCFList& b)
673{
674  if (a.isEmpty())
675    return;
676  if (b.isEmpty())
677  {
678    b= a;
679    return;
680  }
681
682  ListCFListIterator i;
683  CFList elem;
684
685  for (i= a; i.hasItem(); i++)
686  {
687    elem= i.getItem();
688    if ((!elem.isEmpty()) && (!member (elem, b)))
689      b.insert(elem);
690  }
691}
692
693//if list b is member of the list of lists remove b and return the rest
694static ListCFList
695MyDifference (const ListCFList& a, const CFList& b)
696{
697  ListCFList output;
698  ListCFListIterator i;
699  CFList elem;
700
701  for (i= a; i.hasItem(); i++)
702  {
703    elem= i.getItem();
704    if ((!elem.isEmpty()) && (!same (elem, b)))
705      output.append (elem);
706  }
707  return output;
708}
709
710// remove all elements of b from list of lists a and return the rest
711static ListCFList
712Minus( const ListCFList& a, const ListCFList& b)
713{
714  ListCFList output= a;
715
716  for (ListCFListIterator i=b; i.hasItem(); i++)
717    output = MyDifference (output, i.getItem());
718
719  return output;
720}
721
722static ListCFList
723adjoin (const CFList& is, const CFList& qs, const ListCFList& qh)
724{
725  ListCFList iss, qhi;
726  ListCFListIterator j;
727  CFList iscopy, itt;
728  CFListIterator i;
729  int ind, length;
730
731  for (i= is; i.hasItem(); i++)
732  {
733    if (i.getItem().level() > 0)
734      iscopy= Union (CFList (i.getItem()), iscopy);
735  }
736  if (iscopy.isEmpty())
737    return iss;
738
739  qhi= MyDifference (qh, qs);
740  length= qhi.length();
741
742  for (i= iscopy; i.hasItem(); i++)
743  {
744    itt= Union (qs, CFList (i.getItem()));
745    ind= 0;
746    if (length > 0)
747    {
748      for (j= qhi; j.hasItem(); j++)
749      {
750        if (subset (j.getItem(), itt))
751          ind= 1;
752      }
753    }
754    if (ind == 0)
755      iss.append (itt);
756  }
757  return iss;
758}
759
760static ListCFList
761adjoinb (const CFList & is, const CFList & qs, const ListCFList & qh ,const CFList & cs)
762{
763  ListCFList iss, qhi;
764  ListCFListIterator j;
765  CFList iscopy, itt;
766  CFListIterator i;
767  int ind, length;
768
769  for (i= is ; i.hasItem(); i++)
770  {
771    if (i.getItem().level() > 0)
772      iscopy= Union (CFList (i.getItem()), iscopy);
773  }
774  if (iscopy.isEmpty())
775    return iss;
776  qhi= MyDifference (qh, qs);
777  length= qhi.length();
778  for (i= iscopy; i.hasItem(); i++)
779  {
780    itt= Union (Union (qs, CFList (i.getItem())), cs);
781    ind= 0;
782    if (length > 0)
783    {
784      for (j= qhi; j.hasItem(); j++)
785      {
786        if (subset (j.getItem(), itt))
787          ind= 1;
788      }
789    }
790    if (ind == 0)
791      iss.append(itt);
792  }
793  return iss;
794}
795
796static void
797select (const ListCFList& ppi, int length, ListCFList& ppi1, ListCFList& ppi2)
798{
799  CFList elem;
800  for (ListCFListIterator i=ppi; i.hasItem(); i++)
801  {
802    elem = i.getItem();
803    if (!elem.isEmpty())
804    {
805      if (length <= elem.length())
806        ppi2.append(elem);
807      else
808        ppi1.append(elem);
809    }
810  }
811}
812
813CanonicalForm normalize (const CanonicalForm& F)
814{
815  if (F.isZero())
816    return F;
817  if (getCharacteristic() == 0)
818  {
819    CanonicalForm G;
820    bool isRat= isOn (SW_RATIONAL);
821    if (!isRat)
822      On (SW_RATIONAL);
823    G= F/lc(F);
824    G *= bCommonDen (G);
825    if (!isRat)
826      Off (SW_RATIONAL);
827    return G;
828  }
829
830  return F/lc (F);
831}
832
833static
834CanonicalForm
835Prem (const CanonicalForm& F, const CanonicalForm& G)
836{
837  CanonicalForm f, g, l, test, lu, lv, t, retvalue;
838  int degF, degG, levelF, levelG;
839  bool reord;
840  Variable v, vg= G.mvar();
841
842  if ( (levelF= F.level()) < (levelG= G.level()))
843    return F;
844  else
845  {
846    if ( levelF == levelG )
847    {
848      f= F;
849      g= G;
850      reord= false;
851      v= F.mvar();
852    }
853    else
854    {
855      v= Variable (levelF + 1);
856      f= swapvar (F, vg, v);
857      g= swapvar (G, vg, v);
858      reord= true;
859    }
860    degG= degree (g, v );
861    degF= degree (f, v );
862    if (degG <= degF)
863    {
864      l= LC (g);
865      g= g - l*power (v, degG);
866    }
867    else
868      l= 1;
869    while ((degG <= degF) && (!f.isZero()))
870    {
871      test= gcd (l, LC(f));
872      lu= l / test;
873      lv= LC(f) / test;
874
875      t= power (v, degF - degG)*g*lv;
876
877      if (degF == 0)
878        f= 0;
879      else
880        f= f - LC (f)*power (v, degF);
881
882      f= lu*f - t;
883      degF= degree (f, v);
884    }
885
886    if (reord)
887      retvalue= swapvar (f, vg, v);
888    else
889      retvalue= f;
890
891    return retvalue;
892  }
893}
894
895static
896CanonicalForm
897Prem( const CanonicalForm &f, const CFList &L)
898{
899  CanonicalForm rem= f;
900  CFListIterator i= L;
901
902  for (i.lastItem(); i.hasItem(); i--)
903    rem= normalize (Prem (rem, i.getItem()));
904
905  return rem;
906}
907
908
909CFList uniGcd (const CFList& L)
910{
911  CFList tmp;
912  CanonicalForm g;
913  CFListIterator i;
914  for (i= L; i.hasItem(); i++)
915  {
916    if (i.getItem().isUnivariate() && i.getItem().level() == 1)
917      tmp.append (i.getItem());
918  }
919  if (tmp.length() <= 2)
920    return L;
921  i= tmp;
922  g= i.getItem();
923  i++;
924  g= gcd (g,i.getItem());
925  i++;
926  for (; i.hasItem(); i++)
927    g= gcd (g, i.getItem());
928  return Union (Difference (L, tmp), CFList (g));
929}
930
931
932CFList
933factorsOfInitials(const CFList & L)
934{
935  CFList result;
936  CFFList factors;
937  CanonicalForm tmp;
938
939  for (CFListIterator i= L; i.hasItem(); i++)
940  {
941    factors= factorize (LC(i.getItem()));
942    for (CFFListIterator j= factors; j.hasItem(); j++)
943    {
944      tmp= j.getItem().factor();
945      if (!tmp.inCoeffDomain())
946        result= Union (result, CFList (normalize (tmp)));
947    }
948  }
949
950  return result;
951}
952
953void
954removeContent (CanonicalForm& F, CanonicalForm& cF)
955{
956  if (size (F) == 1)
957  {
958    CanonicalForm tmp= F;
959    F= F.mvar();
960    cF= tmp/F;
961    if (!cF.inCoeffDomain())
962      cF= normalize (cF);
963    else
964      cF= 0;
965
966    return;
967  }
968
969  cF= content (F);
970
971  if (cF.inCoeffDomain())
972    cF= 0;
973  else
974    cF= normalize (cF);
975}
976
977CFList
978factorPSet (const CFList& PS)
979{
980  CFList result;
981  CFFList factors;
982  CFFListIterator j;
983
984  for (CFListIterator i= PS; i. hasItem(); i++)
985  {
986    factors= factorize (i.getItem());
987    if (factors.getFirst().factor().inCoeffDomain())
988      factors.removeFirst();
989    for (j= factors; j.hasItem(); j++ )
990      result= Union (result, CFList (normalize (j.getItem().factor())));
991  }
992  return result;
993}
994
995void
996removeFactors (CanonicalForm& r, StoreFactors& StoredFactors,
997               CFList& removedFactors)
998{
999  CanonicalForm quot;
1000  CFList testlist;
1001  int n= level(r);
1002  bool divides;
1003  CFListIterator j;
1004
1005  for (int i=1; i<= n; i++)
1006    testlist.append (CanonicalForm (Variable (i)));
1007
1008  for (j= StoredFactors.FS1; j.hasItem(); j++)
1009  {
1010    while (fdivides (j.getItem(), r, quot))
1011    {
1012      if (!quot.inCoeffDomain())
1013        r= quot;
1014      else
1015        break;
1016    }
1017  }
1018
1019  // remove already removed factors
1020  for (j= StoredFactors.FS2; j.hasItem(); j++)
1021  {
1022    divides= false;
1023    while (fdivides (j.getItem(), r, quot))
1024    {
1025      if (!quot.inCoeffDomain())
1026      {
1027        divides= true;
1028        r= quot;
1029      }
1030      else
1031        break;
1032    }
1033    if (divides)
1034      removedFactors= Union (removedFactors, CFList (j.getItem()));
1035  }
1036  r= normalize (r);
1037
1038  // remove variables
1039  for (j= testlist; j.hasItem() && !r.isOne(); j++)
1040  {
1041    while (fdivides (j.getItem(), r, quot))
1042    {
1043      if (!quot.inCoeffDomain())
1044        r= quot;
1045      else
1046        break;
1047      removedFactors= Union (removedFactors, CFList (j.getItem()));
1048    }
1049  }
1050}
1051
1052
1053static bool
1054contractsub (const CFList& cs1, const CFList& cs2)
1055{
1056  CFListIterator i;
1057
1058  CanonicalForm r;
1059  for (i= cs1; i.hasItem(); i++)
1060  {
1061    if (Prem (i.getItem(), cs2) != 0)
1062      return false;
1063  }
1064
1065  CFList is= factorsOfInitials (cs1);
1066
1067  for (i= is; i.hasItem(); i++)
1068  {
1069    if (Prem (i.getItem(), cs2) == 0)
1070      return false;
1071  }
1072  return true;
1073}
1074
1075static ListCFList
1076contract (const ListCFList& cs)
1077{
1078  ListCFList mem, ts;
1079  CFList iitem, jitem;
1080
1081  if (cs.length() < 2)
1082    return cs;
1083
1084  int l= cs.length();
1085  int ii= 1;
1086  ListCFListIterator j;
1087  for (ListCFListIterator i= cs; i.hasItem() && ii < l; i++, ii++)
1088  {
1089    iitem= i.getItem();
1090    if (!member (iitem, mem))
1091    {
1092      j= i;
1093      j++;
1094      for (; j.hasItem(); j++)
1095      {
1096        jitem= j.getItem();
1097        if (!member (jitem, mem))
1098        {
1099          if (contractsub (iitem, jitem))
1100          {
1101            ts.append (jitem);
1102            mem.append (jitem);
1103          }
1104          else
1105          {
1106            if (contractsub (jitem, iitem))
1107              ts.append (iitem); // no mem.append (item) because we assume cs does not contain duplicate entries
1108          }
1109        }
1110      }
1111    }
1112  }
1113  return Minus (cs,ts);
1114}
1115
1116
1117CFList
1118basicSet (const CFList &PS)
1119{
1120  CFList QS= PS, BS, RS;
1121  CanonicalForm b;
1122  int cb, degb;
1123
1124  if (PS.length() < 2)
1125    return PS;
1126
1127  CFListIterator i;
1128
1129  while (!QS.isEmpty())
1130  {
1131    b= lowestRank (QS);
1132    cb= b.level();
1133
1134    BS= Union(CFList (b), BS);
1135
1136    if (cb <= 0)
1137      return CFList();
1138    else
1139    {
1140      degb= degree (b);
1141      RS= CFList();
1142      for (i= QS; i.hasItem(); i++)
1143      {
1144        if (degree (i.getItem(), cb) < degb)
1145          RS= Union (CFList (i.getItem()), RS);
1146      }
1147      QS= RS;
1148    }
1149  }
1150
1151  return BS;
1152}
1153
1154CFList
1155charSet (const CFList &PS)
1156{
1157  CFList QS= PS, RS= PS, CSet, tmp;
1158  CFListIterator i;
1159  CanonicalForm r;
1160
1161  while (!RS.isEmpty())
1162  {
1163    CSet= basicSet (QS);
1164
1165    RS= CFList();
1166    if (CSet.length() > 0 && CSet.getFirst().level() > 0)
1167    {
1168      tmp= Difference (QS, CSet);
1169      for (i= tmp; i.hasItem(); i++)
1170      {
1171        r= Prem (i.getItem(), CSet);
1172        if (r != 0)
1173          RS= Union (RS, CFList (r));
1174      }
1175      QS= Union (QS, RS);
1176    }
1177  }
1178
1179  return CSet;
1180}
1181
1182/// medial set
1183CFList
1184charSetN (const CFList &PS)
1185{
1186  CFList QS= PS, RS= PS, CSet, tmp;
1187  CFListIterator i;
1188  CanonicalForm r;
1189
1190  while (!RS.isEmpty())
1191  {
1192    QS= uniGcd (QS);
1193    CSet= basicSet (QS);
1194
1195    RS= CFList();
1196    if (CSet.length() > 0 && CSet.getFirst().level() > 0)
1197    {
1198      tmp= Difference (QS, CSet);
1199      for (i= tmp; i.hasItem(); i++)
1200      {
1201        r= Prem (i.getItem(), CSet);
1202        if (!r.isZero())
1203          RS= Union (RS, CFList (r));
1204      }
1205      QS= Union (CSet, RS);
1206    }
1207  }
1208
1209  return CSet;
1210}
1211
1212/// compute a characteristic set via medial set
1213CFList
1214charSetViaCharSetN (const CFList& PS)
1215{
1216  CFList result= charSetN (PS);
1217  if (result.isEmpty() || result.getFirst().inCoeffDomain())
1218    return CFList(1);
1219  CanonicalForm r;
1220  CFList RS;
1221  for (CFListIterator i= PS; i.hasItem(); i++)
1222  {
1223    r= Prem (i.getItem(), result);
1224    if (!r.isZero())
1225      RS= Union (RS, CFList (r));
1226  }
1227  if (RS.isEmpty())
1228    return result;
1229  return charSetViaCharSetN (Union (PS,Union (RS, result)));
1230}
1231
1232/// modified medial set
1233CFList
1234modCharSet (const CFList& L, StoreFactors& StoredFactors)
1235{
1236  CFList QS= L, RS= L, CSet, tmp, contents, initial, removedFactors;
1237  CFListIterator i;
1238  CanonicalForm r, cF;
1239  bool noRemainder= true;
1240  StoreFactors StoredFactors2, StoredFactors3;
1241
1242  QS= uniGcd (L);
1243
1244  while (!RS.isEmpty())
1245  {
1246    noRemainder= true;
1247    CSet= basicSet (QS);
1248
1249    initial= factorsOfInitials (CSet);
1250
1251    StoredFactors2.FS1= StoredFactors.FS1;
1252    StoredFactors2.FS2= Union (StoredFactors2.FS2, initial);
1253
1254    RS= CFList();
1255
1256    if (CSet.length() > 0 && CSet.getFirst().level() > 0)
1257    {
1258      tmp= Difference (QS, CSet);
1259
1260      for (i= tmp; i.hasItem(); i++)
1261      {
1262        r= Prem (i.getItem(), CSet);
1263        if (!r.isZero())
1264        {
1265          noRemainder= false;
1266          removeContent (r, cF);
1267
1268          if (!cF.isZero())
1269            contents= Union (contents, factorPSet (CFList(cF))); //factorPSet maybe too much it should suffice to do a squarefree factorization instead
1270
1271          removeFactors (r, StoredFactors2, removedFactors);
1272          StoredFactors2.FS1= Union (StoredFactors2.FS1, removedFactors);
1273          StoredFactors2.FS2= Difference (StoredFactors2.FS2, removedFactors);
1274
1275          removedFactors= CFList();
1276
1277          RS= Union (RS, CFList (r));
1278        }
1279      }
1280
1281      if (!noRemainder)
1282      {
1283        StoredFactors.FS1= Union (StoredFactors2.FS1, contents);
1284        StoredFactors.FS2= StoredFactors2.FS2;
1285      }
1286      else
1287        StoredFactors= StoredFactors2;
1288
1289      QS= Union (CSet, RS);
1290
1291      contents= CFList();
1292      removedFactors= CFList();
1293    }
1294    else
1295      StoredFactors= StoredFactors2;
1296  }
1297
1298  return CSet;
1299}
1300
1301/// characteristic set via modified medial set
1302CFList
1303charSetViaModCharSet (const CFList& PS, StoreFactors& StoredFactors)
1304{
1305  CFList result= modCharSet (PS, StoredFactors);
1306  if (result.isEmpty() || result.getFirst().inCoeffDomain())
1307    return CFList(1);
1308  CanonicalForm r;
1309  CFList RS;
1310  CFList tmp= Difference (PS, result);
1311  for (CFListIterator i= tmp; i.hasItem(); i++)
1312  {
1313    r= Prem (i.getItem(), result);
1314    if (!r.isZero())
1315      RS= Union (RS, CFList (r));
1316  }
1317  if (RS.isEmpty())
1318    return result;
1319
1320  return charSetViaModCharSet (Union (PS, Union (RS, result)), StoredFactors);
1321}
1322
1323CFList
1324charSetViaModCharSet (const CFList& PS)
1325{
1326  StoreFactors tmp;
1327  return charSetViaModCharSet (PS, tmp);
1328}
1329
1330CFList
1331modCharSet (const CFList& PS)
1332{
1333  StoreFactors tmp;
1334  return modCharSet (PS, tmp);
1335}
1336
1337ListCFList
1338charSeries (const CFList& L)
1339{
1340  ListCFList tmp, result, tmp2, ppi1, ppi2, qqi, ppi, alreadyConsidered;
1341  CFList l, charset, ini;
1342
1343  int count= 0;
1344  int highestLevel= 1;
1345  CFListIterator iter;
1346
1347  StoreFactors StoredFactors;
1348
1349  l= L;
1350
1351  for (iter= l; iter.hasItem(); iter++)
1352  {
1353    iter.getItem()= normalize (iter.getItem());
1354    if (highestLevel < iter.getItem().level())
1355      highestLevel= iter.getItem().level();
1356  }
1357
1358  tmp= ListCFList (l);
1359
1360  while (!tmp.isEmpty())
1361  {
1362    sortListCFList (tmp);
1363
1364    l= tmp.getFirst();
1365
1366    tmp= MyDifference (tmp, l);
1367
1368    select (ppi, l.length(), ppi1, ppi2);
1369
1370    MyUnion2 (ppi2, qqi);
1371
1372    if (count > 0)
1373      ppi= MyUnion (ListCFList (l), ppi1);
1374    else
1375      ppi= ListCFList();
1376
1377    if (l.length() - 3 < highestLevel)
1378      charset= charSetViaModCharSet (l, StoredFactors);
1379    else
1380      charset= charSetViaCharSetN (l);
1381
1382    if (charset.length() > 0 && charset.getFirst().level() > 0)
1383    {
1384      result= MyUnion (result, ListCFList (charset));
1385      ini= factorsOfInitials (charset);
1386
1387      ini= Union (ini, factorPSet (StoredFactors.FS1));
1388      sortCFListByLevel (ini);
1389    }
1390    else
1391    {
1392      ini= factorPSet (StoredFactors.FS1);
1393      sortCFListByLevel (ini);
1394    }
1395
1396    tmp2= adjoin (ini, l, qqi);
1397    tmp= MyUnion (tmp, tmp2);
1398
1399    StoredFactors.FS1= CFList();
1400    StoredFactors.FS2= CFList();
1401
1402    ppi1= ListCFList();
1403    ppi2= ListCFList();
1404
1405    count++;
1406  }
1407
1408  //TODO need to remove superflous components
1409
1410  return result;
1411}
1412
1413static bool
1414irreducible (const CFList & AS)
1415{
1416// AS is given by AS = { A1, A2, .. Ar }, d_i = degree(Ai)
1417
1418// 1) we test: if d_i > 1, d_j =1 for all j<>i, then AS is irreducible.
1419  bool deg1= true;
1420  for (CFListIterator i= AS ; i.hasItem(); i++)
1421  {
1422    if (degree (i.getItem()) > 1)
1423    {
1424      if (deg1)
1425        deg1= false;
1426      else
1427        return false; // found 2nd poly with deg > 1
1428    }
1429  }
1430  return true;
1431}
1432
1433static CFList
1434irredAS (CFList & AS, int & indexRed, CanonicalForm & reducible)
1435{
1436  CFFList qs;
1437  CFList ts, as;
1438  CanonicalForm elem;
1439  bool ind= true;
1440  int nr= 0, success= -1;
1441  CFListIterator i;
1442
1443  indexRed= 0;
1444  for (i= AS; i.hasItem(); i++ )
1445  {
1446    nr += 1;
1447    if (degree(i.getItem()) > 1)
1448    {
1449      qs= factorize (i.getItem());
1450      if (qs.getFirst().factor().inCoeffDomain())
1451        qs.removeFirst();
1452    }
1453    else
1454      qs= CFFList (CFFactor(i.getItem(),1));
1455
1456    if ((qs.length() >= 2 ) || (qs.getFirst().exp() > 1))
1457    {
1458      indexRed= nr;
1459      ind= false;
1460      reducible= i.getItem();
1461      break;
1462    }
1463  }
1464
1465  if (ind)
1466  {
1467    if (irreducible (AS))  // as quasilinear? => irreducible!
1468      indexRed= 0;
1469    else
1470    {
1471      i= AS;
1472      for (nr= 1; nr< AS.length(); nr++)
1473      {
1474        as.append (i.getItem());
1475        i++;
1476        if (degree (i.getItem()) > 1)
1477        {  // search for a non linear elem
1478          qs= newfactoras (i.getItem(), as, success);
1479          if (qs.length() > 1 || qs.getFirst().exp() > 1)
1480          { //found elem is reducible
1481            reducible= i.getItem();
1482            indexRed= nr + 1;
1483            break;
1484          }
1485        }
1486      }
1487    }
1488  }
1489  for (CFFListIterator k= qs; k.hasItem(); k++)
1490    ts.append (k.getItem().factor());
1491  return ts;
1492}
1493
1494ListCFList
1495irrCharSeries (const CFList & PS)
1496{
1497  CanonicalForm reducible, reducible2;
1498  CFList qs, cs, factorset, is, ts;
1499  ListCFList pi, ppi, qqi, qsi, iss, qhi= ListCFList(PS);
1500
1501  StoreFactors StoredFactors;
1502
1503  int nr_of_iteration= 0, indexRed, highestlevel= 0;
1504
1505  for (CFListIterator iter= PS; iter.hasItem(); iter++)
1506  {
1507    if (level (iter.getItem()) > highestlevel)
1508      highestlevel= level(iter.getItem());
1509  }
1510
1511  while (!qhi.isEmpty())
1512  {
1513    sortListCFList (qhi);
1514
1515    qs= qhi.getFirst();
1516
1517    ListCFList ppi1,ppi2;
1518    select (ppi, qs.length(), ppi1, ppi2);
1519
1520    MyUnion2 (ppi2, qqi);
1521
1522    if (nr_of_iteration == 0)
1523    {
1524      nr_of_iteration += 1;
1525      ppi= ListCFList();
1526    }
1527    else
1528    {
1529      nr_of_iteration += 1;
1530      ppi= MyUnion (ListCFList(qs), ppi1);
1531    }
1532
1533    cs= charSetViaModCharSet (qs, StoredFactors);
1534
1535    //cs = removeContent (cs, StoredFactors); //do I really need it
1536    factorset= StoredFactors.FS2;
1537
1538    if (cs.getFirst().level() > 0)
1539    {
1540      ts= irredAS (cs, indexRed, reducible);
1541
1542      if (indexRed <= 0) // irreducible
1543      {
1544        if (!subset (cs,qs))
1545          cs= charSetViaCharSetN (Union (qs,cs));
1546        if (!member (cs, pi))
1547        {
1548          pi= MyUnion (pi, ListCFList (cs));
1549          if (cs.getFirst().level() > 0)
1550          {
1551            ts= irredAS (cs, indexRed, reducible);
1552
1553            if (indexRed <= 0) //irreducible
1554            {
1555              qsi= MyUnion (qsi, ListCFList(cs));
1556              if (cs.length() == highestlevel)
1557                is= factorPSet (factorset);
1558              else
1559                is= Union (factorsOfInitials (cs), factorPSet (factorset));
1560              iss= adjoin (is, qs, qqi);
1561            }
1562          }
1563          else
1564            iss= adjoin (factorPSet (factorset), qs, qqi);
1565        }
1566        else
1567          iss= adjoin (factorPSet (factorset), qs, qqi);
1568      }
1569
1570      if (indexRed > 0)
1571      {
1572        is= factorPSet (factorset);
1573        if (indexRed > 1)
1574        {
1575          CFList cst;
1576          for (CFListIterator i=cs ; i.hasItem(); i++)
1577          {
1578            if (i.getItem() == reducible)
1579              break;
1580            else 
1581              cst.append(i.getItem());
1582          }
1583          is= Union (factorsOfInitials (cst), is);
1584          iss= MyUnion (adjoin (is, qs, qqi), adjoinb (ts, qs, qqi, cst));
1585        }
1586        else
1587          iss= adjoin (Union (is, ts), qs, qqi);
1588      }
1589    }
1590    else
1591      iss= adjoin (factorPSet (factorset), qs, qqi);
1592    if (qhi.length() > 1)
1593    {
1594      qhi.removeFirst();
1595      qhi= MyUnion (qhi, iss);
1596    }
1597    else
1598      qhi= iss;
1599  }
1600  if (!qsi.isEmpty())
1601    return contract (qsi);
1602  return ListCFList() ;
1603}
1604
Note: See TracBrowser for help on using the repository browser.