source: git/libfac/charset/reorder.cc @ 924d8f

spielwiese
Last change on this file since 924d8f was 924d8f, checked in by Hans Schoenemann <hannes@…>, 14 years ago
svn does not support $ git-svn-id: file:///usr/local/Singular/svn/trunk@12915 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 12.5 KB
Line 
1////////////////////////////////////////////////////////////
2// This is really experimental. What is the best order of the variables for
3// an ideal? Clearly, if a variable only occures in one and only one polynomial
4// this variable should be assigned the highest level.
5// But what for the others?
6//
7// The strategy used here is o.k. for *most* of the examples. But there are
8// examples where this strategy doesn't give the best possible answer.
9// So, use this at your own risk! The order given may increase or decrease
10// computing time for your example!
11/////////////////////////////////////////////////////////////
12// emacs edit mode for this file is -*- C++ -*-
13/* $Id$ */
14////////////////////////////////////////////////////////////
15// FACTORY - Includes
16#include <factory.h>
17// Factor - Includes
18#include <tmpl_inst.h>
19#include "homogfactor.h"
20// Charset - Includes
21
22// some CC's need this:
23#include "reorder.h"
24
25#ifdef REORDERDEBUG
26#  define DEBUGOUTPUT
27#else
28#  undef DEBUGOUTPUT
29#endif
30
31#include "debug.h"
32#include "timing.h"
33TIMING_DEFINE_PRINT(neworder_time);
34
35#define __ARRAY_INIT__ -1
36
37// the maximal degree of polys in PS wrt. variable x
38static int
39degpsmax( const CFList & PS, const Variable & x, 
40          Intarray & A, Intarray & C){
41  int varlevel = level(x);
42  if ( A[varlevel] != __ARRAY_INIT__ ) return A[varlevel];
43  int max=0,temp, count=0;
44 
45  for ( CFListIterator i=PS; i.hasItem();i++){
46    temp = degree(i.getItem(),x);
47    if ( temp > max ) {max = temp; count = 0; }
48    if ( temp == max) { count += max; } // we count the number of polys
49  }
50  A[varlevel] = max; 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  int varlevel = level(x);
60  if ( B[varlevel] != __ARRAY_INIT__ ) return B[varlevel];
61  int min=degpsmax(PS,x,A,C), temp, count=0;
62
63  if (min==0) {
64    B[varlevel] = min; D[varlevel] = min;
65    return min;
66  }
67  else
68    for ( CFListIterator i=PS; i.hasItem();i++){
69      temp = degree(i.getItem(),x);
70      if ( temp < min && temp != 0 ){ min = temp; count = 0; }
71      if ( temp == min) { count += min;} // we count the number of polys
72    }
73  B[varlevel] = min; D[varlevel] = count;
74  return min;
75}
76
77// the minimal total degree of lcoeffs of polys in PS wrt. x
78// for those polys having degree degpsmin in x.
79// F will be assigned the minimal number of terms of those lcoeffs
80static int
81Tdeg( const CFList & PS, const Variable & x, Intarray & A, Intarray & B,
82      Intarray & C, Intarray & D, Intarray & E, Intarray & F){
83  int k= degpsmin(PS,x,A,B,C,D), 
84    varlevel= level(x), min=0;
85
86  if ( E[varlevel] != __ARRAY_INIT__ ) return E[varlevel];
87  if (k == 0){
88    E[varlevel]= 0; F[varlevel]= 0;
89  }
90  else{
91    int nopslc=0;
92    CFList LCdegList;
93    CanonicalForm elem;
94    CFListIterator i;
95
96    for ( i=PS; i.hasItem(); i++ ){
97      elem = i.getItem();
98      if ( degree(elem,x) == k ) LCdegList.append(LC(elem,x));
99    }
100   
101    if ( LCdegList.length() > 0 ){
102      CFList TermList;
103      int newmin, newnopslc;
104
105      min= totaldegree(LCdegList.getFirst());
106      TermList= get_Terms(LCdegList.getFirst()); 
107      nopslc= TermList.length();
108      for ( i=LCdegList; i.hasItem(); i++){
109        elem= i.getItem();
110        newmin= totaldegree(elem);
111        TermList= get_Terms(elem);
112        newnopslc= TermList.length();
113        if ( newmin < min ) min= newmin; 
114        if ( newnopslc < nopslc ) nopslc= newnopslc;
115      }
116     
117    }
118    E[varlevel]= min;
119    F[varlevel]= nopslc;
120  }
121  return min;
122}
123
124// The number of the poly in which Variable x first occures
125static int
126nr_of_poly( const CFList & PS, const Variable & x, Intarray & G){
127  int min=0, varlevel=level(x);
128  if ( G[varlevel] != __ARRAY_INIT__ ) return G[varlevel];
129  for ( CFListIterator i=PS; i.hasItem(); i++ ){
130    min += 1;
131    if ( degree(i.getItem(),x) > 0 ) break;
132  }
133  G[varlevel]= min;
134  return min;
135}
136
137static int
138degord( const Variable & x, const Variable & y, const CFList & PS,
139        Intarray & A, Intarray & B, Intarray & C, Intarray & D,
140        Intarray & E, Intarray & F, Intarray & G){
141  int xlevel= level(x), ylevel= level(y);
142
143  if      (degpsmax(PS,y,A,C) < degpsmax(PS,x,A,C))         return 1;
144  else if (degpsmax(PS,x,A,C) < degpsmax(PS,y,A,C) )        return 0;
145  else if (C[ylevel] < C[xlevel])                           return 1;
146  else if (C[xlevel] < C[ylevel])                           return 0;
147  else if (degpsmin(PS,x,A,B,C,D) < degpsmin(PS,y,A,B,C,D)) return 1;
148  else if (degpsmin(PS,y,A,B,C,D) < degpsmin(PS,x,A,B,C,D)) return 0;
149  else if (D[ylevel] < D[xlevel])                           return 1;
150  else if (D[xlevel] < D[ylevel])                           return 0;
151  else if (Tdeg(PS,y,A,B,C,D,E,F) < Tdeg(PS,x,A,B,C,D,E,F)) return 1;
152  else if (Tdeg(PS,x,A,B,C,D,E,F) < Tdeg(PS,y,A,B,C,D,E,F)) return 0;
153  else if (F[ylevel] < F[xlevel])                           return 1;
154  else if (F[xlevel] < F[ylevel])                           return 0;
155  else if (nr_of_poly(PS,x,G) <= nr_of_poly(PS,y,G))        return 1;
156  else return 0;
157
158}
159
160// determine the highest variable of all involved Variables in PS
161// NOTE:
162//    this doesn't give always the correct answer:
163//    If a variable is assigned the highest level in the definition of the
164//    original ring, but doesn't occure in any of the
165//    polynomials, get_max_var returns the variable with a level lower than
166//    the highest level.
167//    Is there a workaround?
168// But for the redefinition of the ring this doesn't matter due to the
169// implementation of neworder().
170
171static Variable
172get_max_var(const CFList & PS){
173  Variable x=PS.getFirst().mvar(), y;
174  for (CFListIterator i=PS; i.hasItem(); i++){
175    y = i.getItem().mvar();
176    if ( y > x ) x=y;
177  }
178  return x;
179}
180
181
182// determine if variable x is in one and only one of the polynomials in PS
183// first criterion for neworder
184static CFList
185only_in_one( const CFList & PS , const Variable & x){
186  CFList output;
187
188  for ( CFListIterator i=PS; i.hasItem(); i++ ){
189    if ( degree(i.getItem(),x) >= 1 ) output.insert(i.getItem());
190    if ( output.length() >= 2 ) break;
191  }
192  return output;
193}
194
195// initialize all Arrays (of same range) with __ARRAY_INIT__
196static void
197initArray(const int highest_level, Intarray & A, Intarray & B, Intarray & C, 
198          Intarray & D, Intarray & E, Intarray & F, Intarray & G){ 
199
200  for ( int i=1 ; i <= highest_level; i ++){
201    A[i] = __ARRAY_INIT__; B[i] = __ARRAY_INIT__; 
202    C[i] = __ARRAY_INIT__; D[i] = __ARRAY_INIT__;
203    E[i] = __ARRAY_INIT__; F[i] = __ARRAY_INIT__;
204    G[i] = __ARRAY_INIT__;
205  }
206}
207
208// now for the second criterion; a little more complex
209//
210// idea: set up seven arrays of lenth highest_level
211//       (of which some entries may be empty, because of only_in_one!)
212//   A saves maxdegree of Variable x in A(level(x))
213//   B saves mindegree of Variable x in B(level(x))
214//   C saves the number of polys in PS which have degree A(level(x)) in
215//     D(level(x))
216//   D saves the number of polys in PS which have degree B(level(x)) in
217//     D(level(x))
218//   E saves the minimal total degree of lcoeffs of polys wrt x in E(level(x))
219//   F saves the minimal number of terms of lcoeffs of E(level(x)) in F(~)
220//   G saves nr of poly Variable x has first deg <> 0
221
222#define __INIT_GAP__ 3
223static Varlist
224reorderb(const Varlist & difference, const CFList & PS, 
225         const int highest_level){
226  Intarray A(1, highest_level), B(1, highest_level), C(1, highest_level), 
227    D(1, highest_level), E(1, highest_level), F(1, highest_level),
228    G(1, highest_level);
229  initArray(highest_level,A,B,C,D,E,F,G);
230  int i=0, j, n=difference.length(), gap=1+__INIT_GAP__;
231  Variable temp;
232  Array<Variable> v(0,n);
233  VarlistIterator J;
234
235  for (J= difference; J.hasItem(); J++ ){ 
236    v[i]= J.getItem(); 
237    i++ ; 
238  }
239 
240  while ( gap <= n) gap = __INIT_GAP__ * gap+1;
241  gap /= __INIT_GAP__;
242  DEBOUTLN(CERR, "gap is ", gap);
243 
244  while ( gap > 0 ){
245    for ( i=gap; i<= n-1; i++){
246      temp = v[i];
247      for ( j= i-gap; j >=0 ; j-=gap){
248        if (degord(v[j],temp, PS, A,B,C,D,E,F,G))  break;
249        v[j+gap] = v[j];
250        //CERR << "v[" << j+gap << "]= " << v[j+gap] << "\n";
251      }
252      v[j+gap] = temp;
253      //CERR << "v[" << j+gap << "]= " << v[j+gap] << "\n";
254    }
255    gap /= __INIT_GAP__;
256  }
257  Varlist output;
258  for (i=0; i<= n-1; i++)
259    output.append(v[i]);
260  DEBOUTLN(CERR, "A= ", A);  DEBOUTLN(CERR, "B= ", B); 
261  DEBOUTLN(CERR, "C= ", C);  DEBOUTLN(CERR, "D= ", D);
262  DEBOUTLN(CERR, "E= ", E);  DEBOUTLN(CERR, "F= ", F);
263  DEBOUTLN(CERR, "G= ", G);
264  return output;
265}
266
267// set up a new orderd list of Variables.
268// we try to reorder the variables heuristically optimal.
269Varlist
270neworder( const CFList & PolyList ){
271  CFList PS= PolyList, PS1=PolyList;
272  Varlist oldorder, reorder, difference;
273
274  DEBINCLEVEL(CERR, "neworder");
275  TIMING_START(neworder_time);
276
277  int highest_level= level(get_max_var(PS));
278  DEBOUTLN(CERR, "neworder: highest_level=   ", highest_level);
279  DEBOUTLN(CERR, "neworder: that is variable ", Variable(highest_level));
280
281  // set up oldorder and first criterion: only_in_one
282  for (int i=highest_level; i>=1; i--){
283    oldorder.insert(Variable(i));
284    CFList is_one= only_in_one(PS1, Variable(i)); 
285    if ( is_one.length() == 1 ){
286      DEBOUTLN(CERR, "Found a variable which is in only one Polynomial: ", 
287               Variable(i));
288      DEBOUTLN(CERR, ".... in the Polynomial: ", is_one.getFirst());
289      reorder.insert(Variable(i));
290      PS1 = Difference(PS1, is_one);
291      DEBOUTLN(CERR, "New cutted list is: ", PS1);
292    }
293    else if ( is_one.length() == 0 ){
294      DEBOUTLN(CERR, "Found a variable which is in no polynomial: ", 
295               Variable(i));
296      DEBOUTMSG(CERR, "... assigning it the highest level.");
297      reorder.append(Variable(i)); // assigne it the highest level
298      PS1 = Difference(PS1, is_one); 
299    }
300  }
301  difference = Difference(oldorder,reorder);
302  DEBOUTLN(CERR, "Missing variables are: ", difference);
303  // rearrange the ordering of the variables!
304  difference = reorderb(difference, PS, highest_level);
305  DEBOUTLN(CERR, "second criterion gives: ", difference);
306  reorder = Union(reorder, difference);
307  DEBOUTLN(CERR, "old order was:     ", oldorder);
308  DEBOUTLN(CERR, "New order will be: ", Union(reorder, Difference(oldorder,reorder)));
309  DEBDECLEVEL(CERR, "neworder");
310  TIMING_END(neworder_time);
311
312  TIMING_PRINT(neworder_time, "\ntime used for neworder   : ");
313
314
315  return Union(reorder,Difference(oldorder,reorder));
316}
317
318// the same as above, only returning a list of CanonicalForms
319CFList
320newordercf(const CFList & PolyList ){
321  Varlist reorder= neworder(PolyList);
322  CFList output;
323
324  for (VarlistIterator i=reorder; i.hasItem(); i++)
325    output.append(CanonicalForm(i.getItem()));
326
327  return output;
328}
329
330// the same as above, only returning a list of ints
331IntList
332neworderint(const CFList & PolyList ){
333  Varlist reorder= neworder(PolyList);
334  IntList output;
335
336  for (VarlistIterator i=reorder; i.hasItem(); i++)
337    output.append(level(i.getItem()));
338
339  return output;
340}
341
342// swapvar a whole list of CanonicalForms
343static CFList
344swapvar( const CFList & PS, const Variable & x, const Variable & y){
345  CFList ps;
346
347  for (CFListIterator i= PS; i.hasItem(); i++)
348    ps.append(swapvar(i.getItem(),x,y));
349  return ps;
350}
351
352static CFFList
353swapvar( const CFFList & PS, const Variable & x, const Variable & y){
354  CFFList ps;
355
356  for (CFFListIterator i= PS; i.hasItem(); i++)
357    ps.append(CFFactor(swapvar(i.getItem().factor(),x,y),i.getItem().exp()));
358  return ps;
359}
360
361// a library function: we reorganize the global variable ordering
362CFList
363reorder( const Varlist & betterorder, const CFList & PS){
364  int i=1, n = betterorder.length();
365  Intarray v(1,n);
366  CFList ps=PS;
367
368  //initalize:
369  for (VarlistIterator j = betterorder; j.hasItem(); j++){
370    v[i]= level(j.getItem()); i++;
371  }
372  DEBOUTLN(CERR, "reorder: Original ps=  ", ps);
373  // reorder:
374  for (i=1; i <= n; i++)
375    ps=swapvar(ps,Variable(v[i]),Variable(n+i));
376  DEBOUTLN(CERR, "reorder: Reorganized ps= ", ps); 
377  return ps;
378}
379
380CFFList
381reorder( const Varlist & betterorder, const CFFList & PS){
382  int i=1, n = betterorder.length();
383  Intarray v(1,n);
384  CFFList ps=PS;
385
386  //initalize:
387  for (VarlistIterator j = betterorder; j.hasItem(); j++){
388    v[i]= level(j.getItem()); i++;
389  }
390  DEBOUTLN(CERR, "reorder: Original ps=  ", ps);
391  // reorder:
392  for (i=1; i <= n; i++)
393    ps=swapvar(ps,Variable(v[i]),Variable(n+i));
394  DEBOUTLN(CERR, "reorder: Reorganized ps= ", ps); 
395  return ps;
396}
397
398ListCFList
399reorder(const Varlist & betterorder, const ListCFList & Q){
400  ListCFList Q1;
401
402  for ( ListCFListIterator i=Q; i.hasItem(); i++)
403    Q1.append(reorder(betterorder, i.getItem()));
404  return Q1;
405}
406
Note: See TracBrowser for help on using the repository browser.