source: git/kernel/linear_algebra/Minor.cc @ 9f7665

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