source: git/Singular/Minor.cc @ d7ad81

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