source: git/factory/cfCharSets.cc @ 78e3b3b

spielwiese
Last change on this file since 78e3b3b was 78e3b3b, checked in by Martin Lee <martinlee84@…>, 10 years ago
chg: added Premb and improved normalize
  • Property mode set to 100644
File size: 35.0 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;
824    G *= bCommonDen (G);
825    if (!isRat)
826      Off (SW_RATIONAL);
827    if (isRat)
828      Off (SW_RATIONAL);
829    G= F/icontent (F);
830    if (isRat)
831      On (SW_RATIONAL);
832    return G;
833  }
834
835  return F/lc (F);
836}
837
838static
839CanonicalForm
840Prem (const CanonicalForm& F, const CanonicalForm& G)
841{
842  CanonicalForm f, g, l, test, lu, lv, t, retvalue;
843  int degF, degG, levelF, levelG;
844  bool reord;
845  Variable v, vg= G.mvar();
846
847  if ( (levelF= F.level()) < (levelG= G.level()))
848    return F;
849  else
850  {
851    if ( levelF == levelG )
852    {
853      f= F;
854      g= G;
855      reord= false;
856      v= F.mvar();
857    }
858    else
859    {
860      v= Variable (levelF + 1);
861      f= swapvar (F, vg, v);
862      g= swapvar (G, vg, v);
863      reord= true;
864    }
865    degG= degree (g, v );
866    degF= degree (f, v );
867    if (degG <= degF)
868    {
869      l= LC (g);
870      g= g - l*power (v, degG);
871    }
872    else
873      l= 1;
874    while ((degG <= degF) && (!f.isZero()))
875    {
876      test= gcd (l, LC(f));
877      lu= l / test;
878      lv= LC(f) / test;
879
880      t= power (v, degF - degG)*g*lv;
881
882      if (degF == 0)
883        f= 0;
884      else
885        f= f - LC (f)*power (v, degF);
886
887      f= lu*f - t;
888      degF= degree (f, v);
889    }
890
891    if (reord)
892      retvalue= swapvar (f, vg, v);
893    else
894      retvalue= f;
895
896    return retvalue;
897  }
898}
899
900static
901CanonicalForm
902Premb (const CanonicalForm &f, const CFList &L)
903{
904  CanonicalForm rem= f;
905  CFList l= L;
906  l.removeFirst();
907  CFListIterator i= l;
908
909  for (i.lastItem(); i.hasItem(); i--)
910    rem= normalize (Prem (rem, i.getItem()));
911
912  CanonicalForm tmp= L.getFirst()/content (L.getFirst());
913
914  bool isRat= isOn (SW_RATIONAL);
915  if (getCharacteristic() == 0 && !isRat)
916    On (SW_RATIONAL);
917  if (fdivides (tmp, rem))
918  {
919    if (getCharacteristic() == 0 && !isRat)
920      Off (SW_RATIONAL);
921    return 0;
922  }
923
924  if (getCharacteristic() == 0 && !isRat)
925    Off (SW_RATIONAL);
926
927  rem= normalize (Prem (rem, L.getFirst()));
928
929  return rem;
930}
931
932static
933CanonicalForm
934Prem (const CanonicalForm &f, const CFList &L)
935{
936  CanonicalForm rem= f;
937  CFListIterator i= L;
938
939  for (i.lastItem(); i.hasItem(); i--)
940    rem= normalize (Prem (rem, i.getItem()));
941
942  return rem;
943}
944
945CFList uniGcd (const CFList& L)
946{
947  CFList tmp;
948  CanonicalForm g;
949  CFListIterator i;
950  for (i= L; i.hasItem(); i++)
951  {
952    if (i.getItem().isUnivariate() && i.getItem().level() == 1)
953      tmp.append (i.getItem());
954  }
955  if (tmp.length() <= 2)
956    return L;
957  i= tmp;
958  g= i.getItem();
959  i++;
960  g= gcd (g,i.getItem());
961  i++;
962  for (; i.hasItem(); i++)
963    g= gcd (g, i.getItem());
964  return Union (Difference (L, tmp), CFList (g));
965}
966
967
968CFList
969factorsOfInitials(const CFList & L)
970{
971  CFList result;
972  CFFList factors;
973  CanonicalForm tmp;
974
975  for (CFListIterator i= L; i.hasItem(); i++)
976  {
977    factors= factorize (LC (i.getItem()));
978    for (CFFListIterator j= factors; j.hasItem(); j++)
979    {
980      tmp= j.getItem().factor();
981      if (!tmp.inCoeffDomain())
982        result= Union (result, CFList (normalize (tmp)));
983    }
984  }
985
986  return result;
987}
988
989void
990removeContent (CanonicalForm& F, CanonicalForm& cF)
991{
992  if (size (F) == 1)
993  {
994    CanonicalForm tmp= F;
995    F= F.mvar();
996    cF= tmp/F;
997    if (!cF.inCoeffDomain())
998      cF= normalize (cF);
999    else
1000      cF= 0;
1001
1002    return;
1003  }
1004
1005  cF= content (F);
1006
1007  if (cF.inCoeffDomain())
1008    cF= 0;
1009  else
1010  {
1011    cF= normalize (cF);
1012    F /= cF;
1013    F= normalize (F);
1014  }
1015}
1016
1017CFList
1018factorPSet (const CFList& PS)
1019{
1020  CFList result;
1021  CFFList factors;
1022  CFFListIterator j;
1023
1024  for (CFListIterator i= PS; i. hasItem(); i++)
1025  {
1026    factors= factorize (i.getItem());
1027    if (factors.getFirst().factor().inCoeffDomain())
1028      factors.removeFirst();
1029    for (j= factors; j.hasItem(); j++ )
1030      result= Union (result, CFList (normalize (j.getItem().factor())));
1031  }
1032  return result;
1033}
1034
1035void
1036removeFactors (CanonicalForm& r, StoreFactors& StoredFactors,
1037               CFList& removedFactors)
1038{
1039  CanonicalForm quot;
1040  CFList testlist;
1041  int n= level(r);
1042  bool divides;
1043  CFListIterator j;
1044
1045  for (int i=1; i<= n; i++)
1046    testlist.append (CanonicalForm (Variable (i)));
1047
1048  for (j= StoredFactors.FS1; j.hasItem(); j++)
1049  {
1050    while (fdivides (j.getItem(), r, quot))
1051    {
1052      if (!quot.inCoeffDomain())
1053        r= quot;
1054      else
1055        break;
1056    }
1057  }
1058
1059  // remove already removed factors
1060  for (j= StoredFactors.FS2; j.hasItem(); j++)
1061  {
1062    divides= false;
1063    while (fdivides (j.getItem(), r, quot))
1064    {
1065      if (!quot.inCoeffDomain())
1066      {
1067        divides= true;
1068        r= quot;
1069      }
1070      else
1071        break;
1072    }
1073    if (divides)
1074      removedFactors= Union (removedFactors, CFList (j.getItem()));
1075  }
1076  r= normalize (r);
1077
1078  // remove variables
1079  for (j= testlist; j.hasItem() && !r.isOne(); j++)
1080  {
1081    while (fdivides (j.getItem(), r, quot))
1082    {
1083      if (!quot.inCoeffDomain())
1084        r= quot;
1085      else
1086        break;
1087      removedFactors= Union (removedFactors, CFList (j.getItem()));
1088    }
1089  }
1090}
1091
1092CFList
1093removeContent (const CFList & PS, StoreFactors & StoredFactors)
1094{
1095  CFListIterator i= PS;
1096  if ((!i.hasItem()) || (PS.getFirst().level() == 0 ))
1097    return PS;
1098
1099  CFList output;
1100  CanonicalForm cc,elem;
1101
1102  for (; i.hasItem(); i++)
1103  {
1104    elem= i.getItem();
1105    cc= content (elem, elem.mvar());
1106    if (cc.level() > 0 )
1107    {
1108      output.append (elem / cc);
1109      StoredFactors.FS1 = Union (CFList (cc), StoredFactors.FS1);
1110    }
1111    else
1112      output.append(elem);
1113  }
1114  return output;
1115}
1116
1117static bool
1118contractsub (const CFList& cs1, const CFList& cs2)
1119{
1120  CFListIterator i;
1121
1122  CanonicalForm r;
1123  for (i= cs1; i.hasItem(); i++)
1124  {
1125    if (Prem (i.getItem(), cs2) != 0)
1126      return false;
1127  }
1128
1129  CFList is= factorsOfInitials (cs1);
1130
1131  for (i= is; i.hasItem(); i++)
1132  {
1133    if (Prem (i.getItem(), cs2) == 0)
1134      return false;
1135  }
1136  return true;
1137}
1138
1139static ListCFList
1140contract (const ListCFList& cs)
1141{
1142  ListCFList mem, ts;
1143  CFList iitem, jitem;
1144
1145  if (cs.length() < 2)
1146    return cs;
1147
1148  int l= cs.length();
1149  int ii= 1;
1150  ListCFListIterator j;
1151  for (ListCFListIterator i= cs; i.hasItem() && ii < l; i++, ii++)
1152  {
1153    iitem= i.getItem();
1154    if (!member (iitem, mem))
1155    {
1156      j= i;
1157      j++;
1158      for (; j.hasItem(); j++)
1159      {
1160        jitem= j.getItem();
1161        if (!member (jitem, mem))
1162        {
1163          if (contractsub (iitem, jitem))
1164          {
1165            ts.append (jitem);
1166            mem.append (jitem);
1167          }
1168          else
1169          {
1170            if (contractsub (jitem, iitem))
1171              ts.append (iitem); // no mem.append (item) because we assume cs does not contain duplicate entries
1172          }
1173        }
1174      }
1175    }
1176  }
1177  return Minus (cs,ts);
1178}
1179
1180
1181CFList
1182basicSet (const CFList &PS)
1183{
1184  CFList QS= PS, BS, RS;
1185  CanonicalForm b;
1186  int cb, degb;
1187
1188  if (PS.length() < 2)
1189    return PS;
1190
1191  CFListIterator i;
1192
1193  while (!QS.isEmpty())
1194  {
1195    b= lowestRank (QS);
1196    cb= b.level();
1197
1198    BS= Union(CFList (b), BS);
1199
1200    if (cb <= 0)
1201      return CFList();
1202    else
1203    {
1204      degb= degree (b);
1205      RS= CFList();
1206      for (i= QS; i.hasItem(); i++)
1207      {
1208        if (degree (i.getItem(), cb) < degb)
1209          RS= Union (CFList (i.getItem()), RS);
1210      }
1211      QS= RS;
1212    }
1213  }
1214
1215  return BS;
1216}
1217
1218CFList
1219charSet (const CFList &PS)
1220{
1221  CFList QS= PS, RS= PS, CSet, tmp;
1222  CFListIterator i;
1223  CanonicalForm r;
1224
1225  while (!RS.isEmpty())
1226  {
1227    CSet= basicSet (QS);
1228
1229    RS= CFList();
1230    if (CSet.length() > 0 && CSet.getFirst().level() > 0)
1231    {
1232      tmp= Difference (QS, CSet);
1233      for (i= tmp; i.hasItem(); i++)
1234      {
1235        r= Prem (i.getItem(), CSet);
1236        if (r != 0)
1237          RS= Union (RS, CFList (r));
1238      }
1239      QS= Union (QS, RS);
1240    }
1241  }
1242
1243  return CSet;
1244}
1245
1246/// medial set
1247CFList
1248charSetN (const CFList &PS)
1249{
1250  CFList QS= PS, RS= PS, CSet, tmp;
1251  CFListIterator i;
1252  CanonicalForm r;
1253
1254  while (!RS.isEmpty())
1255  {
1256    QS= uniGcd (QS);
1257    CSet= basicSet (QS);
1258
1259    RS= CFList();
1260    if (CSet.length() > 0 && CSet.getFirst().level() > 0)
1261    {
1262      tmp= Difference (QS, CSet);
1263      for (i= tmp; i.hasItem(); i++)
1264      {
1265        r= Prem (i.getItem(), CSet);
1266        if (!r.isZero())
1267          RS= Union (RS, CFList (r));
1268      }
1269      QS= Union (CSet, RS);
1270    }
1271  }
1272
1273  return CSet;
1274}
1275
1276/// compute a characteristic set via medial set
1277CFList
1278charSetViaCharSetN (const CFList& PS)
1279{
1280  CFList result= charSetN (PS);
1281  if (result.isEmpty() || result.getFirst().inCoeffDomain())
1282    return CFList(1);
1283  CanonicalForm r;
1284  CFList RS;
1285  for (CFListIterator i= PS; i.hasItem(); i++)
1286  {
1287    r= Premb (i.getItem(), result);
1288    if (!r.isZero())
1289      RS= Union (RS, CFList (r));
1290  }
1291  if (RS.isEmpty())
1292    return result;
1293  return charSetViaCharSetN (Union (PS, Union (RS, result)));
1294}
1295
1296/// modified medial set
1297CFList
1298modCharSet (const CFList& L, StoreFactors& StoredFactors, bool removeContents)
1299{
1300  CFList QS= L, RS= L, CSet, tmp, contents, initial, removedFactors;
1301  CFListIterator i;
1302  CanonicalForm r, cF;
1303  bool noRemainder= true;
1304  StoreFactors StoredFactors2;
1305
1306  QS= uniGcd (L);
1307
1308  while (!RS.isEmpty())
1309  {
1310    noRemainder= true;
1311    CSet= basicSet (QS);
1312
1313    initial= factorsOfInitials (CSet);
1314
1315    StoredFactors2.FS1= StoredFactors.FS1;
1316    StoredFactors2.FS2= Union (StoredFactors2.FS2, initial);
1317
1318    RS= CFList();
1319
1320    if (CSet.length() > 0 && CSet.getFirst().level() > 0)
1321    {
1322      tmp= Difference (QS, CSet);
1323
1324      for (i= tmp; i.hasItem(); i++)
1325      {
1326        r= Prem (i.getItem(), CSet);
1327        if (!r.isZero())
1328        {
1329          noRemainder= false;
1330          if (removeContents)
1331          {
1332            removeContent (r, cF);
1333
1334            if (!cF.isZero())
1335              contents= Union (contents, factorPSet (CFList(cF))); //factorPSet maybe too much it should suffice to do a squarefree factorization instead
1336          }
1337
1338          removeFactors (r, StoredFactors2, removedFactors);
1339          StoredFactors2.FS1= Union (StoredFactors2.FS1, removedFactors);
1340          StoredFactors2.FS2= Difference (StoredFactors2.FS2, removedFactors);
1341
1342          removedFactors= CFList();
1343
1344          RS= Union (RS, CFList (r));
1345        }
1346      }
1347
1348      if (removeContents && !noRemainder)
1349      {
1350        StoredFactors.FS1= Union (StoredFactors2.FS1, contents);
1351        StoredFactors.FS2= StoredFactors2.FS2;
1352      }
1353      else
1354        StoredFactors= StoredFactors2;
1355
1356      QS= Union (CSet, RS);
1357
1358      contents= CFList();
1359      removedFactors= CFList();
1360    }
1361    else
1362      StoredFactors= StoredFactors2;
1363  }
1364
1365  return CSet;
1366}
1367
1368/// characteristic set via modified medial set
1369CFList
1370charSetViaModCharSet (const CFList& PS, StoreFactors& StoredFactors, bool removeContents)
1371{
1372  CFList result= modCharSet (PS, StoredFactors, removeContents);
1373  if (result.isEmpty() || result.getFirst().inCoeffDomain())
1374    return CFList(1);
1375  CanonicalForm r;
1376  CFList RS;
1377  CFList tmp= Difference (PS, result);
1378  for (CFListIterator i= tmp; i.hasItem(); i++)
1379  {
1380    r= Premb (i.getItem(), result);
1381    if (!r.isZero())
1382      RS= Union (RS, CFList (r));
1383  }
1384  if (RS.isEmpty())
1385    return result;
1386
1387  return charSetViaModCharSet (Union (PS, Union (RS, result)), StoredFactors, removeContents);
1388}
1389
1390CFList
1391charSetViaModCharSet (const CFList& PS, bool removeContents)
1392{
1393  StoreFactors tmp;
1394  return charSetViaModCharSet (PS, tmp, removeContents);
1395}
1396
1397ListCFList
1398charSeries (const CFList& L)
1399{
1400  ListCFList tmp, result, tmp2, ppi1, ppi2, qqi, ppi, alreadyConsidered;
1401  CFList l, charset, ini;
1402
1403  int count= 0;
1404  int highestLevel= 1;
1405  CFListIterator iter;
1406
1407  StoreFactors StoredFactors;
1408
1409  l= L;
1410
1411  for (iter= l; iter.hasItem(); iter++)
1412  {
1413    iter.getItem()= normalize (iter.getItem());
1414    if (highestLevel < iter.getItem().level())
1415      highestLevel= iter.getItem().level();
1416  }
1417
1418  tmp= ListCFList (l);
1419
1420  while (!tmp.isEmpty())
1421  {
1422    sortListCFList (tmp);
1423
1424    l= tmp.getFirst();
1425
1426    tmp= MyDifference (tmp, l);
1427
1428    select (ppi, l.length(), ppi1, ppi2);
1429
1430    MyUnion2 (ppi2, qqi);
1431
1432    if (count > 0)
1433      ppi= MyUnion (ListCFList (l), ppi1);
1434    else
1435      ppi= ListCFList();
1436
1437    if (l.length() - 3 < highestLevel)
1438      charset= charSetViaModCharSet (l, StoredFactors);
1439    else
1440      charset= charSetViaCharSetN (l);
1441
1442    if (charset.length() > 0 && charset.getFirst().level() > 0)
1443    {
1444      result= MyUnion (result, ListCFList (charset));
1445      ini= factorsOfInitials (charset);
1446
1447      ini= Union (ini, factorPSet (StoredFactors.FS1));
1448      sortCFListByLevel (ini);
1449    }
1450    else
1451    {
1452      ini= factorPSet (StoredFactors.FS1);
1453      sortCFListByLevel (ini);
1454    }
1455
1456    tmp2= adjoin (ini, l, qqi);
1457    tmp= MyUnion (tmp, tmp2);
1458
1459    StoredFactors.FS1= CFList();
1460    StoredFactors.FS2= CFList();
1461
1462    ppi1= ListCFList();
1463    ppi2= ListCFList();
1464
1465    count++;
1466  }
1467
1468  //TODO need to remove superflous components
1469
1470  return result;
1471}
1472
1473static bool
1474irreducible (const CFList & AS)
1475{
1476// AS is given by AS = { A1, A2, .. Ar }, d_i = degree(Ai)
1477
1478// 1) we test: if d_i > 1, d_j =1 for all j<>i, then AS is irreducible.
1479  bool deg1= true;
1480  for (CFListIterator i= AS ; i.hasItem(); i++)
1481  {
1482    if (degree (i.getItem()) > 1)
1483    {
1484      if (deg1)
1485        deg1= false;
1486      else
1487        return false; // found 2nd poly with deg > 1
1488    }
1489  }
1490  return true;
1491}
1492
1493static CFList
1494irredAS (CFList & AS, int & indexRed, CanonicalForm & reducible)
1495{
1496  CFFList qs;
1497  CFList ts, as;
1498  CanonicalForm elem;
1499  bool ind= true;
1500  int nr= 0, success= -1;
1501  CFListIterator i;
1502
1503  indexRed= 0;
1504  for (i= AS; i.hasItem(); i++ )
1505  {
1506    nr += 1;
1507    if (degree (i.getItem()) > 1)
1508    {
1509      qs= factorize (i.getItem());
1510      if (qs.getFirst().factor().inCoeffDomain())
1511        qs.removeFirst();
1512    }
1513    else
1514      qs= CFFList (CFFactor (i.getItem(), 1));
1515
1516    if ((qs.length() >= 2 ) || (qs.getFirst().exp() > 1))
1517    {
1518      indexRed= nr;
1519      ind= false;
1520      reducible= i.getItem();
1521      break;
1522    }
1523  }
1524
1525  if (ind)
1526  {
1527    if (irreducible (AS))  // as quasilinear? => irreducible!
1528      indexRed= 0;
1529    else
1530    {
1531      i= AS;
1532      for (nr= 1; nr< AS.length(); nr++)
1533      {
1534        as.append (i.getItem());
1535        i++;
1536        if (degree (i.getItem()) > 1)
1537        {  // search for a non linear elem
1538          qs= newfactoras (i.getItem(), as, success);
1539          if (qs.getFirst().factor().inCoeffDomain())
1540            qs.removeFirst();
1541          if (qs.length() > 1 || qs.getFirst().exp() > 1)
1542          { //found elem is reducible
1543            reducible= i.getItem();
1544            indexRed= nr + 1;
1545            break;
1546          }
1547        }
1548      }
1549    }
1550  }
1551  for (CFFListIterator k= qs; k.hasItem(); k++)
1552    ts.append (k.getItem().factor());
1553  return ts;
1554}
1555
1556ListCFList
1557irrCharSeries (const CFList & PS)
1558{
1559  CanonicalForm reducible, reducible2;
1560  CFList qs, cs, factorset, is, ts;
1561  ListCFList pi, ppi, qqi, qsi, iss, qhi= ListCFList(PS);
1562
1563  int nr_of_iteration= 0, indexRed, highestlevel= 0;
1564
1565  for (CFListIterator iter= PS; iter.hasItem(); iter++)
1566  {
1567    if (level (iter.getItem()) > highestlevel)
1568      highestlevel= level(iter.getItem());
1569  }
1570
1571  while (!qhi.isEmpty())
1572  {
1573    sortListCFList (qhi);
1574
1575    qs= qhi.getFirst();
1576
1577    ListCFList ppi1,ppi2;
1578    select (ppi, qs.length(), ppi1, ppi2);
1579
1580    MyUnion2 (ppi2, qqi);
1581
1582    if (nr_of_iteration == 0)
1583    {
1584      nr_of_iteration += 1;
1585      ppi= ListCFList();
1586    }
1587    else
1588    {
1589      nr_of_iteration += 1;
1590      ppi= MyUnion (ListCFList(qs), ppi1);
1591    }
1592
1593    StoreFactors StoredFactors;
1594    cs= charSetViaModCharSet (qs, StoredFactors);
1595    cs= removeContent (cs, StoredFactors);
1596
1597    factorset= StoredFactors.FS1;
1598
1599    if (cs.getFirst().level() > 0)
1600    {
1601      ts= irredAS (cs, indexRed, reducible);
1602
1603      if (indexRed <= 0) // irreducible
1604      {
1605        if (!subset (cs,qs))
1606          cs= charSetViaCharSetN (Union (qs,cs));
1607        if (!member (cs, pi))
1608        {
1609          pi= MyUnion (pi, ListCFList (cs));
1610          if (cs.getFirst().level() > 0)
1611          {
1612            ts= irredAS (cs, indexRed, reducible);
1613
1614            if (indexRed <= 0) //irreducible
1615            {
1616              qsi= MyUnion (qsi, ListCFList(cs));
1617              if (cs.length() == highestlevel)
1618                is= factorPSet (factorset);
1619              else
1620                is= Union (factorsOfInitials (cs), factorPSet (factorset));
1621              iss= adjoin (is, qs, qqi);
1622            }
1623          }
1624          else
1625            iss= adjoin (factorPSet (factorset), qs, qqi);
1626        }
1627        else
1628          iss= adjoin (factorPSet (factorset), qs, qqi);
1629      }
1630
1631      if (indexRed > 0)
1632      {
1633        is= factorPSet (factorset);
1634        if (indexRed > 1)
1635        {
1636          CFList cst;
1637          for (CFListIterator i= cs ; i.hasItem(); i++)
1638          {
1639            if (i.getItem() == reducible)
1640              break;
1641            else 
1642              cst.append (i.getItem());
1643          }
1644          is= Union (factorsOfInitials (cst), is);
1645          iss= MyUnion (adjoin (is, qs, qqi), adjoinb (ts, qs, qqi, cst));
1646        }
1647        else
1648          iss= adjoin (Union (is, ts), qs, qqi);
1649      }
1650    }
1651    else
1652      iss= adjoin (factorPSet (factorset), qs, qqi);
1653    if (qhi.length() > 1)
1654    {
1655      qhi.removeFirst();
1656      qhi= MyUnion (qhi, iss);
1657    }
1658    else
1659      qhi= iss;
1660  }
1661  if (!qsi.isEmpty())
1662    return contract (qsi);
1663  return ListCFList() ;
1664}
1665
Note: See TracBrowser for help on using the repository browser.