source: git/kernel/linear_algebra/Minor.cc @ aa8a7e

fieker-DuValspielwiese
Last change on this file since aa8a7e was aa8a7e, checked in by Hans Schoenemann <hannes@…>, 7 years ago
use include ".." for singular related .h, p9
  • Property mode set to 100644
File size: 37.0 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
11using namespace std;
12
13void MinorKey::reset()
14{
15  _numberOfRowBlocks = 0;
16  _numberOfColumnBlocks = 0;
17  omFree(_rowKey);
18  _rowKey = NULL;
19  omFree(_columnKey);
20  _columnKey = NULL;
21}
22
23MinorKey::MinorKey (const MinorKey& mk)
24{
25  _numberOfRowBlocks = mk.getNumberOfRowBlocks();
26  _numberOfColumnBlocks = mk.getNumberOfColumnBlocks();;
27
28  /* allocate memory for new entries in _rowKey and _columnKey */
29  _rowKey = (unsigned*)omAlloc(_numberOfRowBlocks*sizeof(unsigned));
30  _columnKey = (unsigned*)omAlloc(_numberOfColumnBlocks*sizeof(unsigned));
31
32  /* copying values from parameter arrays to private arrays */
33  for (int r = 0; r < _numberOfRowBlocks; r++)
34    _rowKey[r] = mk.getRowKey(r);
35  for (int c = 0; c < _numberOfColumnBlocks; c++)
36    _columnKey[c] = mk.getColumnKey(c);
37}
38
39MinorKey& MinorKey::operator=(const MinorKey& mk)
40{
41  omfree(_rowKey); _rowKey = NULL;
42  omfree(_columnKey); _columnKey = NULL;
43  _numberOfRowBlocks = 0;
44  _numberOfColumnBlocks = 0;
45
46  _numberOfRowBlocks = mk.getNumberOfRowBlocks();
47  _numberOfColumnBlocks = mk.getNumberOfColumnBlocks();;
48
49  /* allocate memory for new entries in _rowKey and _columnKey */
50  _rowKey = (unsigned*)omalloc(_numberOfRowBlocks*sizeof(unsigned));
51  _columnKey = (unsigned*)omalloc(_numberOfColumnBlocks*sizeof(unsigned));
52
53  /* copying values from parameter arrays to private arrays */
54  for (int r = 0; r < _numberOfRowBlocks; r++)
55      _rowKey[r] = mk.getRowKey(r);
56  for (int c = 0; c < _numberOfColumnBlocks; c++)
57      _columnKey[c] = mk.getColumnKey(c);
58
59  return *this;
60}
61
62void MinorKey::set(const int lengthOfRowArray, const unsigned int* rowKey,
63                   const int lengthOfColumnArray,
64                   const unsigned int* columnKey)
65{
66  /* free memory of _rowKey and _columnKey */
67  if (_numberOfRowBlocks > 0) { omFree(_rowKey); }
68  if (_numberOfColumnBlocks > 0) { omFree(_columnKey); }
69
70  _numberOfRowBlocks = lengthOfRowArray;
71  _numberOfColumnBlocks = lengthOfColumnArray;
72
73  /* allocate memory for new entries in _rowKey and _columnKey; */
74  _rowKey = (unsigned*)omAlloc(_numberOfRowBlocks*sizeof(unsigned));
75  _columnKey = (unsigned*)omAlloc(_numberOfColumnBlocks*sizeof(unsigned));
76
77  /* copying values from parameter arrays to private arrays */
78  for (int r = 0; r < _numberOfRowBlocks; r++)
79    _rowKey[r] = rowKey[r];
80  for (int c = 0; c < _numberOfColumnBlocks; c++)
81    _columnKey[c] = columnKey[c];
82}
83
84MinorKey::MinorKey(const int lengthOfRowArray,
85                   const unsigned int* const rowKey,
86                   const int lengthOfColumnArray,
87                   const unsigned int* const columnKey)
88{
89  _numberOfRowBlocks = lengthOfRowArray;
90  _numberOfColumnBlocks = lengthOfColumnArray;
91
92  /* allocate memory for new entries in _rowKey and _columnKey */
93  _rowKey = (unsigned*)omalloc(_numberOfRowBlocks*sizeof(unsigned));
94  _columnKey = (unsigned*)omalloc(_numberOfColumnBlocks*sizeof(unsigned));
95
96  /* copying values from parameter arrays to private arrays */
97  for (int r = 0; r < _numberOfRowBlocks; r++)
98    _rowKey[r] = rowKey[r];
99
100  for (int c = 0; c < _numberOfColumnBlocks; c++)
101    _columnKey[c] = columnKey[c];
102}
103
104MinorKey::~MinorKey()
105{
106  _numberOfRowBlocks = 0;
107  _numberOfColumnBlocks = 0;
108  omfree(_rowKey); _rowKey = NULL;
109  omfree(_columnKey); _columnKey = NULL;
110}
111
112//void MinorKey::print() const
113//{
114//  PrintS(this->toString().c_str());
115//}
116
117int MinorKey::getAbsoluteRowIndex(const int i) const
118{
119  /* This method is to return the absolute (0-based) index of the i-th
120     row encoded in \a this.
121     Example: bit-pattern of rows: "10010001101", i = 3:
122        This should yield the 0-based absolute index of the 3-rd bit
123        (counted from the right), i.e. 7. */
124
125  int matchedBits = -1; /* counter for matched bits;
126                           this needs to reach i, then we're done */
127  for (int block = 0; block < getNumberOfRowBlocks(); block ++)
128  {
129    /* start with lowest bits, i.e. in block No. 0 */
130    /* the bits in this block of 32 bits: */
131    unsigned int blockBits = getRowKey(block);
132    unsigned int shiftedBit = 1;
133    int exponent = 0;
134    /* The invariant "shiftedBit = 2^exponent" will hold throughout the
135       entire while loop. */
136    while (exponent < 32)
137    {
138      if (shiftedBit & blockBits) matchedBits++;
139      if (matchedBits == i) return exponent + (32 * block);
140      shiftedBit = shiftedBit << 1;
141      exponent++;
142    }
143  }
144  /* We should never reach this line of code. */
145  assume(false);
146  return -1;
147}
148
149int MinorKey::getAbsoluteColumnIndex(const int i) const
150{
151  /* This method is to return the absolute (0-based) index of the i-th
152     column encoded in \a this.
153     Example: bit-pattern of columns: "10010001101", i = 3:
154        This should yield the 0-based absolute index of the 3-rd bit
155        (counted from the right), i.e. 7. */
156
157  int matchedBits = -1; /* counter for matched bits; this needs to reach i,
158                           then we're done */
159  for (int block = 0; block < getNumberOfColumnBlocks(); block ++)
160  {
161    /* start with lowest bits, i.e. in block No. 0 */
162    /* the bits in this block of 32 bits: */
163    unsigned int blockBits = getColumnKey(block);
164    unsigned int shiftedBit = 1;
165    int exponent = 0;
166    /* The invariant "shiftedBit = 2^exponent" will hold throughout the
167       entire while loop. */
168    while (exponent < 32)
169    {
170      if (shiftedBit & blockBits) matchedBits++;
171      if (matchedBits == i) return exponent + (32 * block);
172      shiftedBit = shiftedBit << 1;
173      exponent++;
174    }
175  }
176  /* We should never reach this line of code. */
177  assume(false);
178  return -1;
179}
180
181void MinorKey::getAbsoluteRowIndices(int* const target) const
182{
183  int i = 0; /* index for filling the target array */
184  for (int block = 0; block < getNumberOfRowBlocks(); block ++)
185  {
186    /* start with lowest bits, i.e. in block No. 0 */
187    /* the bits in this block of 32 bits: */
188    unsigned int blockBits = getRowKey(block);
189    unsigned int shiftedBit = 1;
190    int exponent = 0;
191    /* The invariant "shiftedBit = 2^exponent" will hold throughout the
192       entire while loop. */
193    while (exponent < 32)
194    {
195      if (shiftedBit & blockBits) target[i++] = exponent + (32 * block);
196      shiftedBit = shiftedBit << 1;
197      exponent++;
198    }
199  }
200}
201
202void MinorKey::getAbsoluteColumnIndices(int* const target) const
203{
204  int i = 0; /* index for filling the target array */
205  for (int block = 0; block < getNumberOfColumnBlocks(); block ++)
206  {
207    /* start with lowest bits, i.e. in block No. 0 */
208    /* the bits in this block of 32 bits: */
209    unsigned int blockBits = getColumnKey(block);
210    unsigned int shiftedBit = 1;
211    int exponent = 0;
212    /* The invariant "shiftedBit = 2^exponent" will hold throughout the
213       entire while loop. */
214    while (exponent < 32)
215    {
216      if (shiftedBit & blockBits) target[i++] = exponent + (32 * block);
217      shiftedBit = shiftedBit << 1;
218      exponent++;
219    }
220  }
221}
222
223int MinorKey::getRelativeRowIndex(const int i) const
224{
225  /* This method is to return the relative (0-based) index of the row
226     with absolute index \c i.
227     Example: bit-pattern of rows: "10010001101", i = 7:
228        This should yield the 0-based relative index of the bit
229        corresponding to row no. 7, i.e. 3. */
230
231  int matchedBits = -1; /* counter for matched bits; this is going to
232                           contain our return value */
233  for (int block = 0; block < getNumberOfRowBlocks(); block ++)
234  {
235    /* start with lowest bits, i.e. in block No. 0 */
236    /* the bits in this block of 32 bits: */
237    unsigned int blockBits = getRowKey(block);
238    unsigned int shiftedBit = 1;
239    int exponent = 0;
240    /* The invariant "shiftedBit = 2^exponent" will hold throughout the
241       entire while loop. */
242    while (exponent < 32)
243    {
244      if (shiftedBit & blockBits) matchedBits++;
245      if (exponent + (32 * block) == i) return matchedBits;
246      shiftedBit = shiftedBit << 1;
247      exponent++;
248    }
249  }
250  /* We should never reach this line of code. */
251  assume(false);
252  return -1;
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  return -1;
285}
286
287unsigned int MinorKey::getRowKey(const int blockIndex) const
288{
289  return _rowKey[blockIndex];
290}
291
292unsigned int MinorKey::getColumnKey(const int blockIndex) const
293{
294  return _columnKey[blockIndex];
295}
296
297int MinorKey::getNumberOfRowBlocks() const
298{
299  return _numberOfRowBlocks;
300}
301
302int MinorKey::getNumberOfColumnBlocks() const
303{
304  return _numberOfColumnBlocks;
305}
306
307#ifndef SING_NDEBUG
308int MinorKey::getSetBits(const int a) const
309{
310  int b = 0;
311  if (a == 1)
312  { /* rows */
313    for (int i = 0; i < _numberOfRowBlocks; i++)
314    {
315      unsigned int m = _rowKey[i];
316      unsigned int k = 1;
317      for (int j = 0; j < 32; j++)
318      {
319        /* k = 2^j */
320        if (m & k) b++;
321        k = k << 1;
322      }
323    }
324  }
325  else
326  { /* columns */
327    for (int i = 0; i < _numberOfColumnBlocks; i++)
328    {
329      unsigned int m = _columnKey[i];
330      unsigned int k = 1;
331      for (int j = 0; j < 32; j++)
332      {
333        /* k = 2^j */
334        if (m & k) b++;
335        k = k << 1;
336      }
337    }
338  }
339  return b;
340}
341#endif
342
343MinorKey MinorKey::getSubMinorKey (const int absoluteEraseRowIndex,
344                                   const int absoluteEraseColumnIndex) const
345{
346  int rowBlock = absoluteEraseRowIndex / 32;
347  int exponent = absoluteEraseRowIndex % 32;
348  unsigned int newRowBits = getRowKey(rowBlock) - (1 << exponent);
349  int highestRowBlock = getNumberOfRowBlocks() - 1;
350  /* highestRowBlock will finally contain the highest block index with
351     non-zero bit pattern */
352  if ((newRowBits == 0) && (rowBlock == highestRowBlock))
353  {
354    /* we have thus nullified the highest block;
355       we can now forget about the highest block... */
356    highestRowBlock -= 1;
357    while (getRowKey(highestRowBlock) == 0) /* ...and maybe even some more
358                                               zero-blocks */
359      highestRowBlock -= 1;
360  }
361  /* highestRowBlock now contains the highest row block index with non-zero
362     bit pattern */
363
364  int columnBlock = absoluteEraseColumnIndex / 32;
365  exponent = absoluteEraseColumnIndex % 32;
366  unsigned int newColumnBits = getColumnKey(columnBlock) - (1 << exponent);
367  int highestColumnBlock = getNumberOfColumnBlocks() - 1;
368  /* highestColumnBlock will finally contain the highest block index with
369     non-zero bit pattern */
370  if ((newColumnBits == 0) && (columnBlock == highestColumnBlock))
371  {
372    /* we have thus nullified the highest block;
373       we can now forget about the highest block... */
374    highestColumnBlock -= 1;
375    while (getColumnKey(highestColumnBlock) == 0) /* ...and maybe even some
376                                                     more zero-blocks */
377      highestColumnBlock -= 1;
378  }
379  /* highestColumnBlock now contains the highest column block index with
380     non-zero bit pattern */
381
382  MinorKey result(highestRowBlock + 1, _rowKey, highestColumnBlock + 1,
383                  _columnKey);
384  /* This is just a copy with maybe some leading bit blocks omitted. We still
385     need to re-define the row block at index 'rowBlock' and the column block
386     at index 'columnBlock': */
387  if ((newRowBits != 0) || (rowBlock < getNumberOfRowBlocks() - 1))
388    result.setRowKey(rowBlock, newRowBits);
389  if ((newColumnBits != 0) || (columnBlock < getNumberOfColumnBlocks() - 1))
390    result.setColumnKey(columnBlock, newColumnBits);
391
392  /* let's check that the number of selected rows and columns are equal;
393     (this check is only performed in the debug version) */
394  assume(result.getSetBits(1) == result.getSetBits(2));
395
396  return result;
397}
398
399void MinorKey::setRowKey (const int blockIndex, const unsigned int rowKey)
400{
401    _rowKey[blockIndex] = rowKey;
402}
403
404void MinorKey::setColumnKey (const int blockIndex,
405                             const unsigned int columnKey)
406{
407    _columnKey[blockIndex] = columnKey;
408}
409
410int MinorKey::compare (const MinorKey& that) const
411{
412  /* compare by rowKeys first; in case of equality, use columnKeys */
413  if (this->getNumberOfRowBlocks() < that.getNumberOfRowBlocks())
414    return -1;
415  if (this->getNumberOfRowBlocks() > that.getNumberOfRowBlocks())
416    return 1;
417  /* Here, numbers of rows are equal. */
418  for (int r = this->getNumberOfRowBlocks() - 1; r >= 0; r--)
419  {
420    if (this->getRowKey(r) < that.getRowKey(r)) return -1;
421    if (this->getRowKey(r) > that.getRowKey(r)) return 1;
422  }
423  /* Here, this and that encode ecaxtly the same sets of rows.
424     Now, we take a look at the columns. */
425  if (this->getNumberOfColumnBlocks() < that.getNumberOfColumnBlocks())
426    return -1;
427  if (this->getNumberOfColumnBlocks() > that.getNumberOfColumnBlocks())
428    return 1;
429  /* Here, numbers of columns are equal. */
430  for (int c = this->getNumberOfColumnBlocks() - 1; c >= 0; c--)
431  {
432    if (this->getColumnKey(c) < that.getColumnKey(c)) return -1;
433    if (this->getColumnKey(c) > that.getColumnKey(c)) return 1;
434  }
435  /* Here, this and that encode exactly the same sets of rows and columns. */
436  return 0;
437}
438
439/* just to make the compiler happy;
440   this method should never be called */
441bool MinorKey::operator==(const MinorKey& mk) const
442{
443  assume(false);
444  return this->compare(mk) == 0;
445}
446
447/* just to make the compiler happy;
448   this method should never be called */
449bool MinorKey::operator<(const MinorKey& mk) const
450{
451  assume(false);
452  return this->compare(mk) == -1;
453}
454
455void MinorKey::selectFirstRows (const int k, const MinorKey& mk)
456{
457  int hitBits = 0;      /* the number of bits we have hit; in the end, this
458                           has to be equal to k, the dimension of the minor */
459  int blockIndex = -1;  /* the index of the current int in mk */
460  unsigned int highestInt = 0;  /* the new highest block of this MinorKey */
461  /* We determine which ints of mk we can copy. Their indices will be
462     0, 1, ..., blockIndex - 1. And highestInt is going to capture the highest
463     int (which may be only a portion of the corresponding int in mk.
464     We loop until hitBits = k: */
465  while (hitBits < k)
466  {
467    blockIndex++;
468    highestInt = 0;
469    unsigned int currentInt = mk.getRowKey(blockIndex);
470    unsigned int shiftedBit = 1;
471    int exponent = 0;
472    /* invariant in the loop: shiftedBit = 2^exponent */
473    while (exponent < 32 && hitBits < k)
474    {
475      if (shiftedBit & currentInt)
476      {
477        highestInt += shiftedBit;
478        hitBits++;
479      }
480      shiftedBit = shiftedBit << 1;
481      exponent++;
482    }
483  }
484  /* free old memory */
485  omfree(_rowKey);
486  _rowKey = NULL;
487  _numberOfRowBlocks = blockIndex + 1;
488  /* allocate memory for new entries in _rowKey; */
489  _rowKey = (unsigned*)omAlloc(_numberOfRowBlocks*sizeof(unsigned));
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  omfree(_columnKey); _columnKey = NULL;
527  _numberOfColumnBlocks = blockIndex + 1;
528  /* allocate memory for new entries in _columnKey; */
529  _columnKey = (unsigned*)omAlloc(_numberOfColumnBlocks*sizeof(unsigned));
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      omFree(_rowKey); _rowKey = NULL;
607      _numberOfRowBlocks = newBitBlockIndex + 1;
608      /* allocate memory for new entries in _rowKey; */
609      _rowKey = (unsigned*)omAlloc(_numberOfRowBlocks*sizeof(unsigned));
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        omFree( _columnKey); _columnKey = NULL;
739        _numberOfColumnBlocks = newBitBlockIndex + 1;
740        /* allocate memory for new entries in _columnKey; */
741        _columnKey = (unsigned*)omAlloc(_numberOfColumnBlocks*sizeof(unsigned));
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{ return ""; }
800/*
801  string t;
802  string s = "(";
803  unsigned int z = 0;
804  for (int r = this->getNumberOfRowBlocks() - 1; r >= 0; r--)
805  {
806    t = "";
807    z = this->getRowKey(r);
808    while (z != 0)
809    {
810      if ((z % 2) != 0) t = "1" + t; else t = "0" + t;
811      z = z / 2;
812    }
813    if (r < this->getNumberOfRowBlocks() - 1)
814      t = string(32 - t.length(), '0') + t;
815    s += t;
816  }
817  s += ", ";
818  for (int c = this->getNumberOfColumnBlocks() - 1; c >= 0; c--)
819  {
820    t = "";
821    z = this->getColumnKey(c);
822    while (z != 0)
823    {
824      if ((z % 2) != 0) t = "1" + t; else t = "0" + t;
825      z = z / 2;
826    }
827    if (c < this->getNumberOfColumnBlocks() - 1)
828      t = string(32 - t.length(), '0') + t;
829    s += t;
830  }
831  s += ")";
832  return s;
833}
834*/
835
836int MinorValue::g_rankingStrategy = -1;
837
838int MinorValue::getWeight () const
839{
840  assume(false);  /* must be overridden in derived classes */
841  return 0;
842}
843
844/* just to make the compiler happy;
845   this method should never be called */
846bool MinorValue::operator==(const MinorValue& mv) const
847{
848  assume(false);
849  return (this == &mv);  /* compare addresses of both objects */
850}
851
852string MinorValue::toString () const
853{
854  assume(false);  /* must be overridden in derived classes */
855  return "";
856}
857
858/* just to make the compiler happy;
859   this method should never be called */
860bool MinorValue::operator<(const MinorValue& mv) const
861{
862  assume(false);
863  return (this < &mv);  /* compare addresses of both objects */
864}
865
866int MinorValue::getRetrievals() const
867{
868  return _retrievals;
869}
870
871void MinorValue::incrementRetrievals()
872{
873  _retrievals++;
874}
875
876int MinorValue::getPotentialRetrievals() const
877{
878  return _potentialRetrievals;
879}
880
881int MinorValue::getMultiplications() const
882{
883  return _multiplications;
884}
885
886int MinorValue::getAdditions() const
887{
888  return _additions;
889}
890
891int MinorValue::getAccumulatedMultiplications() const
892{
893  return _accumulatedMult;
894}
895
896int MinorValue::getAccumulatedAdditions() const
897{
898  return _accumulatedSum;
899}
900
901void MinorValue::print() const
902{
903  PrintS(this->toString().c_str());
904}
905
906
907void MinorValue::SetRankingStrategy (const int rankingStrategy)
908{
909  g_rankingStrategy = rankingStrategy;
910  //if (g_rankingStrategy == 6) : rand() is never used
911  //{
912  //  /* initialize the random generator with system time */
913  //  srand ( time(NULL) );
914  //}
915}
916
917int MinorValue::GetRankingStrategy()
918{
919  return g_rankingStrategy;
920}
921
922/* this is for generically accessing the rank measure regardless of
923   which strategy has been set */
924int MinorValue::getUtility () const
925{
926  switch (this->GetRankingStrategy())
927  {
928    case 1: return this->rankMeasure1();
929    case 2: return this->rankMeasure2();
930    case 3: return this->rankMeasure3();
931    case 4: return this->rankMeasure4();
932    case 5: return this->rankMeasure5();
933    default: return this->rankMeasure1();
934  }
935}
936
937/* here are some sensible caching strategies: */
938int MinorValue::rankMeasure1 () const
939{
940  /* number of actually performed multiplications */
941  return this->getMultiplications();
942}
943
944int MinorValue::rankMeasure2 () const
945{
946  /* accumulated number of performed multiplications, i.e. all including
947     nested multiplications */
948  return this->getAccumulatedMultiplications();
949}
950
951int MinorValue::rankMeasure3 () const
952{
953  /* number of performed multiplications, weighted with the ratio of
954     not yet performed retrievals over the maximal number of retrievals */
955  return this->getMultiplications()
956         * (this->getPotentialRetrievals()
957         - this->getRetrievals())
958         / this->getPotentialRetrievals();
959}
960
961int MinorValue::rankMeasure4 () const
962{
963  /* number of performed multiplications,
964     multiplied with the number of not yet performed retrievals */
965  return this->getMultiplications()
966         * (this->getPotentialRetrievals()
967         - this->getRetrievals());
968}
969
970int MinorValue::rankMeasure5 () const
971{
972  /* number of not yet performed retrievals;
973     tends to cache entries longer when they are going to be retrieved more
974     often in the future */
975  return this->getPotentialRetrievals() - this->getRetrievals();
976}
977
978int IntMinorValue::getWeight () const
979{
980  /* put measure for size of MinorValue here, i.e. number of monomials in
981     polynomial; so far, we use the accumulated number of multiplications
982     (i.e., including all nested ones) to simmulate the size of a polynomial */
983  return _accumulatedMult;
984}
985
986IntMinorValue::IntMinorValue (const int result, const int multiplications,
987                              const int additions,
988                              const int accumulatedMultiplications,
989                              const int accumulatedAdditions,
990                              const int retrievals,
991                              const int potentialRetrievals)
992{
993  _result = result;
994  _multiplications = multiplications;
995  _additions = additions;
996  _accumulatedMult = accumulatedMultiplications;
997  _accumulatedSum = accumulatedAdditions;
998  _potentialRetrievals = potentialRetrievals;
999  _retrievals = retrievals;
1000}
1001
1002IntMinorValue::IntMinorValue ()
1003{
1004  _result = -1;
1005  _multiplications = -1;
1006  _additions = -1;
1007  _accumulatedMult = -1;
1008  _accumulatedSum = -1;
1009  _potentialRetrievals = -1;
1010  _retrievals = -1;
1011}
1012
1013IntMinorValue::~IntMinorValue()
1014{
1015}
1016
1017int IntMinorValue::getResult() const
1018{
1019  return _result;
1020}
1021
1022string IntMinorValue::toString () const
1023{
1024  char h[10];
1025
1026  /* Let's see whether a cache has been used to compute this MinorValue: */
1027  bool cacheHasBeenUsed = true;
1028  if (this->getRetrievals() == -1) cacheHasBeenUsed = false;
1029
1030  sprintf(h, "%d", this->getResult());
1031  string s = h;
1032  s += " [retrievals: ";
1033  if (cacheHasBeenUsed) { sprintf(h, "%d", this->getRetrievals()); s += h; }
1034  else s += "/";
1035  s += " (of ";
1036  if (cacheHasBeenUsed)
1037  {
1038    sprintf(h, "%d", this->getPotentialRetrievals());
1039    s += h;
1040  }
1041  else s += "/";
1042  s += "), *: ";
1043  sprintf(h, "%d", this->getMultiplications()); s += h;
1044  s += " (accumulated: ";
1045  sprintf(h, "%d", this->getAccumulatedMultiplications()); s += h;
1046  s += "), +: ";
1047  sprintf(h, "%d", this->getAdditions()); s += h;
1048  s += " (accumulated: ";
1049  sprintf(h, "%d", this->getAccumulatedAdditions()); s += h;
1050  s += "), rank: ";
1051  if (cacheHasBeenUsed) { sprintf(h, "%d", this->getUtility()); s += h; }
1052  else s += "/";
1053  s += "]";
1054  return s;
1055}
1056
1057IntMinorValue::IntMinorValue (const IntMinorValue& mv)
1058{
1059  _result = mv.getResult();
1060  _retrievals = mv.getRetrievals();
1061  _potentialRetrievals = mv.getPotentialRetrievals();
1062  _multiplications = mv.getMultiplications();
1063  _additions = mv.getAdditions();
1064  _accumulatedMult = mv.getAccumulatedMultiplications();
1065  _accumulatedSum = mv.getAccumulatedAdditions();
1066}
1067
1068PolyMinorValue::PolyMinorValue (const poly result, const int multiplications,
1069                                const int additions,
1070                                const int accumulatedMultiplications,
1071                                const int accumulatedAdditions,
1072                                const int retrievals,
1073                                const int potentialRetrievals)
1074{
1075  _result = pCopy(result);
1076  _multiplications = multiplications;
1077  _additions = additions;
1078  _accumulatedMult = accumulatedMultiplications;
1079  _accumulatedSum = accumulatedAdditions;
1080  _potentialRetrievals = potentialRetrievals;
1081  _retrievals = retrievals;
1082}
1083
1084PolyMinorValue::PolyMinorValue ()
1085{
1086  _result = NULL;
1087  _multiplications = -1;
1088  _additions = -1;
1089  _accumulatedMult = -1;
1090  _accumulatedSum = -1;
1091  _potentialRetrievals = -1;
1092  _retrievals = -1;
1093}
1094
1095PolyMinorValue::~PolyMinorValue()
1096{
1097  p_Delete(&_result, currRing);
1098}
1099
1100poly PolyMinorValue::getResult() const
1101{
1102  return _result;
1103}
1104
1105int PolyMinorValue::getWeight () const
1106{
1107  /* put measure for size of PolyMinorValue here, e.g. the number of monomials
1108     in the cached polynomial */
1109  return pLength(_result); // the number of monomials in the polynomial
1110}
1111
1112string PolyMinorValue::toString () const
1113{
1114  char h[20];
1115
1116  /* Let's see whether a cache has been used to compute this MinorValue: */
1117  bool cacheHasBeenUsed = true;
1118  if (this->getRetrievals() == -1) cacheHasBeenUsed = false;
1119
1120  string s = pString(_result);
1121  s += " [retrievals: ";
1122  if (cacheHasBeenUsed) { sprintf(h, "%d", this->getRetrievals()); s += h; }
1123  else s += "/";
1124  s += " (of ";
1125  if (cacheHasBeenUsed)
1126  {
1127    sprintf(h, "%d", this->getPotentialRetrievals());
1128    s += h;
1129  }
1130  else s += "/";
1131  s += "), *: ";
1132  sprintf(h, "%d", this->getMultiplications()); s += h;
1133  s += " (accumulated: ";
1134  sprintf(h, "%d", this->getAccumulatedMultiplications()); s += h;
1135  s += "), +: ";
1136  sprintf(h, "%d", this->getAdditions()); s += h;
1137  s += " (accumulated: ";
1138  sprintf(h, "%d", this->getAccumulatedAdditions()); s += h;
1139  s += "), rank: ";
1140  if (cacheHasBeenUsed) { sprintf(h, "%d", this->getUtility()); s += h; }
1141  else s += "/";
1142  s += "]";
1143  return s;
1144}
1145
1146PolyMinorValue::PolyMinorValue (const PolyMinorValue& mv)
1147{
1148  _result = pCopy(mv.getResult());
1149  _retrievals = mv.getRetrievals();
1150  _potentialRetrievals = mv.getPotentialRetrievals();
1151  _multiplications = mv.getMultiplications();
1152  _additions = mv.getAdditions();
1153  _accumulatedMult = mv.getAccumulatedMultiplications();
1154  _accumulatedSum = mv.getAccumulatedAdditions();
1155}
1156
1157void PolyMinorValue::operator= (const PolyMinorValue& mv)
1158{
1159  if (_result != mv.getResult()) pDelete(&_result);
1160  _result = pCopy(mv.getResult());
1161  _retrievals = mv.getRetrievals();
1162  _potentialRetrievals = mv.getPotentialRetrievals();
1163  _multiplications = mv.getMultiplications();
1164  _additions = mv.getAdditions();
1165  _accumulatedMult = mv.getAccumulatedMultiplications();
1166  _accumulatedSum = mv.getAccumulatedAdditions();
1167}
Note: See TracBrowser for help on using the repository browser.