source: git/factory/cfCharSets.cc @ c514f7

spielwiese
Last change on this file since c514f7 was c514f7, checked in by Martin Lee <martinlee84@…>, 10 years ago
chg: moved helper functions from cfCharSets and facAlgFunc to respective Util files chg: better nomenclature, code format, include structure
  • Property mode set to 100644
File size: 15.1 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 * @note some of the code is code from libfac or derived from code from libfac.
9 * Libfac is written by M. Messollen. See also COPYING for license information
10 * and README for general information on characteristic sets.
11 *
12 * ABSTRACT: Descriptions can be found in Wang "On the Parallelization of
13 * characteristic-set based algorithms" or Greuel/Pfister "A Singular
14 * Introduction to Commutative Algebra".
15 *
16 * @authors Martin Lee
17 *
18 **/
19/*****************************************************************************/
20
21#include "config.h"
22
23#include "timing.h"
24
25#include "canonicalform.h"
26#include "cfCharSets.h"
27#include "cfCharSetsUtil.h"
28#include "cf_algorithm.h"
29#include "facAlgFunc.h"
30
31TIMING_DEFINE_PRINT(neworder_time)
32
33// set up a new orderd list of Variables.
34// we try to reorder the variables heuristically optimal.
35Varlist
36neworder (const CFList & PolyList)
37{
38  CFList PS= PolyList, PS1=PolyList;
39  Varlist oldorder, reorder, difference;
40
41  TIMING_START (neworder_time);
42
43  int highest_level= level (get_max_var (PS));
44
45  // set up oldorder and first criterion: only_in_one
46  for (int i= highest_level; i>=1; i--)
47  {
48    oldorder.insert (Variable (i));
49    CFList is_one= only_in_one (PS1, Variable (i)); 
50    if (is_one.length() == 1)
51    {
52      reorder.insert (Variable (i));
53      PS1= Difference (PS1, is_one);
54    }
55    else if (is_one.length() == 0)
56    {
57      reorder.append (Variable (i)); // assigne it the highest level
58      PS1= Difference (PS1, is_one); 
59    }
60  }
61  difference= Difference (oldorder, reorder);
62
63  // rearrange the ordering of the variables!
64  difference= reorderb (difference, PS, highest_level);
65  reorder= Union (reorder, difference);
66  TIMING_END(neworder_time);
67
68  TIMING_PRINT(neworder_time, "\ntime used for neworder   : ");
69
70  return Union (reorder, Difference (oldorder, reorder));
71}
72
73// the same as above, only returning a list of CanonicalForms
74CFList
75newordercf (const CFList & PolyList)
76{
77  Varlist reorder= neworder (PolyList);
78  CFList output;
79
80  for (VarlistIterator i=reorder; i.hasItem(); i++)
81    output.append (CanonicalForm (i.getItem()));
82
83  return output;
84}
85
86// the same as above, only returning a list of ints
87IntList
88neworderint (const CFList & PolyList)
89{
90  Varlist reorder= neworder (PolyList);
91  IntList output;
92
93  for (VarlistIterator i= reorder; i.hasItem(); i++)
94    output.append (level (i.getItem()));
95
96  return output;
97}
98
99// a library function: we reorganize the global variable ordering
100CFList
101reorder (const Varlist & betterorder, const CFList & PS)
102{
103  int i= 1, n= betterorder.length();
104  Intarray v (1, n);
105  CFList ps= PS;
106
107  //initalize:
108  for (VarlistIterator j= betterorder; j.hasItem(); j++)
109  {
110    v[i]= level (j.getItem());
111    i++;
112  }
113  // reorder:
114  for (i= 1; i <= n; i++)
115    ps= swapvar (ps, Variable (v[i]), Variable (n + i));
116  return ps;
117}
118
119CFFList
120reorder (const Varlist & betterorder, const CFFList & PS)
121{
122  int i= 1, n= betterorder.length();
123  Intarray v (1, n);
124  CFFList ps= PS;
125
126  //initalize:
127  for (VarlistIterator j= betterorder; j.hasItem(); j++)
128  {
129    v[i]= level (j.getItem());
130    i++;
131  }
132
133  // reorder:
134  for (i= 1; i <= n; i++)
135    ps= swapvar (ps, Variable (v[i]), Variable (n + i));
136  return ps;
137}
138
139ListCFList
140reorder (const Varlist & betterorder, const ListCFList & Q)
141{
142  ListCFList Q1;
143
144  for (ListCFListIterator i= Q; i.hasItem(); i++)
145    Q1.append (reorder (betterorder, i.getItem()));
146  return Q1;
147}
148
149CFList
150basicSet (const CFList &PS)
151{
152  CFList QS= PS, BS, RS;
153  CanonicalForm b;
154  int cb, degb;
155
156  if (PS.length() < 2)
157    return PS;
158
159  CFListIterator i;
160
161  while (!QS.isEmpty())
162  {
163    b= lowestRank (QS);
164    cb= b.level();
165
166    BS= Union(CFList (b), BS);
167
168    if (cb <= 0)
169      return CFList();
170    else
171    {
172      degb= degree (b);
173      RS= CFList();
174      for (i= QS; i.hasItem(); i++)
175      {
176        if (degree (i.getItem(), cb) < degb)
177          RS= Union (CFList (i.getItem()), RS);
178      }
179      QS= RS;
180    }
181  }
182
183  return BS;
184}
185
186CFList
187charSet (const CFList &PS)
188{
189  CFList QS= PS, RS= PS, CSet, tmp;
190  CFListIterator i;
191  CanonicalForm r;
192
193  while (!RS.isEmpty())
194  {
195    CSet= basicSet (QS);
196
197    RS= CFList();
198    if (CSet.length() > 0 && CSet.getFirst().level() > 0)
199    {
200      tmp= Difference (QS, CSet);
201      for (i= tmp; i.hasItem(); i++)
202      {
203        r= Prem (i.getItem(), CSet);
204        if (r != 0)
205          RS= Union (RS, CFList (r));
206      }
207      QS= Union (QS, RS);
208    }
209  }
210
211  return CSet;
212}
213
214/// medial set
215CFList
216charSetN (const CFList &PS)
217{
218  CFList QS= PS, RS= PS, CSet, tmp;
219  CFListIterator i;
220  CanonicalForm r;
221
222  while (!RS.isEmpty())
223  {
224    QS= uniGcd (QS);
225    CSet= basicSet (QS);
226
227    RS= CFList();
228    if (CSet.length() > 0 && CSet.getFirst().level() > 0)
229    {
230      tmp= Difference (QS, CSet);
231      for (i= tmp; i.hasItem(); i++)
232      {
233        r= Prem (i.getItem(), CSet);
234        if (!r.isZero())
235          RS= Union (RS, CFList (r));
236      }
237      QS= Union (CSet, RS);
238    }
239  }
240
241  return CSet;
242}
243
244/// compute a characteristic set via medial set
245CFList
246charSetViaCharSetN (const CFList& PS)
247{
248  CFList L;
249  CFFList sqrfFactors;
250  CanonicalForm sqrf;
251  CFFListIterator iter2;
252  for (CFListIterator iter= PS; iter.hasItem(); iter++)
253  {
254    sqrf= 1;
255    sqrfFactors= sqrFree (iter.getItem());
256    for (iter2= sqrfFactors; iter2.hasItem(); iter2++)
257      sqrf *= iter2.getItem().factor();
258    L= Union (L, CFList (normalize (sqrf)));
259  }
260
261  CFList result= charSetN (L);
262
263  if (result.isEmpty() || result.getFirst().inCoeffDomain())
264    return CFList(1);
265
266  CanonicalForm r;
267  CFList RS;
268  CFList tmp= Difference (L, result);
269
270  for (CFListIterator i= tmp; i.hasItem(); i++)
271  {
272    r= Premb (i.getItem(), result);
273    if (!r.isZero())
274      RS= Union (RS, CFList (r));
275  }
276  if (RS.isEmpty())
277    return result;
278
279  return charSetViaCharSetN (Union (L, Union (RS, result)));
280}
281
282/// modified medial set
283CFList
284modCharSet (const CFList& L, StoreFactors& StoredFactors, bool removeContents)
285{
286  CFList QS= L, RS= L, CSet, tmp, contents, initial, removedFactors;
287  CFListIterator i;
288  CanonicalForm r, cF;
289  bool noRemainder= true;
290  StoreFactors StoredFactors2;
291
292  QS= uniGcd (L);
293
294  while (!RS.isEmpty())
295  {
296    noRemainder= true;
297    CSet= basicSet (QS);
298
299    initial= factorsOfInitials (CSet);
300
301    StoredFactors2.FS1= StoredFactors.FS1;
302    StoredFactors2.FS2= Union (StoredFactors2.FS2, initial);
303
304    RS= CFList();
305
306    if (CSet.length() > 0 && CSet.getFirst().level() > 0)
307    {
308      tmp= Difference (QS, CSet);
309
310      for (i= tmp; i.hasItem(); i++)
311      {
312        r= Prem (i.getItem(), CSet);
313        if (!r.isZero())
314        {
315          noRemainder= false;
316          if (removeContents)
317          {
318            removeContent (r, cF);
319
320            if (!cF.isZero())
321              contents= Union (contents, factorPSet (CFList(cF))); //factorPSet maybe too much it should suffice to do a squarefree factorization instead
322          }
323
324          removeFactors (r, StoredFactors2, removedFactors);
325          StoredFactors2.FS1= Union (StoredFactors2.FS1, removedFactors);
326          StoredFactors2.FS2= Difference (StoredFactors2.FS2, removedFactors);
327
328          removedFactors= CFList();
329
330          RS= Union (RS, CFList (r));
331        }
332      }
333
334      if (removeContents && !noRemainder)
335      {
336        StoredFactors.FS1= Union (StoredFactors2.FS1, contents);
337        StoredFactors.FS2= StoredFactors2.FS2;
338      }
339      else
340        StoredFactors= StoredFactors2;
341
342      QS= Union (CSet, RS);
343
344      contents= CFList();
345      removedFactors= CFList();
346    }
347    else
348      StoredFactors= StoredFactors2;
349  }
350
351  return CSet;
352}
353
354/// characteristic set via modified medial set
355CFList
356charSetViaModCharSet (const CFList& PS, StoreFactors& StoredFactors, bool removeContents)
357{
358  CFList L;
359  CFFList sqrfFactors;
360  CanonicalForm sqrf;
361  CFFListIterator iter2;
362  for (CFListIterator iter= PS; iter.hasItem(); iter++)
363  {
364    sqrf= 1;
365    sqrfFactors= sqrFree (iter.getItem());
366    for (iter2= sqrfFactors; iter2.hasItem(); iter2++)
367      sqrf *= iter2.getItem().factor();
368    L= Union (L, CFList (normalize (sqrf)));
369  }
370
371  L= uniGcd (L);
372
373  CFList result= modCharSet (L, StoredFactors, removeContents);
374
375  if (result.isEmpty() || result.getFirst().inCoeffDomain())
376    return CFList(1);
377
378  CanonicalForm r;
379  CFList RS;
380  CFList tmp= Difference (L, result);
381
382  for (CFListIterator i= tmp; i.hasItem(); i++)
383  {
384    r= Premb (i.getItem(), result);
385    if (!r.isZero())
386      RS= Union (RS, CFList (r));
387  }
388  if (RS.isEmpty())
389    return result;
390
391  return charSetViaModCharSet (Union (L, Union (RS, result)), StoredFactors, removeContents);
392}
393
394CFList
395charSetViaModCharSet (const CFList& PS, bool removeContents)
396{
397  StoreFactors tmp;
398  return charSetViaModCharSet (PS, tmp, removeContents);
399}
400
401ListCFList
402charSeries (const CFList& L)
403{
404  ListCFList tmp, result, tmp2, ppi1, ppi2, qqi, ppi, alreadyConsidered;
405  CFList l, charset, ini;
406
407  int count= 0;
408  int highestLevel= 1;
409  CFListIterator iter;
410
411  StoreFactors StoredFactors;
412
413  l= L;
414
415  for (iter= l; iter.hasItem(); iter++)
416  {
417    iter.getItem()= normalize (iter.getItem());
418    if (highestLevel < iter.getItem().level())
419      highestLevel= iter.getItem().level();
420  }
421
422  tmp= ListCFList (l);
423
424  while (!tmp.isEmpty())
425  {
426    sortListCFList (tmp);
427
428    l= tmp.getFirst();
429
430    tmp= MyDifference (tmp, l);
431
432    select (ppi, l.length(), ppi1, ppi2);
433
434    MyUnion2 (ppi2, qqi);
435
436    if (count > 0)
437      ppi= MyUnion (ListCFList (l), ppi1);
438    else
439      ppi= ListCFList();
440
441    if (l.length() - 3 < highestLevel)
442      charset= charSetViaModCharSet (l, StoredFactors);
443    else
444      charset= charSetViaCharSetN (l);
445
446    if (charset.length() > 0 && charset.getFirst().level() > 0)
447    {
448      result= MyUnion (result, ListCFList (charset));
449      ini= factorsOfInitials (charset);
450
451      ini= Union (ini, factorPSet (StoredFactors.FS1));
452      sortCFListByLevel (ini);
453    }
454    else
455    {
456      ini= factorPSet (StoredFactors.FS1);
457      sortCFListByLevel (ini);
458    }
459
460    tmp2= adjoin (ini, l, qqi);
461    tmp= MyUnion (tmp, tmp2);
462
463    StoredFactors.FS1= CFList();
464    StoredFactors.FS2= CFList();
465
466    ppi1= ListCFList();
467    ppi2= ListCFList();
468
469    count++;
470  }
471
472  //TODO need to remove superflous components
473
474  return result;
475}
476
477static bool
478irreducible (const CFList & AS)
479{
480// AS is given by AS = { A1, A2, .. Ar }, d_i = degree(Ai)
481
482// 1) we test: if d_i > 1, d_j =1 for all j<>i, then AS is irreducible.
483  bool deg1= true;
484  for (CFListIterator i= AS ; i.hasItem(); i++)
485  {
486    if (degree (i.getItem()) > 1)
487    {
488      if (deg1)
489        deg1= false;
490      else
491        return false; // found 2nd poly with deg > 1
492    }
493  }
494  return true;
495}
496
497static CFList
498irredAS (CFList & AS, int & indexRed, CanonicalForm & reducible)
499{
500  CFFList qs;
501  CFList ts, as;
502  CanonicalForm elem;
503  bool ind= true;
504  int nr= 0, success= -1;
505  CFListIterator i;
506
507  indexRed= 0;
508  for (i= AS; i.hasItem(); i++ )
509  {
510    nr += 1;
511    if (degree (i.getItem()) > 1)
512    {
513      qs= factorize (i.getItem());
514      if (qs.getFirst().factor().inCoeffDomain())
515        qs.removeFirst();
516    }
517    else
518      qs= CFFList (CFFactor (i.getItem(), 1));
519
520    if ((qs.length() >= 2 ) || (qs.getFirst().exp() > 1))
521    {
522      indexRed= nr;
523      ind= false;
524      reducible= i.getItem();
525      break;
526    }
527  }
528
529  if (ind)
530  {
531    if (irreducible (AS))  // as quasilinear? => irreducible!
532      indexRed= 0;
533    else
534    {
535      i= AS;
536      for (nr= 1; nr< AS.length(); nr++)
537      {
538        as.append (i.getItem());
539        i++;
540        if (degree (i.getItem()) > 1)
541        {  // search for a non linear elem
542          qs= facAlgFunc2 (i.getItem(), as);
543          if (qs.getFirst().factor().inCoeffDomain())
544            qs.removeFirst();
545          if (qs.length() > 1 || qs.getFirst().exp() > 1)
546          { //found elem is reducible
547            reducible= i.getItem();
548            indexRed= nr + 1;
549            break;
550          }
551        }
552      }
553    }
554  }
555  for (CFFListIterator k= qs; k.hasItem(); k++)
556    ts.append (k.getItem().factor());
557  return ts;
558}
559
560ListCFList
561irrCharSeries (const CFList & PS)
562{
563  CanonicalForm reducible, reducible2;
564  CFList qs, cs, factorset, is, ts, L;
565  CanonicalForm sqrf;
566  CFFList sqrfFactors;
567  CFFListIterator iter2;
568  for (CFListIterator iter= PS; iter.hasItem(); iter++)
569  {
570    sqrf= 1;
571    sqrfFactors= sqrFree (iter.getItem());
572    if (sqrfFactors.getFirst().factor().inCoeffDomain())
573      sqrfFactors.removeFirst();
574    for (iter2= sqrfFactors; iter2.hasItem(); iter2++)
575      sqrf *= iter2.getItem().factor();
576    sqrf= normalize (sqrf);
577    L= Union (L, CFList (sqrf));
578  }
579
580  ListCFList pi, ppi, qqi, qsi, iss, qhi= ListCFList(L);
581
582  int nr_of_iteration= 0, indexRed, highestlevel= 0;
583
584  for (CFListIterator iter= PS; iter.hasItem(); iter++)
585  {
586    if (level (iter.getItem()) > highestlevel)
587      highestlevel= level(iter.getItem());
588  }
589
590  while (!qhi.isEmpty())
591  {
592    sortListCFList (qhi);
593
594    qs= qhi.getFirst();
595
596    ListCFList ppi1,ppi2;
597    select (ppi, qs.length(), ppi1, ppi2);
598
599    MyUnion2 (ppi2, qqi);
600
601    if (nr_of_iteration == 0)
602    {
603      nr_of_iteration += 1;
604      ppi= ListCFList();
605    }
606    else
607    {
608      nr_of_iteration += 1;
609      ppi= MyUnion (ListCFList(qs), ppi1);
610    }
611
612    StoreFactors StoredFactors;
613    cs= charSetViaModCharSet (qs, StoredFactors);
614    cs= removeContent (cs, StoredFactors);
615
616    factorset= StoredFactors.FS1;
617
618    if (cs.getFirst().level() > 0)
619    {
620      ts= irredAS (cs, indexRed, reducible);
621
622      if (indexRed <= 0) // irreducible
623      {
624        if (!subset (cs,qs))
625          cs= charSetViaCharSetN (Union (qs,cs));
626        if (!member (cs, pi))
627        {
628          pi= MyUnion (pi, ListCFList (cs));
629          if (cs.getFirst().level() > 0)
630          {
631            ts= irredAS (cs, indexRed, reducible);
632
633            if (indexRed <= 0) //irreducible
634            {
635              qsi= MyUnion (qsi, ListCFList(cs));
636              if (cs.length() == highestlevel)
637                is= factorPSet (factorset);
638              else
639                is= Union (factorsOfInitials (cs), factorPSet (factorset));
640              iss= adjoin (is, qs, qqi);
641            }
642          }
643          else
644            iss= adjoin (factorPSet (factorset), qs, qqi);
645        }
646        else
647          iss= adjoin (factorPSet (factorset), qs, qqi);
648      }
649
650      if (indexRed > 0)
651      {
652        is= factorPSet (factorset);
653        if (indexRed > 1)
654        {
655          CFList cst;
656          for (CFListIterator i= cs ; i.hasItem(); i++)
657          {
658            if (i.getItem() == reducible)
659              break;
660            else 
661              cst.append (i.getItem());
662          }
663          is= Union (factorsOfInitials (cst), is);
664          iss= MyUnion (adjoin (is, qs, qqi), adjoinb (ts, qs, qqi, cst));
665        }
666        else
667          iss= adjoin (Union (is, ts), qs, qqi);
668      }
669    }
670    else
671      iss= adjoin (factorPSet (factorset), qs, qqi);
672    if (qhi.length() > 1)
673    {
674      qhi.removeFirst();
675      qhi= MyUnion (qhi, iss);
676    }
677    else
678      qhi= iss;
679  }
680  if (!qsi.isEmpty())
681    return contract (qsi);
682  return ListCFList(CFList (1)) ;
683}
684
Note: See TracBrowser for help on using the repository browser.