source: git/Singular/Minor.cc @ 894604

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