source: git/factory/cfCharSets.cc @ 2a1008a

spielwiese
Last change on this file since 2a1008a was 2a1008a, checked in by Martin Lee <martinlee84@…>, 10 years ago
fix: really remove content
  • Property mode set to 100644
File size: 34.3 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  {
975    cF= normalize (cF);
976    F /= cF;
977    F= normalize (F);
978  }
979}
980
981CFList
982factorPSet (const CFList& PS)
983{
984  CFList result;
985  CFFList factors;
986  CFFListIterator j;
987
988  for (CFListIterator i= PS; i. hasItem(); i++)
989  {
990    factors= factorize (i.getItem());
991    if (factors.getFirst().factor().inCoeffDomain())
992      factors.removeFirst();
993    for (j= factors; j.hasItem(); j++ )
994      result= Union (result, CFList (normalize (j.getItem().factor())));
995  }
996  return result;
997}
998
999void
1000removeFactors (CanonicalForm& r, StoreFactors& StoredFactors,
1001               CFList& removedFactors)
1002{
1003  CanonicalForm quot;
1004  CFList testlist;
1005  int n= level(r);
1006  bool divides;
1007  CFListIterator j;
1008
1009  for (int i=1; i<= n; i++)
1010    testlist.append (CanonicalForm (Variable (i)));
1011
1012  for (j= StoredFactors.FS1; j.hasItem(); j++)
1013  {
1014    while (fdivides (j.getItem(), r, quot))
1015    {
1016      if (!quot.inCoeffDomain())
1017        r= quot;
1018      else
1019        break;
1020    }
1021  }
1022
1023  // remove already removed factors
1024  for (j= StoredFactors.FS2; j.hasItem(); j++)
1025  {
1026    divides= false;
1027    while (fdivides (j.getItem(), r, quot))
1028    {
1029      if (!quot.inCoeffDomain())
1030      {
1031        divides= true;
1032        r= quot;
1033      }
1034      else
1035        break;
1036    }
1037    if (divides)
1038      removedFactors= Union (removedFactors, CFList (j.getItem()));
1039  }
1040  r= normalize (r);
1041
1042  // remove variables
1043  for (j= testlist; j.hasItem() && !r.isOne(); j++)
1044  {
1045    while (fdivides (j.getItem(), r, quot))
1046    {
1047      if (!quot.inCoeffDomain())
1048        r= quot;
1049      else
1050        break;
1051      removedFactors= Union (removedFactors, CFList (j.getItem()));
1052    }
1053  }
1054}
1055
1056CFList
1057removeContent (const CFList & PS, StoreFactors & StoredFactors)
1058{
1059  CFListIterator i= PS;
1060  if ((!i.hasItem()) || (PS.getFirst().level() == 0 ))
1061    return PS;
1062
1063  CFList output;
1064  CanonicalForm cc,elem;
1065
1066  for (; i.hasItem(); i++)
1067  {
1068    elem= i.getItem();
1069    cc= content (elem, elem.mvar());
1070    if (cc.level() > 0 )
1071    {
1072      output.append (elem / cc);
1073      StoredFactors.FS1 = Union (CFList (cc), StoredFactors.FS1);
1074    }
1075    else
1076      output.append(elem);
1077  }
1078  return output;
1079}
1080
1081static bool
1082contractsub (const CFList& cs1, const CFList& cs2)
1083{
1084  CFListIterator i;
1085
1086  CanonicalForm r;
1087  for (i= cs1; i.hasItem(); i++)
1088  {
1089    if (Prem (i.getItem(), cs2) != 0)
1090      return false;
1091  }
1092
1093  CFList is= factorsOfInitials (cs1);
1094
1095  for (i= is; i.hasItem(); i++)
1096  {
1097    if (Prem (i.getItem(), cs2) == 0)
1098      return false;
1099  }
1100  return true;
1101}
1102
1103static ListCFList
1104contract (const ListCFList& cs)
1105{
1106  ListCFList mem, ts;
1107  CFList iitem, jitem;
1108
1109  if (cs.length() < 2)
1110    return cs;
1111
1112  int l= cs.length();
1113  int ii= 1;
1114  ListCFListIterator j;
1115  for (ListCFListIterator i= cs; i.hasItem() && ii < l; i++, ii++)
1116  {
1117    iitem= i.getItem();
1118    if (!member (iitem, mem))
1119    {
1120      j= i;
1121      j++;
1122      for (; j.hasItem(); j++)
1123      {
1124        jitem= j.getItem();
1125        if (!member (jitem, mem))
1126        {
1127          if (contractsub (iitem, jitem))
1128          {
1129            ts.append (jitem);
1130            mem.append (jitem);
1131          }
1132          else
1133          {
1134            if (contractsub (jitem, iitem))
1135              ts.append (iitem); // no mem.append (item) because we assume cs does not contain duplicate entries
1136          }
1137        }
1138      }
1139    }
1140  }
1141  return Minus (cs,ts);
1142}
1143
1144
1145CFList
1146basicSet (const CFList &PS)
1147{
1148  CFList QS= PS, BS, RS;
1149  CanonicalForm b;
1150  int cb, degb;
1151
1152  if (PS.length() < 2)
1153    return PS;
1154
1155  CFListIterator i;
1156
1157  while (!QS.isEmpty())
1158  {
1159    b= lowestRank (QS);
1160    cb= b.level();
1161
1162    BS= Union(CFList (b), BS);
1163
1164    if (cb <= 0)
1165      return CFList();
1166    else
1167    {
1168      degb= degree (b);
1169      RS= CFList();
1170      for (i= QS; i.hasItem(); i++)
1171      {
1172        if (degree (i.getItem(), cb) < degb)
1173          RS= Union (CFList (i.getItem()), RS);
1174      }
1175      QS= RS;
1176    }
1177  }
1178
1179  return BS;
1180}
1181
1182CFList
1183charSet (const CFList &PS)
1184{
1185  CFList QS= PS, RS= PS, CSet, tmp;
1186  CFListIterator i;
1187  CanonicalForm r;
1188
1189  while (!RS.isEmpty())
1190  {
1191    CSet= basicSet (QS);
1192
1193    RS= CFList();
1194    if (CSet.length() > 0 && CSet.getFirst().level() > 0)
1195    {
1196      tmp= Difference (QS, CSet);
1197      for (i= tmp; i.hasItem(); i++)
1198      {
1199        r= Prem (i.getItem(), CSet);
1200        if (r != 0)
1201          RS= Union (RS, CFList (r));
1202      }
1203      QS= Union (QS, RS);
1204    }
1205  }
1206
1207  return CSet;
1208}
1209
1210/// medial set
1211CFList
1212charSetN (const CFList &PS)
1213{
1214  CFList QS= PS, RS= PS, CSet, tmp;
1215  CFListIterator i;
1216  CanonicalForm r;
1217
1218  while (!RS.isEmpty())
1219  {
1220    QS= uniGcd (QS);
1221    CSet= basicSet (QS);
1222
1223    RS= CFList();
1224    if (CSet.length() > 0 && CSet.getFirst().level() > 0)
1225    {
1226      tmp= Difference (QS, CSet);
1227      for (i= tmp; i.hasItem(); i++)
1228      {
1229        r= Prem (i.getItem(), CSet);
1230        if (!r.isZero())
1231          RS= Union (RS, CFList (r));
1232      }
1233      QS= Union (CSet, RS);
1234    }
1235  }
1236
1237  return CSet;
1238}
1239
1240/// compute a characteristic set via medial set
1241CFList
1242charSetViaCharSetN (const CFList& PS)
1243{
1244  CFList result= charSetN (PS);
1245  if (result.isEmpty() || result.getFirst().inCoeffDomain())
1246    return CFList(1);
1247  CanonicalForm r;
1248  CFList RS;
1249  for (CFListIterator i= PS; i.hasItem(); i++)
1250  {
1251    r= Prem (i.getItem(), result);
1252    if (!r.isZero())
1253      RS= Union (RS, CFList (r));
1254  }
1255  if (RS.isEmpty())
1256    return result;
1257  return charSetViaCharSetN (Union (PS,Union (RS, result)));
1258}
1259
1260/// modified medial set
1261CFList
1262modCharSet (const CFList& L, StoreFactors& StoredFactors, bool removeContents)
1263{
1264  CFList QS= L, RS= L, CSet, tmp, contents, initial, removedFactors;
1265  CFListIterator i;
1266  CanonicalForm r, cF;
1267  bool noRemainder= true;
1268  StoreFactors StoredFactors2;
1269
1270  QS= uniGcd (L);
1271
1272  while (!RS.isEmpty())
1273  {
1274    noRemainder= true;
1275    CSet= basicSet (QS);
1276
1277    initial= factorsOfInitials (CSet);
1278
1279    StoredFactors2.FS1= StoredFactors.FS1;
1280    StoredFactors2.FS2= Union (StoredFactors2.FS2, initial);
1281
1282    RS= CFList();
1283
1284    if (CSet.length() > 0 && CSet.getFirst().level() > 0)
1285    {
1286      tmp= Difference (QS, CSet);
1287
1288      for (i= tmp; i.hasItem(); i++)
1289      {
1290        r= Prem (i.getItem(), CSet);
1291        if (!r.isZero())
1292        {
1293          noRemainder= false;
1294          if (removeContents)
1295          {
1296            removeContent (r, cF);
1297
1298            if (!cF.isZero())
1299              contents= Union (contents, factorPSet (CFList(cF))); //factorPSet maybe too much it should suffice to do a squarefree factorization instead
1300          }
1301
1302          removeFactors (r, StoredFactors2, removedFactors);
1303          StoredFactors2.FS1= Union (StoredFactors2.FS1, removedFactors);
1304          StoredFactors2.FS2= Difference (StoredFactors2.FS2, removedFactors);
1305
1306          removedFactors= CFList();
1307
1308          RS= Union (RS, CFList (r));
1309        }
1310      }
1311
1312      if (removeContents && !noRemainder)
1313      {
1314        StoredFactors.FS1= Union (StoredFactors2.FS1, contents);
1315        StoredFactors.FS2= StoredFactors2.FS2;
1316      }
1317      else
1318        StoredFactors= StoredFactors2;
1319
1320      QS= Union (CSet, RS);
1321
1322      contents= CFList();
1323      removedFactors= CFList();
1324    }
1325    else
1326      StoredFactors= StoredFactors2;
1327  }
1328
1329  return CSet;
1330}
1331
1332/// characteristic set via modified medial set
1333CFList
1334charSetViaModCharSet (const CFList& PS, StoreFactors& StoredFactors, bool removeContents)
1335{
1336  CFList result= modCharSet (PS, StoredFactors, removeContents);
1337  if (result.isEmpty() || result.getFirst().inCoeffDomain())
1338    return CFList(1);
1339  CanonicalForm r;
1340  CFList RS;
1341  CFList tmp= Difference (PS, result);
1342  for (CFListIterator i= tmp; i.hasItem(); i++)
1343  {
1344    r= Prem (i.getItem(), result);
1345    if (!r.isZero())
1346      RS= Union (RS, CFList (r));
1347  }
1348  if (RS.isEmpty())
1349    return result;
1350
1351  return charSetViaModCharSet (Union (PS, Union (RS, result)), StoredFactors, removeContents);
1352}
1353
1354CFList
1355charSetViaModCharSet (const CFList& PS, bool removeContents)
1356{
1357  StoreFactors tmp;
1358  return charSetViaModCharSet (PS, tmp, removeContents);
1359}
1360
1361ListCFList
1362charSeries (const CFList& L)
1363{
1364  ListCFList tmp, result, tmp2, ppi1, ppi2, qqi, ppi, alreadyConsidered;
1365  CFList l, charset, ini;
1366
1367  int count= 0;
1368  int highestLevel= 1;
1369  CFListIterator iter;
1370
1371  StoreFactors StoredFactors;
1372
1373  l= L;
1374
1375  for (iter= l; iter.hasItem(); iter++)
1376  {
1377    iter.getItem()= normalize (iter.getItem());
1378    if (highestLevel < iter.getItem().level())
1379      highestLevel= iter.getItem().level();
1380  }
1381
1382  tmp= ListCFList (l);
1383
1384  while (!tmp.isEmpty())
1385  {
1386    sortListCFList (tmp);
1387
1388    l= tmp.getFirst();
1389
1390    tmp= MyDifference (tmp, l);
1391
1392    select (ppi, l.length(), ppi1, ppi2);
1393
1394    MyUnion2 (ppi2, qqi);
1395
1396    if (count > 0)
1397      ppi= MyUnion (ListCFList (l), ppi1);
1398    else
1399      ppi= ListCFList();
1400
1401    if (l.length() - 3 < highestLevel)
1402      charset= charSetViaModCharSet (l, StoredFactors);
1403    else
1404      charset= charSetViaCharSetN (l);
1405
1406    if (charset.length() > 0 && charset.getFirst().level() > 0)
1407    {
1408      result= MyUnion (result, ListCFList (charset));
1409      ini= factorsOfInitials (charset);
1410
1411      ini= Union (ini, factorPSet (StoredFactors.FS1));
1412      sortCFListByLevel (ini);
1413    }
1414    else
1415    {
1416      ini= factorPSet (StoredFactors.FS1);
1417      sortCFListByLevel (ini);
1418    }
1419
1420    tmp2= adjoin (ini, l, qqi);
1421    tmp= MyUnion (tmp, tmp2);
1422
1423    StoredFactors.FS1= CFList();
1424    StoredFactors.FS2= CFList();
1425
1426    ppi1= ListCFList();
1427    ppi2= ListCFList();
1428
1429    count++;
1430  }
1431
1432  //TODO need to remove superflous components
1433
1434  return result;
1435}
1436
1437static bool
1438irreducible (const CFList & AS)
1439{
1440// AS is given by AS = { A1, A2, .. Ar }, d_i = degree(Ai)
1441
1442// 1) we test: if d_i > 1, d_j =1 for all j<>i, then AS is irreducible.
1443  bool deg1= true;
1444  for (CFListIterator i= AS ; i.hasItem(); i++)
1445  {
1446    if (degree (i.getItem()) > 1)
1447    {
1448      if (deg1)
1449        deg1= false;
1450      else
1451        return false; // found 2nd poly with deg > 1
1452    }
1453  }
1454  return true;
1455}
1456
1457static CFList
1458irredAS (CFList & AS, int & indexRed, CanonicalForm & reducible)
1459{
1460  CFFList qs;
1461  CFList ts, as;
1462  CanonicalForm elem;
1463  bool ind= true;
1464  int nr= 0, success= -1;
1465  CFListIterator i;
1466
1467  indexRed= 0;
1468  for (i= AS; i.hasItem(); i++ )
1469  {
1470    nr += 1;
1471    if (degree (i.getItem()) > 1)
1472    {
1473      qs= factorize (i.getItem());
1474      if (qs.getFirst().factor().inCoeffDomain())
1475        qs.removeFirst();
1476    }
1477    else
1478      qs= CFFList (CFFactor (i.getItem(), 1));
1479
1480    if ((qs.length() >= 2 ) || (qs.getFirst().exp() > 1))
1481    {
1482      indexRed= nr;
1483      ind= false;
1484      reducible= i.getItem();
1485      break;
1486    }
1487  }
1488
1489  if (ind)
1490  {
1491    if (irreducible (AS))  // as quasilinear? => irreducible!
1492      indexRed= 0;
1493    else
1494    {
1495      i= AS;
1496      for (nr= 1; nr< AS.length(); nr++)
1497      {
1498        as.append (i.getItem());
1499        i++;
1500        if (degree (i.getItem()) > 1)
1501        {  // search for a non linear elem
1502          qs= newfactoras (i.getItem(), as, success);
1503          if (qs.getFirst().factor().inCoeffDomain())
1504            qs.removeFirst();
1505          if (qs.length() > 1 || qs.getFirst().exp() > 1)
1506          { //found elem is reducible
1507            reducible= i.getItem();
1508            indexRed= nr + 1;
1509            break;
1510          }
1511        }
1512      }
1513    }
1514  }
1515  for (CFFListIterator k= qs; k.hasItem(); k++)
1516    ts.append (k.getItem().factor());
1517  return ts;
1518}
1519
1520ListCFList
1521irrCharSeries (const CFList & PS)
1522{
1523  CanonicalForm reducible, reducible2;
1524  CFList qs, cs, factorset, is, ts;
1525  ListCFList pi, ppi, qqi, qsi, iss, qhi= ListCFList(PS);
1526
1527  int nr_of_iteration= 0, indexRed, highestlevel= 0;
1528
1529  for (CFListIterator iter= PS; iter.hasItem(); iter++)
1530  {
1531    if (level (iter.getItem()) > highestlevel)
1532      highestlevel= level(iter.getItem());
1533  }
1534
1535  while (!qhi.isEmpty())
1536  {
1537    sortListCFList (qhi);
1538
1539    qs= qhi.getFirst();
1540
1541    ListCFList ppi1,ppi2;
1542    select (ppi, qs.length(), ppi1, ppi2);
1543
1544    MyUnion2 (ppi2, qqi);
1545
1546    if (nr_of_iteration == 0)
1547    {
1548      nr_of_iteration += 1;
1549      ppi= ListCFList();
1550    }
1551    else
1552    {
1553      nr_of_iteration += 1;
1554      ppi= MyUnion (ListCFList(qs), ppi1);
1555    }
1556
1557    StoreFactors StoredFactors;
1558    cs= charSetViaModCharSet (qs, StoredFactors);
1559    cs= removeContent (cs, StoredFactors);
1560
1561    factorset= StoredFactors.FS1;
1562
1563    if (cs.getFirst().level() > 0)
1564    {
1565      ts= irredAS (cs, indexRed, reducible);
1566
1567      if (indexRed <= 0) // irreducible
1568      {
1569        if (!subset (cs,qs))
1570          cs= charSetViaCharSetN (Union (qs,cs));
1571        if (!member (cs, pi))
1572        {
1573          pi= MyUnion (pi, ListCFList (cs));
1574          if (cs.getFirst().level() > 0)
1575          {
1576            ts= irredAS (cs, indexRed, reducible);
1577
1578            if (indexRed <= 0) //irreducible
1579            {
1580              qsi= MyUnion (qsi, ListCFList(cs));
1581              if (cs.length() == highestlevel)
1582                is= factorPSet (factorset);
1583              else
1584                is= Union (factorsOfInitials (cs), factorPSet (factorset));
1585              iss= adjoin (is, qs, qqi);
1586            }
1587          }
1588          else
1589            iss= adjoin (factorPSet (factorset), qs, qqi);
1590        }
1591        else
1592          iss= adjoin (factorPSet (factorset), qs, qqi);
1593      }
1594
1595      if (indexRed > 0)
1596      {
1597        is= factorPSet (factorset);
1598        if (indexRed > 1)
1599        {
1600          CFList cst;
1601          for (CFListIterator i=cs ; i.hasItem(); i++)
1602          {
1603            if (i.getItem() == reducible)
1604              break;
1605            else 
1606              cst.append (i.getItem());
1607          }
1608          is= Union (factorsOfInitials (cst), is);
1609          iss= MyUnion (adjoin (is, qs, qqi), adjoinb (ts, qs, qqi, cst));
1610        }
1611        else
1612          iss= adjoin (Union (is, ts), qs, qqi);
1613      }
1614    }
1615    else
1616      iss= adjoin (factorPSet (factorset), qs, qqi);
1617    if (qhi.length() > 1)
1618    {
1619      qhi.removeFirst();
1620      qhi= MyUnion (qhi, iss);
1621    }
1622    else
1623      qhi= iss;
1624  }
1625  if (!qsi.isEmpty())
1626    return contract (qsi);
1627  return ListCFList() ;
1628}
1629
Note: See TracBrowser for help on using the repository browser.