source: git/libfac/charset/reorder.cc @ 3e55bc

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