source: git/Singular/Minor.cc @ 8c1285

spielwiese
Last change on this file since 8c1285 was a9c298, checked in by Hans Schoenemann <hannes@…>, 10 years ago
format stuff
  • Property mode set to 100644
File size: 36.8 KB
Line 
1#ifdef HAVE_CONFIG_H
2#include "singularconfig.h"
3#endif /* HAVE_CONFIG_H */
4#include <kernel/mod2.h>
5
6#include "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
117void 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
312int MinorKey::getSetBits(const int a) const
313{
314  int b = 0;
315  if (a == 1)
316  { /* rows */
317    for (int i = 0; i < _numberOfRowBlocks; i++)
318    {
319      unsigned int m = _rowKey[i];
320      unsigned int k = 1;
321      for (int j = 0; j < 32; j++)
322      {
323        /* k = 2^j */
324        if (m & k) b++;
325        k = k << 1;
326      }
327    }
328  }
329  else
330  { /* columns */
331    for (int i = 0; i < _numberOfColumnBlocks; i++)
332    {
333      unsigned int m = _columnKey[i];
334      unsigned int k = 1;
335      for (int j = 0; j < 32; j++)
336      {
337        /* k = 2^j */
338        if (m & k) b++;
339        k = k << 1;
340      }
341    }
342  }
343  return b;
344}
345
346MinorKey MinorKey::getSubMinorKey (const int absoluteEraseRowIndex,
347                                   const int absoluteEraseColumnIndex) const
348{
349  int rowBlock = absoluteEraseRowIndex / 32;
350  int exponent = absoluteEraseRowIndex % 32;
351  unsigned int newRowBits = getRowKey(rowBlock) - (1 << exponent);
352  int highestRowBlock = getNumberOfRowBlocks() - 1;
353  /* highestRowBlock will finally contain the highest block index with
354     non-zero bit pattern */
355  if ((newRowBits == 0) && (rowBlock == highestRowBlock))
356  {
357    /* we have thus nullified the highest block;
358       we can now forget about the highest block... */
359    highestRowBlock -= 1;
360    while (getRowKey(highestRowBlock) == 0) /* ...and maybe even some more
361                                               zero-blocks */
362      highestRowBlock -= 1;
363  }
364  /* highestRowBlock now contains the highest row block index with non-zero
365     bit pattern */
366
367  int columnBlock = absoluteEraseColumnIndex / 32;
368  exponent = absoluteEraseColumnIndex % 32;
369  unsigned int newColumnBits = getColumnKey(columnBlock) - (1 << exponent);
370  int highestColumnBlock = getNumberOfColumnBlocks() - 1;
371  /* highestColumnBlock will finally contain the highest block index with
372     non-zero bit pattern */
373  if ((newColumnBits == 0) && (columnBlock == highestColumnBlock))
374  {
375    /* we have thus nullified the highest block;
376       we can now forget about the highest block... */
377    highestColumnBlock -= 1;
378    while (getColumnKey(highestColumnBlock) == 0) /* ...and maybe even some
379                                                     more zero-blocks */
380      highestColumnBlock -= 1;
381  }
382  /* highestColumnBlock now contains the highest column block index with
383     non-zero bit pattern */
384
385  MinorKey result(highestRowBlock + 1, _rowKey, highestColumnBlock + 1,
386                  _columnKey);
387  /* This is just a copy with maybe some leading bit blocks omitted. We still
388     need to re-define the row block at index 'rowBlock' and the column block
389     at index 'columnBlock': */
390  if ((newRowBits != 0) || (rowBlock < getNumberOfRowBlocks() - 1))
391    result.setRowKey(rowBlock, newRowBits);
392  if ((newColumnBits != 0) || (columnBlock < getNumberOfColumnBlocks() - 1))
393    result.setColumnKey(columnBlock, newColumnBits);
394
395  /* let's check that the number of selected rows and columns are equal;
396     (this check is only performed in the debug version) */
397  assume(result.getSetBits(1) == result.getSetBits(2));
398
399  return result;
400}
401
402void MinorKey::setRowKey (const int blockIndex, const unsigned int rowKey)
403{
404    _rowKey[blockIndex] = rowKey;
405}
406
407void MinorKey::setColumnKey (const int blockIndex,
408                             const unsigned int columnKey)
409{
410    _columnKey[blockIndex] = columnKey;
411}
412
413int MinorKey::compare (const MinorKey& that) const
414{
415  /* compare by rowKeys first; in case of equality, use columnKeys */
416  if (this->getNumberOfRowBlocks() < that.getNumberOfRowBlocks())
417    return -1;
418  if (this->getNumberOfRowBlocks() > that.getNumberOfRowBlocks())
419    return 1;
420  /* Here, numbers of rows are equal. */
421  for (int r = this->getNumberOfRowBlocks() - 1; r >= 0; r--)
422  {
423    if (this->getRowKey(r) < that.getRowKey(r)) return -1;
424    if (this->getRowKey(r) > that.getRowKey(r)) return 1;
425  }
426  /* Here, this and that encode ecaxtly the same sets of rows.
427     Now, we take a look at the columns. */
428  if (this->getNumberOfColumnBlocks() < that.getNumberOfColumnBlocks())
429    return -1;
430  if (this->getNumberOfColumnBlocks() > that.getNumberOfColumnBlocks())
431    return 1;
432  /* Here, numbers of columns are equal. */
433  for (int c = this->getNumberOfColumnBlocks() - 1; c >= 0; c--)
434  {
435    if (this->getColumnKey(c) < that.getColumnKey(c)) return -1;
436    if (this->getColumnKey(c) > that.getColumnKey(c)) return 1;
437  }
438  /* Here, this and that encode exactly the same sets of rows and columns. */
439  return 0;
440}
441
442/* just to make the compiler happy;
443   this method should never be called */
444bool MinorKey::operator==(const MinorKey& mk) const
445{
446  assume(false);
447  return this->compare(mk) == 0;
448}
449
450/* just to make the compiler happy;
451   this method should never be called */
452bool MinorKey::operator<(const MinorKey& mk) const
453{
454  assume(false);
455  return this->compare(mk) == -1;
456}
457
458void MinorKey::selectFirstRows (const int k, const MinorKey& mk)
459{
460  int hitBits = 0;      /* the number of bits we have hit; in the end, this
461                           has to be equal to k, the dimension of the minor */
462  int blockIndex = -1;  /* the index of the current int in mk */
463  unsigned int highestInt = 0;  /* the new highest block of this MinorKey */
464  /* We determine which ints of mk we can copy. Their indices will be
465     0, 1, ..., blockIndex - 1. And highestInt is going to capture the highest
466     int (which may be only a portion of the corresponding int in mk.
467     We loop until hitBits = k: */
468  while (hitBits < k)
469  {
470    blockIndex++;
471    highestInt = 0;
472    unsigned int currentInt = mk.getRowKey(blockIndex);
473    unsigned int shiftedBit = 1;
474    int exponent = 0;
475    /* invariant in the loop: shiftedBit = 2^exponent */
476    while (exponent < 32 && hitBits < k)
477    {
478      if (shiftedBit & currentInt)
479      {
480        highestInt += shiftedBit;
481        hitBits++;
482      }
483      shiftedBit = shiftedBit << 1;
484      exponent++;
485    }
486  }
487  /* free old memory */
488  delete [] _rowKey; _rowKey = 0;
489  _numberOfRowBlocks = blockIndex + 1;
490  /* allocate memory for new entries in _rowKey; */
491  _rowKey = new unsigned int[_numberOfRowBlocks];
492  /* copying values from mk to this MinorKey */
493  for (int r = 0; r < blockIndex; r++)
494    _rowKey[r] = mk.getRowKey(r);
495  _rowKey[blockIndex] = highestInt;
496}
497
498void MinorKey::selectFirstColumns (const int k, const MinorKey& mk)
499{
500  int hitBits = 0;      /* the number of bits we have hit; in the end, this
501                           has to be equal to k, the dimension of the minor */
502  int blockIndex = -1;  /* the index of the current int in mk */
503  unsigned int highestInt = 0;  /* the new highest block of this MinorKey */
504  /* We determine which ints of mk we can copy. Their indices will be
505     0, 1, ..., blockIndex - 1. And highestInt is going to capture the highest
506     int (which may be only a portion of the corresponding int in mk.
507     We loop until hitBits = k: */
508  while (hitBits < k)
509  {
510    blockIndex++;
511    highestInt = 0;
512    unsigned int currentInt = mk.getColumnKey(blockIndex);
513    unsigned int shiftedBit = 1;
514    int exponent = 0;
515    /* invariant in the loop: shiftedBit = 2^exponent */
516    while (exponent < 32 && hitBits < k)
517    {
518      if (shiftedBit & currentInt)
519      {
520        highestInt += shiftedBit;
521        hitBits++;
522      }
523      shiftedBit = shiftedBit << 1;
524      exponent++;
525    }
526  }
527  /* free old memory */
528  delete [] _columnKey; _columnKey = 0;
529  _numberOfColumnBlocks = blockIndex + 1;
530  /* allocate memory for new entries in _columnKey; */
531  _columnKey = new unsigned int[_numberOfColumnBlocks];
532  /*  copying values from mk to this MinorKey */
533  for (int c = 0; c < blockIndex; c++)
534    _columnKey[c] = mk.getColumnKey(c);
535  _columnKey[blockIndex] = highestInt;
536}
537
538bool MinorKey::selectNextRows (const int k, const MinorKey& mk)
539{
540  /* We need to compute the set of k rows which must all be contained in mk.
541     AND: This set must be the least possible of this kind which is larger
542          than the currently encoded set of rows. (Here, '<' is w.r.t. to the
543          natural ordering on multi-indices.
544     Example: mk encodes the rows according to the bit pattern 11010111,
545              k = 3, this MinorKey encodes 10010100. Then, the method must
546              shift the set of rows in this MinorKey to 11000001 (, and
547              return true). */
548
549  /* The next two variables will finally name a row which is
550     (1) currently not yet among the rows in this MinorKey, but
551     (2) among the rows in mk, and
552     (3) which is "higher" than the lowest row in this MinorKey, and
553     (4) which is the lowest possible choice such that (1) - (3) hold.
554     If we should not be able to find such a row, then there is no next
555     subset of rows. In this case, the method will return false; otherwise
556     always true. */
557  int newBitBlockIndex = 0;        /* the block index of the bit */
558  unsigned int newBitToBeSet = 0;  /* the bit as 2^e, where 0 <= e <= 31 */
559
560  /* number of ints (representing rows) in this MinorKey: */
561  int blockCount = this->getNumberOfRowBlocks();
562  /* for iterating along the blocks of mk: */
563  int mkBlockIndex = mk.getNumberOfRowBlocks();
564
565  int hitBits = 0;    /* the number of bits we have hit */
566  int bitCounter = 0; /* for storing the number of bits hit before a
567                         specific moment; see below */
568  while (hitBits < k)
569  {
570    mkBlockIndex--;
571    unsigned int currentInt = mk.getRowKey(mkBlockIndex);
572    unsigned int shiftedBit = 1 << 31; /* initially, this equals 2^31, i.e.
573                                          the highest bit */
574    while (hitBits < k && shiftedBit > 0)
575    {
576      if ((blockCount - 1 >= mkBlockIndex) &&
577        (shiftedBit & this->getRowKey(mkBlockIndex))) hitBits++;
578      else if (shiftedBit & currentInt)
579      {
580        newBitToBeSet = shiftedBit;
581        newBitBlockIndex = mkBlockIndex;
582        bitCounter = hitBits; /* So, whenever we set newBitToBeSet, we want
583                                 to remember the momentary number of hit
584                                 bits. This will later be needed; see below. */
585      }
586      shiftedBit = shiftedBit >> 1;
587    }
588  }
589  if (newBitToBeSet == 0)
590  {
591    return false;
592  }
593  else
594  {
595    /* Note that the following must hold when reaching this line of code:
596       (1) The row with bit newBitToBeSet in this->getRowKey(newBitBlockIndex)
597           is currently not among the rows in this MinorKey, but
598       (2) it is among the rows in mk, and
599       (3) it is higher than the lowest row in this MinorKey, and
600       (4) it is the lowest possible choice such that (1) - (3) hold.
601       In the above example, we would reach this line with
602       newBitToBeSet == 2^6 and bitCounter == 1 (resulting from the bit 2^7).
603       */
604
605    if (blockCount - 1 < newBitBlockIndex)
606    { /* In this case, _rowKey is too small. */
607      /* free old memory */
608      delete [] _rowKey; _rowKey = 0;
609      _numberOfRowBlocks = newBitBlockIndex + 1;
610      /* allocate memory for new entries in _rowKey; */
611      _rowKey = new unsigned int[_numberOfRowBlocks];
612      /* initializing entries to zero */
613        for (int r = 0; r < _numberOfRowBlocks; r++) _rowKey[r] = 0;
614    }
615    else
616    {
617      /* We need to delete all bits in _rowKey[newBitBlockIndex] that are
618         below newBitToBeSet: */
619      unsigned int anInt = this->getRowKey(newBitBlockIndex);
620      unsigned int deleteBit = newBitToBeSet >> 1; // in example: = 2^5
621      while (deleteBit > 0)
622      {
623        if (anInt & deleteBit) anInt -= deleteBit;
624        deleteBit = deleteBit >> 1;
625      };
626      _rowKey[newBitBlockIndex] = anInt;
627      /* ...and we delete all entries in _rowKey[i] for
628         0 <= i < newBitBlockIndex */
629      for (int i = 0; i < newBitBlockIndex; i++)
630        _rowKey[i] = 0;
631    }
632
633    /* We have now deleted all bits from _rowKey[...] below the bit
634       2^newBitToBeSet.
635       In the example we shall have at this point: _rowKey[...] = 10000000.
636       Now let's set the new bit: */
637    _rowKey[newBitBlockIndex] += newBitToBeSet;
638    /* in the example: _rowKey[newBitBlockIndex] = 11000000 */
639    bitCounter++; /* This is now the number of correct bits in _rowKey[...];
640                     i.e. in the example this will be equal to 2. */
641
642    /* Now we only need to fill _rowKey[...] with the lowest possible bits
643       until it consists of exactly k bits. (We know that we need to set
644       exactly (k - bitCounter) additional bits.) */
645    mkBlockIndex = -1;
646    while (bitCounter < k)
647    {
648      mkBlockIndex++;
649      unsigned int currentInt = mk.getRowKey(mkBlockIndex);
650      unsigned int shiftedBit = 1;
651      int exponent = 0;
652      /* invariant: shiftedBit = 2^exponent */
653      while (bitCounter < k && exponent < 32)
654      {
655        if (shiftedBit & currentInt)
656        {
657          _rowKey[mkBlockIndex] += shiftedBit;
658          bitCounter++;
659        };
660        shiftedBit = shiftedBit << 1;
661        exponent++;
662      }
663    };
664    /* in the example, we shall obtain _rowKey[...] = 11000001 */
665    return true;
666  }
667}
668
669bool MinorKey::selectNextColumns (const int k, const MinorKey& mk)
670{
671  /* We need to compute the set of k columns which must all be contained in mk.
672     AND: This set must be the least possible of this kind which is larger
673          than the currently encoded set of columns. (Here, '<' is w.r.t. to
674          the natural ordering on multi-indices.
675     Example: mk encodes the columns according to the bit pattern 11010111,
676              k = 3, this MinorKey encodes 10010100. Then, the method must
677              shift the set of columns in this MinorKey to 11000001 (, and
678              return true). */
679
680  /* The next two variables will finally name a column which is
681     (1) currently not yet among the columns in this MinorKey, but
682     (2) among the columns in mk, and
683     (3) which is "higher" than the lowest column in this MinorKey, and
684     (4) which is the lowest possible choice such that (1) - (3) hold.
685     If we should not be able to find such a column, then there is no next
686     subset of columns. In this case, the method will return false; otherwise
687     always true. */
688  int newBitBlockIndex = 0;        /* the block index of the bit */
689  unsigned int newBitToBeSet = 0;  /* the bit as 2^e, where 0 <= e <= 31 */
690
691   /* number of ints (representing columns) in this MinorKey: */
692  int blockCount = this->getNumberOfColumnBlocks();
693  /* for iterating along the blocks of mk: */
694  int mkBlockIndex = mk.getNumberOfColumnBlocks();
695
696  int hitBits = 0;    /* the number of bits we have hit */
697  int bitCounter = 0; /* for storing the number of bits hit before a specific
698                         moment; see below */
699  while (hitBits < k)
700  {
701    mkBlockIndex--;
702    unsigned int currentInt = mk.getColumnKey(mkBlockIndex);
703    unsigned int shiftedBit = 1 << 31; /* initially, this equals 2^31, i.e.
704                                          the highest bit */
705    while (hitBits < k && shiftedBit > 0)
706    {
707      if ((blockCount - 1 >= mkBlockIndex) &&
708        (shiftedBit & this->getColumnKey(mkBlockIndex))) hitBits++;
709      else if (shiftedBit & currentInt)
710      {
711        newBitToBeSet = shiftedBit;
712        newBitBlockIndex = mkBlockIndex;
713        bitCounter = hitBits; /* So, whenever we set newBitToBeSet, we want to
714                                 remember the momentary number of hit bits.
715                                 This will later be needed; see below. */
716      }
717      shiftedBit = shiftedBit >> 1;
718    }
719  }
720  if (newBitToBeSet == 0)
721  {
722    return false;
723  }
724  else
725  {
726    /* Note that the following must hold when reaching this line of code:
727       (1) The column with bit newBitToBeSet in
728           this->getColumnKey(newBitBlockIndex) is currently not among the
729           columns in this MinorKey, but
730       (2) it is among the columns in mk, and
731       (3) it is higher than the lowest columns in this MinorKey, and
732       (4) it is the lowest possible choice such that (1) - (3) hold.
733       In the above example, we would reach this line with
734       newBitToBeSet == 2^6 and bitCounter == 1 (resulting from the bit 2^7).
735       */
736
737    if (blockCount - 1 < newBitBlockIndex)
738    { /* In this case, _columnKey is too small. */
739        /* free old memory */
740        delete [] _columnKey; _columnKey = 0;
741        _numberOfColumnBlocks = newBitBlockIndex + 1;
742        /* allocate memory for new entries in _columnKey; */
743        _columnKey = new unsigned int[_numberOfColumnBlocks];
744        /* initializing entries to zero */
745        for (int c = 0; c < _numberOfColumnBlocks; c++) _columnKey[c] = 0;
746    }
747    else
748    {
749      /* We need to delete all bits in _columnKey[newBitBlockIndex] that are
750         below newBitToBeSet: */
751      unsigned int anInt = this->getColumnKey(newBitBlockIndex);
752      unsigned int deleteBit = newBitToBeSet >> 1; /* in example: = 2^5 */
753      while (deleteBit > 0)
754      {
755        if (anInt & deleteBit) anInt -= deleteBit;
756        deleteBit = deleteBit >> 1;
757      };
758      _columnKey[newBitBlockIndex] = anInt;
759      /* ...and we delete all entries in _columnKey[i] fo
760         0 <= i < newBitBlockIndex */
761      for (int i = 0; i < newBitBlockIndex; i++)
762        _columnKey[i] = 0;
763    }
764    /* We have now deleted all bits from _columnKey[...] below the bit
765       2^newBitToBeSet. In the example we shall have at this point:
766       _columnKey[...] = 10000000. Now let's set the new bit: */
767    _columnKey[newBitBlockIndex] += newBitToBeSet;
768    /* in the example: _columnKey[newBitBlockIndex] = 11000000 */
769    bitCounter++; /* This is now the number of correct bits in
770                     _columnKey[...]; i.e. in the example this will be equal
771                     to 2. */
772
773    /* Now we only need to fill _columnKey[...] with the lowest possible bits
774       until it consists of exactly k bits. (We know that we need to set
775       exactly (k - bitCounter) additional bits.) */
776    mkBlockIndex = -1;
777    while (bitCounter < k)
778    {
779      mkBlockIndex++;
780      unsigned int currentInt = mk.getColumnKey(mkBlockIndex);
781      unsigned int shiftedBit = 1;
782      int exponent = 0;
783      /* invariant: shiftedBit = 2^exponent */
784      while (bitCounter < k && exponent < 32)
785      {
786        if (shiftedBit & currentInt)
787        {
788          _columnKey[mkBlockIndex] += shiftedBit;
789          bitCounter++;
790        };
791        shiftedBit = shiftedBit << 1;
792        exponent++;
793      }
794    };
795    /* in the example, we shall obtain _columnKey[...] = 11000001 */
796    return true;
797  }
798}
799
800string MinorKey::toString() const
801{
802  string t;
803  string s = "(";
804  unsigned int z = 0;
805  for (int r = this->getNumberOfRowBlocks() - 1; r >= 0; r--)
806  {
807    t = "";
808    z = this->getRowKey(r);
809    while (z != 0)
810    {
811      if ((z % 2) != 0) t = "1" + t; else t = "0" + t;
812      z = z / 2;
813    }
814    if (r < this->getNumberOfRowBlocks() - 1)
815      t = string(32 - t.length(), '0') + t;
816    s += t;
817  }
818  s += ", ";
819  for (int c = this->getNumberOfColumnBlocks() - 1; c >= 0; c--)
820  {
821    t = "";
822    z = this->getColumnKey(c);
823    while (z != 0)
824    {
825      if ((z % 2) != 0) t = "1" + t; else t = "0" + t;
826      z = z / 2;
827    }
828    if (c < this->getNumberOfColumnBlocks() - 1)
829      t = string(32 - t.length(), '0') + t;
830    s += t;
831  }
832  s += ")";
833  return s;
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)
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.