source: git/Singular/Minor.cc @ 7b8818

spielwiese
Last change on this file since 7b8818 was 056089, checked in by Jan Engelhardt <jengelh@…>, 12 years ago
src: resolve compiler warnings for -Wreturn-type The compiler cannot always know that some places are not reached. Minor.cc: In member function 'int MinorKey::getRelativeColumnIndex(int) const': Minor.cc:284:1: warning: control reaches end of non-void function [-Wreturn-type] Minor.cc: In member function 'int MinorKey::getRelativeRowIndex(int) const': Minor.cc:253:1: warning: control reaches end of non-void function [-Wreturn-type] Minor.cc: In member function 'int MinorKey::getAbsoluteColumnIndex(int) const': Minor.cc:180:1: warning: control reaches end of non-void function [-Wreturn-type] Minor.cc: In member function 'int MinorKey::getAbsoluteRowIndex(int) const': Minor.cc:149:1: warning: control reaches end of non-void function [-Wreturn-type] binomial.cc: In member function 'binomial& binomial::flip_variable(const short int&)': binomial.cc:1850:1: warning: control reaches end of non-void function [-Wreturn-type] minpoly.cc: In member function 'int NewVectorMatrix::findLargestNonpivot()': minpoly.cc:387:1: warning: control reaches end of non-void function [-Wreturn-type] minpoly.cc: In member function 'int NewVectorMatrix::findSmallestNonpivot()': minpoly.cc:362:1: warning: control reaches end of non-void function [-Wreturn-type] mod_main.cc: In function 'BOOLEAN {anonymous}::_p_Content(leftv, leftv)': mod_main.cc:936:1: warning: control reaches end of non-void function [-Wreturn-type]
  • Property mode set to 100644
File size: 36.8 KB
Line 
1#include "config.h"
2#include <kernel/mod2.h>
3
4#include "Minor.h"
5
6#include <kernel/structs.h>
7#include <kernel/polys.h>
8#include <kernel/febase.h>
9
10using namespace std;
11
12void MinorKey::reset()
13{                     
14  _numberOfRowBlocks = 0;
15  _numberOfColumnBlocks = 0;
16  delete [] _rowKey;
17  delete [] _columnKey;
18  _rowKey = 0;
19  _columnKey = 0;
20}
21
22MinorKey::MinorKey (const MinorKey& mk)
23{
24  _numberOfRowBlocks = mk.getNumberOfRowBlocks();
25  _numberOfColumnBlocks = mk.getNumberOfColumnBlocks();;
26
27  /* allocate memory for new entries in _rowKey and _columnKey */
28  _rowKey = new unsigned int[_numberOfRowBlocks];
29  _columnKey = new unsigned int[_numberOfColumnBlocks];
30
31  /* copying values from parameter arrays to private arrays */
32  for (int r = 0; r < _numberOfRowBlocks; r++)
33    _rowKey[r] = mk.getRowKey(r);
34  for (int c = 0; c < _numberOfColumnBlocks; c++)
35    _columnKey[c] = mk.getColumnKey(c);
36}
37
38MinorKey& MinorKey::operator=(const MinorKey& mk)
39{
40  if (_numberOfRowBlocks != 0)    delete [] _rowKey;
41  if (_numberOfColumnBlocks != 0) delete [] _columnKey;
42  _numberOfRowBlocks = 0;
43  _numberOfColumnBlocks = 0;
44  _rowKey = 0;
45  _columnKey = 0;
46
47  _numberOfRowBlocks = mk.getNumberOfRowBlocks();
48  _numberOfColumnBlocks = mk.getNumberOfColumnBlocks();;
49
50  /* allocate memory for new entries in _rowKey and _columnKey */
51  _rowKey = new unsigned int[_numberOfRowBlocks];
52  _columnKey = new unsigned int[_numberOfColumnBlocks];
53
54  /* copying values from parameter arrays to private arrays */
55  for (int r = 0; r < _numberOfRowBlocks; r++)
56      _rowKey[r] = mk.getRowKey(r);
57  for (int c = 0; c < _numberOfColumnBlocks; c++)
58      _columnKey[c] = mk.getColumnKey(c);
59     
60  return *this;
61}
62
63void MinorKey::set(const int lengthOfRowArray, const unsigned int* rowKey,
64                   const int lengthOfColumnArray,
65                   const unsigned int* columnKey)
66{
67  /* free memory of _rowKey and _columnKey */
68  if (_numberOfRowBlocks > 0) { delete [] _rowKey; }
69  if (_numberOfColumnBlocks > 0) { delete [] _columnKey; }
70
71  _numberOfRowBlocks = lengthOfRowArray;
72  _numberOfColumnBlocks = lengthOfColumnArray;
73
74  /* allocate memory for new entries in _rowKey and _columnKey; */
75  _rowKey = new unsigned int[_numberOfRowBlocks];
76  _columnKey = new unsigned int[_numberOfColumnBlocks];
77
78  /* copying values from parameter arrays to private arrays */
79  for (int r = 0; r < _numberOfRowBlocks; r++)
80    _rowKey[r] = rowKey[r];
81  for (int c = 0; c < _numberOfColumnBlocks; c++)
82    _columnKey[c] = columnKey[c];
83}
84
85MinorKey::MinorKey(const int lengthOfRowArray,
86                   const unsigned int* const rowKey,
87                   const int lengthOfColumnArray,
88                   const unsigned int* const columnKey)
89{
90  _numberOfRowBlocks = lengthOfRowArray;
91  _numberOfColumnBlocks = lengthOfColumnArray;
92
93  /* allocate memory for new entries in _rowKey and _columnKey */
94  _rowKey = new unsigned int[_numberOfRowBlocks];
95  _columnKey = new unsigned int[_numberOfColumnBlocks];
96
97  /* copying values from parameter arrays to private arrays */
98  for (int r = 0; r < _numberOfRowBlocks; r++)
99    _rowKey[r] = rowKey[r];
100
101  for (int c = 0; c < _numberOfColumnBlocks; c++)
102    _columnKey[c] = columnKey[c];
103}
104
105MinorKey::~MinorKey()
106{
107  _numberOfRowBlocks = 0;
108  _numberOfColumnBlocks = 0;
109  delete [] _rowKey;
110  delete [] _columnKey;
111  _rowKey = 0;
112  _columnKey = 0;
113}
114
115void MinorKey::print() const
116{
117  PrintS(this->toString().c_str());
118}
119
120int MinorKey::getAbsoluteRowIndex(const int i) const
121{
122  /* This method is to return the absolute (0-based) index of the i-th
123     row encoded in \a this.
124     Example: bit-pattern of rows: "10010001101", i = 3:
125        This should yield the 0-based absolute index of the 3-rd bit
126        (counted from the right), i.e. 7. */
127
128  int matchedBits = -1; /* counter for matched bits;
129                           this needs to reach i, then we're done */
130  for (int block = 0; block < getNumberOfRowBlocks(); block ++)
131  {
132    /* start with lowest bits, i.e. in block No. 0 */
133    /* the bits in this block of 32 bits: */
134    unsigned int blockBits = getRowKey(block);
135    unsigned int shiftedBit = 1;
136    int exponent = 0;
137    /* The invariant "shiftedBit = 2^exponent" will hold throughout the
138       entire while loop. */
139    while (exponent < 32)
140    {
141      if (shiftedBit & blockBits) matchedBits++;
142      if (matchedBits == i) return exponent + (32 * block);
143      shiftedBit = shiftedBit << 1;
144      exponent++;
145    }
146  }
147  /* We should never reach this line of code. */
148  assume(false);
149  return -1;
150}
151
152int MinorKey::getAbsoluteColumnIndex(const int i) const
153{
154  /* This method is to return the absolute (0-based) index of the i-th
155     column encoded in \a this.
156     Example: bit-pattern of columns: "10010001101", i = 3:
157        This should yield the 0-based absolute index of the 3-rd bit
158        (counted from the right), i.e. 7. */
159
160  int matchedBits = -1; /* counter for matched bits; this needs to reach i,
161                           then we're done */
162  for (int block = 0; block < getNumberOfColumnBlocks(); block ++)
163  {
164    /* start with lowest bits, i.e. in block No. 0 */
165    /* the bits in this block of 32 bits: */
166    unsigned int blockBits = getColumnKey(block);
167    unsigned int shiftedBit = 1;
168    int exponent = 0;
169    /* The invariant "shiftedBit = 2^exponent" will hold throughout the
170       entire while loop. */
171    while (exponent < 32)
172    {
173      if (shiftedBit & blockBits) matchedBits++;
174      if (matchedBits == i) return exponent + (32 * block);
175      shiftedBit = shiftedBit << 1;
176      exponent++;
177    }
178  }
179  /* We should never reach this line of code. */
180  assume(false);
181  return -1;
182}
183
184void MinorKey::getAbsoluteRowIndices(int* const target) const
185{
186  int i = 0; /* index for filling the target array */
187  for (int block = 0; block < getNumberOfRowBlocks(); block ++)
188  {
189    /* start with lowest bits, i.e. in block No. 0 */
190    /* the bits in this block of 32 bits: */
191    unsigned int blockBits = getRowKey(block);
192    unsigned int shiftedBit = 1;
193    int exponent = 0;
194    /* The invariant "shiftedBit = 2^exponent" will hold throughout the
195       entire while loop. */
196    while (exponent < 32)
197    {
198      if (shiftedBit & blockBits) target[i++] = exponent + (32 * block);
199      shiftedBit = shiftedBit << 1;
200      exponent++;
201    }
202  }
203}
204
205void MinorKey::getAbsoluteColumnIndices(int* const target) const
206{
207  int i = 0; /* index for filling the target array */
208  for (int block = 0; block < getNumberOfColumnBlocks(); block ++)
209  {
210    /* start with lowest bits, i.e. in block No. 0 */
211    /* the bits in this block of 32 bits: */
212    unsigned int blockBits = getColumnKey(block);
213    unsigned int shiftedBit = 1;
214    int exponent = 0;
215    /* The invariant "shiftedBit = 2^exponent" will hold throughout the
216       entire while loop. */
217    while (exponent < 32)
218    {
219      if (shiftedBit & blockBits) target[i++] = exponent + (32 * block);
220      shiftedBit = shiftedBit << 1;
221      exponent++;
222    }
223  }
224}
225
226int MinorKey::getRelativeRowIndex(const int i) const
227{
228  /* This method is to return the relative (0-based) index of the row
229     with absolute index \c i.
230     Example: bit-pattern of rows: "10010001101", i = 7:
231        This should yield the 0-based relative index of the bit
232        corresponding to row no. 7, i.e. 3. */
233
234  int matchedBits = -1; /* counter for matched bits; this is going to
235                           contain our return value */
236  for (int block = 0; block < getNumberOfRowBlocks(); block ++)
237  {
238    /* start with lowest bits, i.e. in block No. 0 */
239    /* the bits in this block of 32 bits: */
240    unsigned int blockBits = getRowKey(block);
241    unsigned int shiftedBit = 1;
242    int exponent = 0;
243    /* The invariant "shiftedBit = 2^exponent" will hold throughout the
244       entire while loop. */
245    while (exponent < 32)
246    {
247      if (shiftedBit & blockBits) matchedBits++;
248      if (exponent + (32 * block) == i) return matchedBits;
249      shiftedBit = shiftedBit << 1;
250      exponent++;
251    }
252  }
253  /* We should never reach this line of code. */
254  assume(false);
255  return -1;
256}
257
258int MinorKey::getRelativeColumnIndex(const int i) const
259{
260  /* This method is to return the relative (0-based) index
261     of the column with absolute index \c i.
262     Example: bit-pattern of columns: "10010001101", i = 7:
263        This should yield the 0-based relative index of the bit
264        corresponding to column no. 7, i.e. 3. */
265
266  int matchedBits = -1; /* counter for matched bits; this is going
267                           to contain our return value */
268  for (int block = 0; block < getNumberOfColumnBlocks(); block ++)
269  {
270    /* start with lowest bits, i.e. in block No. 0 */
271    /* the bits in this block of 32 bits: */
272    unsigned int blockBits = getColumnKey(block);
273    unsigned int shiftedBit = 1;
274    int exponent = 0;
275    /* The invariant "shiftedBit = 2^exponent" will hold
276       throughout the entire while loop. */
277    while (exponent < 32)
278    {
279      if (shiftedBit & blockBits) matchedBits++;
280      if (exponent + (32 * block) == i) return matchedBits;
281      shiftedBit = shiftedBit << 1;
282      exponent++;
283    }
284  }
285  /* We should never reach this line of code. */
286  assume(false);
287  return -1;
288}
289
290unsigned int MinorKey::getRowKey(const int blockIndex) const
291{
292  return _rowKey[blockIndex];
293}
294
295unsigned int MinorKey::getColumnKey(const int blockIndex) const
296{
297  return _columnKey[blockIndex];
298}
299
300int MinorKey::getNumberOfRowBlocks() const
301{
302  return _numberOfRowBlocks;
303}
304
305int MinorKey::getNumberOfColumnBlocks() const
306{
307  return _numberOfColumnBlocks;
308}
309
310int MinorKey::getSetBits(const int a) const
311{
312  int b = 0;
313  if (a == 1)
314  { /* rows */
315    for (int i = 0; i < _numberOfRowBlocks; i++)
316    {
317      unsigned int m = _rowKey[i];
318      unsigned int k = 1;
319      for (int j = 0; j < 32; j++)
320      {
321        /* k = 2^j */
322        if (m & k) b++;
323        k = k << 1;
324      }
325    }
326  }
327  else
328  { /* columns */
329    for (int i = 0; i < _numberOfColumnBlocks; i++)
330    {
331      unsigned int m = _columnKey[i];
332      unsigned int k = 1;
333      for (int j = 0; j < 32; j++)
334      {
335        /* k = 2^j */
336        if (m & k) b++;
337        k = k << 1;
338      }
339    }
340  }
341  return b;
342}
343
344MinorKey MinorKey::getSubMinorKey (const int absoluteEraseRowIndex,
345                                   const int absoluteEraseColumnIndex) const
346{
347  int rowBlock = absoluteEraseRowIndex / 32;
348  int exponent = absoluteEraseRowIndex % 32;
349  unsigned int newRowBits = getRowKey(rowBlock) - (1 << exponent);
350  int highestRowBlock = getNumberOfRowBlocks() - 1;
351  /* highestRowBlock will finally contain the highest block index with
352     non-zero bit pattern */
353  if ((newRowBits == 0) && (rowBlock == highestRowBlock))
354  {
355    /* we have thus nullified the highest block;
356       we can now forget about the highest block... */
357    highestRowBlock -= 1;
358    while (getRowKey(highestRowBlock) == 0) /* ...and maybe even some more
359                                               zero-blocks */
360      highestRowBlock -= 1;
361  }
362  /* highestRowBlock now contains the highest row block index with non-zero
363     bit pattern */
364
365  int columnBlock = absoluteEraseColumnIndex / 32;
366  exponent = absoluteEraseColumnIndex % 32;
367  unsigned int newColumnBits = getColumnKey(columnBlock) - (1 << exponent);
368  int highestColumnBlock = getNumberOfColumnBlocks() - 1;
369  /* highestColumnBlock will finally contain the highest block index with
370     non-zero bit pattern */
371  if ((newColumnBits == 0) && (columnBlock == highestColumnBlock))
372  {
373    /* we have thus nullified the highest block;
374       we can now forget about the highest block... */
375    highestColumnBlock -= 1;
376    while (getColumnKey(highestColumnBlock) == 0) /* ...and maybe even some
377                                                     more zero-blocks */
378      highestColumnBlock -= 1;
379  }
380  /* highestColumnBlock now contains the highest column block index with
381     non-zero bit pattern */
382
383  MinorKey result(highestRowBlock + 1, _rowKey, highestColumnBlock + 1,
384                  _columnKey);
385  /* This is just a copy with maybe some leading bit blocks omitted. We still
386     need to re-define the row block at index 'rowBlock' and the column block
387     at index 'columnBlock': */
388  if ((newRowBits != 0) || (rowBlock < getNumberOfRowBlocks() - 1))
389    result.setRowKey(rowBlock, newRowBits);
390  if ((newColumnBits != 0) || (columnBlock < getNumberOfColumnBlocks() - 1))
391    result.setColumnKey(columnBlock, newColumnBits);
392
393  /* let's check that the number of selected rows and columns are equal;
394     (this check is only performed in the debug version) */
395  assume(result.getSetBits(1) == result.getSetBits(2));
396
397  return result;
398}
399
400void MinorKey::setRowKey (const int blockIndex, const unsigned int rowKey)
401{
402    _rowKey[blockIndex] = rowKey;
403}
404
405void MinorKey::setColumnKey (const int blockIndex,
406                             const unsigned int columnKey)
407{
408    _columnKey[blockIndex] = columnKey;
409}
410
411int MinorKey::compare (const MinorKey& that) const
412{
413  /* compare by rowKeys first; in case of equality, use columnKeys */
414  if (this->getNumberOfRowBlocks() < that.getNumberOfRowBlocks())
415    return -1;
416  if (this->getNumberOfRowBlocks() > that.getNumberOfRowBlocks())
417    return 1;
418  /* Here, numbers of rows are equal. */
419  for (int r = this->getNumberOfRowBlocks() - 1; r >= 0; r--)
420  {
421    if (this->getRowKey(r) < that.getRowKey(r)) return -1;
422    if (this->getRowKey(r) > that.getRowKey(r)) return 1;
423  }
424  /* Here, this and that encode ecaxtly the same sets of rows.
425     Now, we take a look at the columns. */
426  if (this->getNumberOfColumnBlocks() < that.getNumberOfColumnBlocks())
427    return -1;
428  if (this->getNumberOfColumnBlocks() > that.getNumberOfColumnBlocks())
429    return 1;
430  /* Here, numbers of columns are equal. */
431  for (int c = this->getNumberOfColumnBlocks() - 1; c >= 0; c--)
432  {
433    if (this->getColumnKey(c) < that.getColumnKey(c)) return -1;
434    if (this->getColumnKey(c) > that.getColumnKey(c)) return 1;
435  }
436  /* Here, this and that encode exactly the same sets of rows and columns. */
437  return 0;
438}
439
440/* just to make the compiler happy;
441   this method should never be called */
442bool MinorKey::operator==(const MinorKey& mk) const
443{
444  assume(false);
445  return this->compare(mk) == 0;
446}
447
448/* just to make the compiler happy;
449   this method should never be called */
450bool MinorKey::operator<(const MinorKey& mk) const
451{
452  assume(false);
453  return this->compare(mk) == -1;
454}
455
456void MinorKey::selectFirstRows (const int k, const MinorKey& mk)
457{
458  int hitBits = 0;      /* the number of bits we have hit; in the end, this
459                           has to be equal to k, the dimension of the minor */
460  int blockIndex = -1;  /* the index of the current int in mk */
461  unsigned int highestInt = 0;  /* the new highest block of this MinorKey */
462  /* We determine which ints of mk we can copy. Their indices will be
463     0, 1, ..., blockIndex - 1. And highestInt is going to capture the highest
464     int (which may be only a portion of the corresponding int in mk.
465     We loop until hitBits = k: */
466  while (hitBits < k)
467  {
468    blockIndex++;
469    highestInt = 0;
470    unsigned int currentInt = mk.getRowKey(blockIndex);
471    unsigned int shiftedBit = 1;
472    int exponent = 0;
473    /* invariant in the loop: shiftedBit = 2^exponent */
474    while (exponent < 32 && hitBits < k)
475    {
476      if (shiftedBit & currentInt)
477      {
478        highestInt += shiftedBit;
479        hitBits++;
480      }
481      shiftedBit = shiftedBit << 1;
482      exponent++;
483    }
484  }
485  /* free old memory */
486  delete [] _rowKey; _rowKey = 0;
487  _numberOfRowBlocks = blockIndex + 1;
488  /* allocate memory for new entries in _rowKey; */
489  _rowKey = new unsigned int[_numberOfRowBlocks];
490  /* copying values from mk to this MinorKey */
491  for (int r = 0; r < blockIndex; r++)
492    _rowKey[r] = mk.getRowKey(r);
493  _rowKey[blockIndex] = highestInt;
494}
495
496void MinorKey::selectFirstColumns (const int k, const MinorKey& mk)
497{
498  int hitBits = 0;      /* the number of bits we have hit; in the end, this
499                           has to be equal to k, the dimension of the minor */
500  int blockIndex = -1;  /* the index of the current int in mk */
501  unsigned int highestInt = 0;  /* the new highest block of this MinorKey */
502  /* We determine which ints of mk we can copy. Their indices will be
503     0, 1, ..., blockIndex - 1. And highestInt is going to capture the highest
504     int (which may be only a portion of the corresponding int in mk.
505     We loop until hitBits = k: */
506  while (hitBits < k)
507  {
508    blockIndex++;
509    highestInt = 0;
510    unsigned int currentInt = mk.getColumnKey(blockIndex);
511    unsigned int shiftedBit = 1;
512    int exponent = 0;
513    /* invariant in the loop: shiftedBit = 2^exponent */
514    while (exponent < 32 && hitBits < k)
515    {
516      if (shiftedBit & currentInt)
517      {
518        highestInt += shiftedBit;
519        hitBits++;
520      }
521      shiftedBit = shiftedBit << 1;
522      exponent++;
523    }
524  }
525  /* free old memory */
526  delete [] _columnKey; _columnKey = 0;
527  _numberOfColumnBlocks = blockIndex + 1;
528  /* allocate memory for new entries in _columnKey; */
529  _columnKey = new unsigned int[_numberOfColumnBlocks];
530  /*  copying values from mk to this MinorKey */
531  for (int c = 0; c < blockIndex; c++)
532    _columnKey[c] = mk.getColumnKey(c);
533  _columnKey[blockIndex] = highestInt;
534}
535
536bool MinorKey::selectNextRows (const int k, const MinorKey& mk)
537{
538  /* We need to compute the set of k rows which must all be contained in mk.
539     AND: This set must be the least possible of this kind which is larger
540          than the currently encoded set of rows. (Here, '<' is w.r.t. to the
541          natural ordering on multi-indices.
542     Example: mk encodes the rows according to the bit pattern 11010111,
543              k = 3, this MinorKey encodes 10010100. Then, the method must
544              shift the set of rows in this MinorKey to 11000001 (, and
545              return true). */
546
547  /* The next two variables will finally name a row which is
548     (1) currently not yet among the rows in this MinorKey, but
549     (2) among the rows in mk, and
550     (3) which is "higher" than the lowest row in this MinorKey, and
551     (4) which is the lowest possible choice such that (1) - (3) hold.
552     If we should not be able to find such a row, then there is no next
553     subset of rows. In this case, the method will return false; otherwise
554     always true. */
555  int newBitBlockIndex = 0;        /* the block index of the bit */
556  unsigned int newBitToBeSet = 0;  /* the bit as 2^e, where 0 <= e <= 31 */
557
558  /* number of ints (representing rows) in this MinorKey: */
559  int blockCount = this->getNumberOfRowBlocks();
560  /* for iterating along the blocks of mk: */
561  int mkBlockIndex = mk.getNumberOfRowBlocks();
562
563  int hitBits = 0;    /* the number of bits we have hit */
564  int bitCounter = 0; /* for storing the number of bits hit before a
565                         specific moment; see below */
566  while (hitBits < k)
567  {
568    mkBlockIndex--;
569    unsigned int currentInt = mk.getRowKey(mkBlockIndex);
570    unsigned int shiftedBit = 1 << 31; /* initially, this equals 2^31, i.e.
571                                          the highest bit */
572    while (hitBits < k && shiftedBit > 0)
573    {
574      if ((blockCount - 1 >= mkBlockIndex) &&
575        (shiftedBit & this->getRowKey(mkBlockIndex))) hitBits++;
576      else if (shiftedBit & currentInt)
577      {
578        newBitToBeSet = shiftedBit;
579        newBitBlockIndex = mkBlockIndex;
580        bitCounter = hitBits; /* So, whenever we set newBitToBeSet, we want
581                                 to remember the momentary number of hit
582                                 bits. This will later be needed; see below. */
583      }
584      shiftedBit = shiftedBit >> 1;
585    }
586  }
587  if (newBitToBeSet == 0)
588  {
589    return false;
590  }
591  else
592  {
593    /* Note that the following must hold when reaching this line of code:
594       (1) The row with bit newBitToBeSet in this->getRowKey(newBitBlockIndex)
595           is currently not among the rows in this MinorKey, but
596       (2) it is among the rows in mk, and
597       (3) it is higher than the lowest row in this MinorKey, and
598       (4) it is the lowest possible choice such that (1) - (3) hold.
599       In the above example, we would reach this line with
600       newBitToBeSet == 2^6 and bitCounter == 1 (resulting from the bit 2^7).
601       */
602
603    if (blockCount - 1 < newBitBlockIndex)
604    { /* In this case, _rowKey is too small. */
605      /* free old memory */
606      delete [] _rowKey; _rowKey = 0;
607      _numberOfRowBlocks = newBitBlockIndex + 1;
608      /* allocate memory for new entries in _rowKey; */
609      _rowKey = new unsigned int[_numberOfRowBlocks];
610      /* initializing entries to zero */
611        for (int r = 0; r < _numberOfRowBlocks; r++) _rowKey[r] = 0;
612    }
613    else
614    {
615      /* We need to delete all bits in _rowKey[newBitBlockIndex] that are
616         below newBitToBeSet: */
617      unsigned int anInt = this->getRowKey(newBitBlockIndex);
618      unsigned int deleteBit = newBitToBeSet >> 1; // in example: = 2^5
619      while (deleteBit > 0)
620      {
621        if (anInt & deleteBit) anInt -= deleteBit;
622        deleteBit = deleteBit >> 1;
623      };
624      _rowKey[newBitBlockIndex] = anInt;
625      /* ...and we delete all entries in _rowKey[i] for
626         0 <= i < newBitBlockIndex */
627      for (int i = 0; i < newBitBlockIndex; i++)
628        _rowKey[i] = 0;
629    }
630
631    /* We have now deleted all bits from _rowKey[...] below the bit
632       2^newBitToBeSet.
633       In the example we shall have at this point: _rowKey[...] = 10000000.
634       Now let's set the new bit: */
635    _rowKey[newBitBlockIndex] += newBitToBeSet;
636    /* in the example: _rowKey[newBitBlockIndex] = 11000000 */
637    bitCounter++; /* This is now the number of correct bits in _rowKey[...];
638                     i.e. in the example this will be equal to 2. */
639
640    /* Now we only need to fill _rowKey[...] with the lowest possible bits
641       until it consists of exactly k bits. (We know that we need to set
642       exactly (k - bitCounter) additional bits.) */
643    mkBlockIndex = -1;
644    while (bitCounter < k)
645    {
646      mkBlockIndex++;
647      unsigned int currentInt = mk.getRowKey(mkBlockIndex);
648      unsigned int shiftedBit = 1;
649      int exponent = 0;
650      /* invariant: shiftedBit = 2^exponent */
651      while (bitCounter < k && exponent < 32)
652      {
653        if (shiftedBit & currentInt)
654        {
655          _rowKey[mkBlockIndex] += shiftedBit;
656          bitCounter++;
657        };
658        shiftedBit = shiftedBit << 1;
659        exponent++;
660      }
661    };
662    /* in the example, we shall obtain _rowKey[...] = 11000001 */
663    return true;
664  }
665}
666
667bool MinorKey::selectNextColumns (const int k, const MinorKey& mk)
668{
669  /* We need to compute the set of k columns which must all be contained in mk.
670     AND: This set must be the least possible of this kind which is larger
671          than the currently encoded set of columns. (Here, '<' is w.r.t. to
672          the natural ordering on multi-indices.
673     Example: mk encodes the columns according to the bit pattern 11010111,
674              k = 3, this MinorKey encodes 10010100. Then, the method must
675              shift the set of columns in this MinorKey to 11000001 (, and
676              return true). */
677
678  /* The next two variables will finally name a column which is
679     (1) currently not yet among the columns in this MinorKey, but
680     (2) among the columns in mk, and
681     (3) which is "higher" than the lowest column in this MinorKey, and
682     (4) which is the lowest possible choice such that (1) - (3) hold.
683     If we should not be able to find such a column, then there is no next
684     subset of columns. In this case, the method will return false; otherwise
685     always true. */
686  int newBitBlockIndex = 0;        /* the block index of the bit */
687  unsigned int newBitToBeSet = 0;  /* the bit as 2^e, where 0 <= e <= 31 */
688
689   /* number of ints (representing columns) in this MinorKey: */
690  int blockCount = this->getNumberOfColumnBlocks();
691  /* for iterating along the blocks of mk: */
692  int mkBlockIndex = mk.getNumberOfColumnBlocks();
693
694  int hitBits = 0;    /* the number of bits we have hit */
695  int bitCounter = 0; /* for storing the number of bits hit before a specific
696                         moment; see below */
697  while (hitBits < k)
698  {
699    mkBlockIndex--;
700    unsigned int currentInt = mk.getColumnKey(mkBlockIndex);
701    unsigned int shiftedBit = 1 << 31; /* initially, this equals 2^31, i.e.
702                                          the highest bit */
703    while (hitBits < k && shiftedBit > 0)
704    {
705      if ((blockCount - 1 >= mkBlockIndex) &&
706        (shiftedBit & this->getColumnKey(mkBlockIndex))) hitBits++;
707      else if (shiftedBit & currentInt) 
708      {
709        newBitToBeSet = shiftedBit;
710        newBitBlockIndex = mkBlockIndex;
711        bitCounter = hitBits; /* So, whenever we set newBitToBeSet, we want to
712                                 remember the momentary number of hit bits.
713                                 This will later be needed; see below. */
714      }
715      shiftedBit = shiftedBit >> 1;
716    }
717  }
718  if (newBitToBeSet == 0)
719  {
720    return false;
721  }
722  else
723  {
724    /* Note that the following must hold when reaching this line of code:
725       (1) The column with bit newBitToBeSet in
726           this->getColumnKey(newBitBlockIndex) is currently not among the
727           columns in this MinorKey, but
728       (2) it is among the columns in mk, and
729       (3) it is higher than the lowest columns in this MinorKey, and
730       (4) it is the lowest possible choice such that (1) - (3) hold.
731       In the above example, we would reach this line with
732       newBitToBeSet == 2^6 and bitCounter == 1 (resulting from the bit 2^7).
733       */
734
735    if (blockCount - 1 < newBitBlockIndex)
736    { /* In this case, _columnKey is too small. */
737        /* free old memory */
738        delete [] _columnKey; _columnKey = 0;
739        _numberOfColumnBlocks = newBitBlockIndex + 1;
740        /* allocate memory for new entries in _columnKey; */
741        _columnKey = new unsigned int[_numberOfColumnBlocks];
742        /* initializing entries to zero */
743        for (int c = 0; c < _numberOfColumnBlocks; c++) _columnKey[c] = 0;
744    }
745    else
746    {
747      /* We need to delete all bits in _columnKey[newBitBlockIndex] that are
748         below newBitToBeSet: */
749      unsigned int anInt = this->getColumnKey(newBitBlockIndex);
750      unsigned int deleteBit = newBitToBeSet >> 1; /* in example: = 2^5 */
751      while (deleteBit > 0)
752      {
753        if (anInt & deleteBit) anInt -= deleteBit;
754        deleteBit = deleteBit >> 1;
755      };
756      _columnKey[newBitBlockIndex] = anInt;
757      /* ...and we delete all entries in _columnKey[i] fo
758         0 <= i < newBitBlockIndex */
759      for (int i = 0; i < newBitBlockIndex; i++)
760        _columnKey[i] = 0;
761    }
762    /* We have now deleted all bits from _columnKey[...] below the bit
763       2^newBitToBeSet. In the example we shall have at this point:
764       _columnKey[...] = 10000000. Now let's set the new bit: */
765    _columnKey[newBitBlockIndex] += newBitToBeSet;
766    /* in the example: _columnKey[newBitBlockIndex] = 11000000 */
767    bitCounter++; /* This is now the number of correct bits in
768                     _columnKey[...]; i.e. in the example this will be equal
769                     to 2. */
770
771    /* Now we only need to fill _columnKey[...] with the lowest possible bits
772       until it consists of exactly k bits. (We know that we need to set
773       exactly (k - bitCounter) additional bits.) */
774    mkBlockIndex = -1;
775    while (bitCounter < k)
776    {
777      mkBlockIndex++;
778      unsigned int currentInt = mk.getColumnKey(mkBlockIndex);
779      unsigned int shiftedBit = 1;
780      int exponent = 0;
781      /* invariant: shiftedBit = 2^exponent */
782      while (bitCounter < k && exponent < 32)
783      {
784        if (shiftedBit & currentInt)
785        {
786          _columnKey[mkBlockIndex] += shiftedBit;
787          bitCounter++;
788        };
789        shiftedBit = shiftedBit << 1;
790        exponent++;
791      }
792    };
793    /* in the example, we shall obtain _columnKey[...] = 11000001 */
794    return true;
795  }
796}
797
798string MinorKey::toString() const
799{
800  string t;
801  string s = "(";
802  unsigned int z = 0;
803  for (int r = this->getNumberOfRowBlocks() - 1; r >= 0; r--)
804  {
805    t = "";
806    z = this->getRowKey(r);
807    while (z != 0)
808    {
809      if ((z % 2) != 0) t = "1" + t; else t = "0" + t;
810      z = z / 2;
811    }
812    if (r < this->getNumberOfRowBlocks() - 1)
813      t = string(32 - t.length(), '0') + t;
814    s += t;
815  }
816  s += ", ";
817  for (int c = this->getNumberOfColumnBlocks() - 1; c >= 0; c--)
818  {
819    t = "";
820    z = this->getColumnKey(c);
821    while (z != 0)
822    {
823      if ((z % 2) != 0) t = "1" + t; else t = "0" + t;
824      z = z / 2;
825    }
826    if (c < this->getNumberOfColumnBlocks() - 1)
827      t = string(32 - t.length(), '0') + t;
828    s += t;
829  }
830  s += ")";
831  return s;
832}
833
834int MinorValue::g_rankingStrategy = -1;
835
836int MinorValue::getWeight () const
837{
838  assume(false);  /* must be overridden in derived classes */
839  return 0;
840}
841
842/* just to make the compiler happy;
843   this method should never be called */
844bool MinorValue::operator==(const MinorValue& mv) const
845{
846  assume(false);
847  return (this == &mv);  /* compare addresses of both objects */
848}
849
850string MinorValue::toString () const
851{
852  assume(false);  /* must be overridden in derived classes */
853  return "";
854}
855
856/* just to make the compiler happy;
857   this method should never be called */
858bool MinorValue::operator<(const MinorValue& mv) const
859{
860  assume(false);
861  return (this < &mv);  /* compare addresses of both objects */
862}
863
864int MinorValue::getRetrievals() const
865{
866  return _retrievals;
867}
868
869void MinorValue::incrementRetrievals()
870{
871  _retrievals++;
872}
873
874int MinorValue::getPotentialRetrievals() const
875{
876  return _potentialRetrievals;
877}
878
879int MinorValue::getMultiplications() const
880{
881  return _multiplications;
882}
883
884int MinorValue::getAdditions() const
885{
886  return _additions;
887}
888
889int MinorValue::getAccumulatedMultiplications() const
890{
891  return _accumulatedMult;
892}
893
894int MinorValue::getAccumulatedAdditions() const
895{
896  return _accumulatedSum;
897}
898
899void MinorValue::print() const
900{
901  PrintS(this->toString().c_str());
902}
903
904
905void MinorValue::SetRankingStrategy (const int rankingStrategy)
906{
907  g_rankingStrategy = rankingStrategy;
908  if (g_rankingStrategy == 6)
909  {
910    /* initialize the random generator with system time */
911    srand ( time(NULL) );
912  }
913}
914
915int MinorValue::GetRankingStrategy()
916{
917  return g_rankingStrategy;
918}
919
920/* this is for generically accessing the rank measure regardless of
921   which strategy has been set */
922int MinorValue::getUtility () const
923{
924  switch (this->GetRankingStrategy())
925  {
926    case 1: return this->rankMeasure1();
927    case 2: return this->rankMeasure2();
928    case 3: return this->rankMeasure3();
929    case 4: return this->rankMeasure4();
930    case 5: return this->rankMeasure5();
931    default: return this->rankMeasure1();
932  }
933}
934
935/* here are some sensible caching strategies: */
936int MinorValue::rankMeasure1 () const
937{
938  /* number of actually performed multiplications */
939  return this->getMultiplications();
940}
941
942int MinorValue::rankMeasure2 () const
943{
944  /* accumulated number of performed multiplications, i.e. all including
945     nested multiplications */
946  return this->getAccumulatedMultiplications();
947}
948
949int MinorValue::rankMeasure3 () const
950{
951  /* number of performed multiplications, weighted with the ratio of
952     not yet performed retrievals over the maximal number of retrievals */
953  return this->getMultiplications()
954         * (this->getPotentialRetrievals()
955         - this->getRetrievals())
956         / this->getPotentialRetrievals();
957}
958
959int MinorValue::rankMeasure4 () const
960{
961  /* number of performed multiplications,
962     multiplied with the number of not yet performed retrievals */
963  return this->getMultiplications()
964         * (this->getPotentialRetrievals()
965         - this->getRetrievals());
966}
967
968int MinorValue::rankMeasure5 () const
969{
970  /* number of not yet performed retrievals;
971     tends to cache entries longer when they are going to be retrieved more
972     often in the future */
973  return this->getPotentialRetrievals() - this->getRetrievals();
974}
975
976int IntMinorValue::getWeight () const
977{
978  /* put measure for size of MinorValue here, i.e. number of monomials in
979     polynomial; so far, we use the accumulated number of multiplications
980     (i.e., including all nested ones) to simmulate the size of a polynomial */
981  return _accumulatedMult;
982}
983
984IntMinorValue::IntMinorValue (const int result, const int multiplications,
985                              const int additions,
986                              const int accumulatedMultiplications,
987                              const int accumulatedAdditions,
988                              const int retrievals,
989                              const int potentialRetrievals)
990{
991  _result = result;
992  _multiplications = multiplications;
993  _additions = additions;
994  _accumulatedMult = accumulatedMultiplications;
995  _accumulatedSum = accumulatedAdditions;
996  _potentialRetrievals = potentialRetrievals;
997  _retrievals = retrievals;
998}
999
1000IntMinorValue::IntMinorValue ()
1001{
1002  _result = -1;
1003  _multiplications = -1;
1004  _additions = -1;
1005  _accumulatedMult = -1;
1006  _accumulatedSum = -1;
1007  _potentialRetrievals = -1;
1008  _retrievals = -1;
1009}
1010
1011IntMinorValue::~IntMinorValue()
1012{
1013}
1014
1015int IntMinorValue::getResult() const
1016{
1017  return _result;
1018}
1019
1020string IntMinorValue::toString () const
1021{
1022  char h[10];
1023
1024  /* Let's see whether a cache has been used to compute this MinorValue: */
1025  bool cacheHasBeenUsed = true;
1026  if (this->getRetrievals() == -1) cacheHasBeenUsed = false;
1027
1028  sprintf(h, "%d", this->getResult());
1029  string s = h;
1030  s += " [retrievals: ";
1031  if (cacheHasBeenUsed) { sprintf(h, "%d", this->getRetrievals()); s += h; }
1032  else s += "/";
1033  s += " (of ";
1034  if (cacheHasBeenUsed)
1035  {
1036    sprintf(h, "%d", this->getPotentialRetrievals());
1037    s += h;
1038  }
1039  else s += "/";
1040  s += "), *: ";
1041  sprintf(h, "%d", this->getMultiplications()); s += h;
1042  s += " (accumulated: ";
1043  sprintf(h, "%d", this->getAccumulatedMultiplications()); s += h;
1044  s += "), +: ";
1045  sprintf(h, "%d", this->getAdditions()); s += h;
1046  s += " (accumulated: ";
1047  sprintf(h, "%d", this->getAccumulatedAdditions()); s += h;
1048  s += "), rank: ";
1049  if (cacheHasBeenUsed) { sprintf(h, "%d", this->getUtility()); s += h; }
1050  else s += "/";
1051  s += "]";
1052  return s;
1053}
1054
1055IntMinorValue::IntMinorValue (const IntMinorValue& mv)
1056{
1057  _result = mv.getResult();
1058  _retrievals = mv.getRetrievals();
1059  _potentialRetrievals = mv.getPotentialRetrievals();
1060  _multiplications = mv.getMultiplications();
1061  _additions = mv.getAdditions();
1062  _accumulatedMult = mv.getAccumulatedMultiplications();
1063  _accumulatedSum = mv.getAccumulatedAdditions();
1064}
1065
1066PolyMinorValue::PolyMinorValue (const poly result, const int multiplications,
1067                                const int additions,
1068                                const int accumulatedMultiplications,
1069                                const int accumulatedAdditions,
1070                                const int retrievals,
1071                                const int potentialRetrievals)
1072{
1073  _result = pCopy(result);
1074  _multiplications = multiplications;
1075  _additions = additions;
1076  _accumulatedMult = accumulatedMultiplications;
1077  _accumulatedSum = accumulatedAdditions;
1078  _potentialRetrievals = potentialRetrievals;
1079  _retrievals = retrievals;
1080}
1081
1082PolyMinorValue::PolyMinorValue ()
1083{
1084  _result = NULL;
1085  _multiplications = -1;
1086  _additions = -1;
1087  _accumulatedMult = -1;
1088  _accumulatedSum = -1;
1089  _potentialRetrievals = -1;
1090  _retrievals = -1;
1091}
1092
1093PolyMinorValue::~PolyMinorValue()
1094{
1095  p_Delete(&_result, currRing);
1096}
1097
1098poly PolyMinorValue::getResult() const
1099{
1100  return _result;
1101}
1102
1103int PolyMinorValue::getWeight () const
1104{
1105  /* put measure for size of PolyMinorValue here, e.g. the number of monomials
1106     in the cached polynomial */
1107  return pLength(_result); // the number of monomials in the polynomial
1108}
1109
1110string PolyMinorValue::toString () const
1111{
1112  char h[20];
1113
1114  /* Let's see whether a cache has been used to compute this MinorValue: */
1115  bool cacheHasBeenUsed = true;
1116  if (this->getRetrievals() == -1) cacheHasBeenUsed = false;
1117
1118  string s = pString(_result);
1119  s += " [retrievals: ";
1120  if (cacheHasBeenUsed) { sprintf(h, "%d", this->getRetrievals()); s += h; }
1121  else s += "/";
1122  s += " (of ";
1123  if (cacheHasBeenUsed)
1124  {
1125    sprintf(h, "%d", this->getPotentialRetrievals());
1126    s += h;
1127  }
1128  else s += "/";
1129  s += "), *: ";
1130  sprintf(h, "%d", this->getMultiplications()); s += h;
1131  s += " (accumulated: ";
1132  sprintf(h, "%d", this->getAccumulatedMultiplications()); s += h;
1133  s += "), +: ";
1134  sprintf(h, "%d", this->getAdditions()); s += h;
1135  s += " (accumulated: ";
1136  sprintf(h, "%d", this->getAccumulatedAdditions()); s += h;
1137  s += "), rank: ";
1138  if (cacheHasBeenUsed) { sprintf(h, "%d", this->getUtility()); s += h; }
1139  else s += "/";
1140  s += "]";
1141  return s;
1142}
1143
1144PolyMinorValue::PolyMinorValue (const PolyMinorValue& mv)
1145{
1146  _result = pCopy(mv.getResult());
1147  _retrievals = mv.getRetrievals();
1148  _potentialRetrievals = mv.getPotentialRetrievals();
1149  _multiplications = mv.getMultiplications();
1150  _additions = mv.getAdditions();
1151  _accumulatedMult = mv.getAccumulatedMultiplications();
1152  _accumulatedSum = mv.getAccumulatedAdditions();
1153}
1154
1155void PolyMinorValue::operator= (const PolyMinorValue& mv)
1156{
1157  if (_result != mv.getResult()) pDelete(&_result);
1158  _result = pCopy(mv.getResult());
1159  _retrievals = mv.getRetrievals();
1160  _potentialRetrievals = mv.getPotentialRetrievals();
1161  _multiplications = mv.getMultiplications();
1162  _additions = mv.getAdditions();
1163  _accumulatedMult = mv.getAccumulatedMultiplications();
1164  _accumulatedSum = mv.getAccumulatedAdditions();
1165}
Note: See TracBrowser for help on using the repository browser.