source: git/Singular/Minor.cc @ dbee17c

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