source: git/Singular/MinorInterface.cc @ bee06d

spielwiese
Last change on this file since bee06d was d2ea299, checked in by Frank Seelisch <seelisch@…>, 14 years ago
new LIB versions and debugging in code for matrix minors git-svn-id: file:///usr/local/Singular/svn/trunk@13339 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 21.1 KB
Line 
1#include <kernel/mod2.h>
2#include <kernel/structs.h>
3#include <kernel/polys.h>
4#include <kernel/ideals.h>
5#include <kernel/kstd1.h>
6#include <kernel/matpol.h>
7#include <MinorInterface.h>
8#include <MinorProcessor.h>
9
10bool currRingIsOverIntegralDomain ()
11{
12  if (rField_is_Ring_PtoM()) return false;
13  if (rField_is_Ring_2toM()) return false;
14  if (rField_is_Ring_ModN()) return false;
15  return true;
16}
17
18bool currRingIsOverField ()
19{
20  if (rField_is_Ring_PtoM()) return false;
21  if (rField_is_Ring_2toM()) return false;
22  if (rField_is_Ring_ModN()) return false;
23  if (rField_is_Ring_Z())    return false;
24  return true;
25}
26
27/* returns true iff the given polyArray has only number entries;
28   if so, the int's corresponding to these numbers will be written
29   into intArray[0..(length-1)];
30   the method assumes that both polyArray and intArray have valid
31   entries for the indices 0..(length-1);
32   after the call, zeroCounter contains the number of zero entries
33   in the matrix */
34bool arrayIsNumberArray (const poly* polyArray, const ideal iSB,
35                         const int length, int* intArray,
36                         poly* nfPolyArray, int& zeroCounter)
37{
38  int n = 0; if (currRing != 0) n = currRing->N;
39  int characteristic = 0; if (currRing != 0) characteristic = rChar(currRing);
40  zeroCounter = 0;
41  bool result = true;
42
43  for (int i = 0; i < length; i++)
44  {
45    nfPolyArray[i] = pCopy(polyArray[i]);
46    if (iSB != 0) nfPolyArray[i] = kNF(iSB, currRing->qideal, nfPolyArray[i]);
47    if (nfPolyArray[i] == NULL)
48    {
49      intArray[i] = 0;
50      zeroCounter++;
51    }
52    else
53    {
54      bool isConstant = true;
55      for (int j = 1; j <= n; j++)
56        if (pGetExp(nfPolyArray[i], j) > 0)
57          isConstant = false;
58      if (!isConstant) result = false;
59      else
60      {
61        intArray[i] = n_Int(pGetCoeff(nfPolyArray[i]), currRing);
62        if (characteristic != 0) intArray[i] = intArray[i] % characteristic;
63        if (intArray[i] == 0) zeroCounter++;
64      }
65    }
66  }
67  return result;
68}
69
70/* special implementation for the case that the matrix has only number entries;
71   if i is not the zero pointer, then it is assumed to contain a std basis, and
72   the number entries of the matrix are then assumed to be reduced w.r.t. i and
73   modulo the characteristic of the gound field/ring;
74   this method should also work when currRing == null, i.e. when no ring has
75   been declared */
76ideal getMinorIdeal_Int (const int* intMatrix, const int rowCount,
77                         const int columnCount, const int minorSize,
78                         const int k, const char* algorithm,
79                         const ideal i, const bool allDifferent)
80{
81  /* setting up a MinorProcessor for matrices with integer entries: */
82  IntMinorProcessor mp;
83  mp.defineMatrix(rowCount, columnCount, intMatrix);
84  int myRowIndices[rowCount];
85  for (int j = 0; j < rowCount; j++) myRowIndices[j] = j;
86  int myColumnIndices[columnCount];
87  for (int j = 0; j < columnCount; j++) myColumnIndices[j] = j;
88  mp.defineSubMatrix(rowCount, myRowIndices, columnCount, myColumnIndices);
89  mp.setMinorSize(minorSize);
90
91  /* containers for all upcoming results: */
92  IntMinorValue theMinor;
93  int value = 0;
94  int collectedMinors = 0;
95  int characteristic = 0; if (currRing != 0) characteristic = rChar(currRing);
96 
97  /* the ideal to be returned: */
98  ideal iii = idInit(1, 0);
99
100  bool zeroOk = ((k < 0) ? true : false); /* for k = 0, all minors are requested,
101                                             omitting zero minors */
102  bool duplicatesOk = (allDifferent ? false : true);
103  int kk = ((k < 0) ? -k : k); /* absolute value of k */
104
105  /* looping over all minors: */
106  while (mp.hasNextMinor() && ((kk == 0) || (collectedMinors < kk)))
107  {
108    /* retrieving the next minor: */
109    theMinor = mp.getNextMinor(characteristic, i, algorithm);
110    poly f = NULL;
111    if (theMinor.getResult() != 0) f = pISet(theMinor.getResult());
112    if (idInsertPolyWithTests(iii, collectedMinors, f, zeroOk, duplicatesOk))
113      collectedMinors++;
114  }
115
116  /* before we return the result, let's omit zero generators
117     in iii which come after the computed minors */
118  ideal jjj;
119  if (collectedMinors == 0) jjj = idInit(1, 0);
120  else                      jjj = idCopyFirstK(iii, collectedMinors);
121  idDelete(&iii);
122  return jjj;
123}                 
124
125/* special implementation for the case that the matrix has non-number,
126   i.e., actual polynomial entries;
127   if i is not the zero pointer than it is assumed to be a std basis (ideal),
128   and the poly matrix is assumed to be already reduced w.r.t. i */
129ideal getMinorIdeal_Poly (const poly* polyMatrix, const int rowCount,
130                          const int columnCount, const int minorSize,
131                          const int k, const char* algorithm,
132                          const ideal i, const bool allDifferent)
133{       
134  /* setting up a MinorProcessor for matrices with polynomial entries: */
135  PolyMinorProcessor mp;
136  mp.defineMatrix(rowCount, columnCount, polyMatrix);
137  int myRowIndices[rowCount];
138  for (int j = 0; j < rowCount; j++) myRowIndices[j] = j;
139  int myColumnIndices[columnCount];
140  for (int j = 0; j < columnCount; j++) myColumnIndices[j] = j;
141  mp.defineSubMatrix(rowCount, myRowIndices, columnCount, myColumnIndices);
142  mp.setMinorSize(minorSize);
143
144  /* containers for all upcoming results: */
145  PolyMinorValue theMinor;
146  poly f = NULL;
147  int collectedMinors = 0;
148
149  /* the ideal to be returned: */
150  ideal iii = idInit(1, 0);
151
152  bool zeroOk = ((k < 0) ? true : false); /* for k = 0, all minors are
153                                             requested, omitting zero minors */
154  bool duplicatesOk = (allDifferent ? false : true);
155  int kk = ((k < 0) ? -k : k); /* absolute value of k */
156#ifdef COUNT_AND_PRINT_OPERATIONS
157  printCounters ("starting", true);
158  int qqq = 0;
159#endif
160  /* looping over all minors: */
161  while (mp.hasNextMinor() && ((kk == 0) || (collectedMinors < kk)))
162  {
163    /* retrieving the next minor: */
164    theMinor = mp.getNextMinor(algorithm, i);
165#if (defined COUNT_AND_PRINT_OPERATIONS) && (COUNT_AND_PRINT_OPERATIONS > 1)
166    qqq++;
167    printf("after %d", qqq);
168    printCounters ("-th minor", false);
169#endif
170    f = theMinor.getResult();
171    if (idInsertPolyWithTests(iii, collectedMinors, pCopy(f),
172                              zeroOk, duplicatesOk))
173      collectedMinors++;
174  }
175#ifdef COUNT_AND_PRINT_OPERATIONS
176  printCounters ("ending", true);
177#endif
178
179  /* before we return the result, let's omit zero generators
180     in iii which come after the computed minors */
181  ideal jjj;
182  if (collectedMinors == 0) jjj = idInit(1, 0);
183  else                      jjj = idCopyFirstK(iii, collectedMinors);
184  idDelete(&iii);
185  return jjj;
186}
187
188ideal getMinorIdeal_toBeDone (const matrix mat, const int minorSize,
189                              const int k, const char* algorithm,
190                              const ideal i, const bool allDifferent)
191{
192  int rowCount = mat->nrows;
193  int columnCount = mat->ncols;
194  poly* myPolyMatrix = (poly*)(mat->m);
195  ideal iii; /* the ideal to be filled and returned */
196  int zz = 0;
197
198  /* divert to special implementations for pure number matrices and actual
199     polynomial matrices: */
200  int*  myIntMatrix  = new int [rowCount * columnCount];
201  poly* nfPolyMatrix = new poly[rowCount * columnCount];
202  if (arrayIsNumberArray(myPolyMatrix, i, rowCount * columnCount,
203                         myIntMatrix, nfPolyMatrix, zz))
204    iii = getMinorIdeal_Int(myIntMatrix, rowCount, columnCount, minorSize, k,
205                            algorithm, i, allDifferent);
206  else
207  {
208    if ((k == 0) && (strcmp(algorithm, "Bareiss") == 0)
209        && (!rField_is_Ring_Z()) && (!allDifferent))
210    {
211      /* In this case, we call an optimized procedure, dating back to
212         Wilfried Pohl. It may be used whenever
213         - all minors are requested,
214         - requested minors need not be mutually distinct, and
215         - coefficients come from a field (i.e., Z is also not allowed
216           for this implementation). */
217      iii = (i == 0 ? idMinors(mat, minorSize) : idMinors(mat, minorSize, i));
218    }
219    else
220    {
221      iii = getMinorIdeal_Poly(nfPolyMatrix, rowCount, columnCount, minorSize,
222                               k, algorithm, i, allDifferent);
223    }
224  }
225
226  /* clean up */
227  delete [] myIntMatrix;
228  for (int j = 0; j < rowCount * columnCount; j++) pDelete(&nfPolyMatrix[j]);
229  delete [] nfPolyMatrix;
230
231  return iii;
232}
233
234/* When called with algorithm == "Bareiss", the coefficients are assumed
235   to come from a field or from a ring which does not have zero-divisors
236   (other than 0), i.e. from an integral domain.
237   E.g. Bareiss may be used over fields or over Z but not over
238        Z/6 (which has non-zero zero divisors, namely 2 and 3). */
239ideal getMinorIdeal (const matrix mat, const int minorSize, const int k,
240                     const char* algorithm, const ideal iSB,
241                     const bool allDifferent)
242{
243  /* Note that this method should be replaced by getMinorIdeal_toBeDone,
244     to enable faster computations in the case of matrices which contain
245     only numbers. But so far, this method is not yet usable as it replaces
246     the numbers by ints which may result in overflows during computations
247     of minors. */
248  int rowCount = mat->nrows;
249  int columnCount = mat->ncols;
250  poly* myPolyMatrix = (poly*)(mat->m);
251  int length = rowCount * columnCount;
252  poly* nfPolyMatrix = new poly[length];
253  ideal iii; /* the ideal to be filled and returned */
254
255  /* copy all polynomials and reduce them w.r.t. iSB
256     (if iSB is present, i.e., not the NULL pointer) */
257  for (int i = 0; i < length; i++)
258  {
259    nfPolyMatrix[i] = pCopy(myPolyMatrix[i]);
260    if (iSB != 0) nfPolyMatrix[i] = kNF(iSB, currRing->qideal,
261                                        nfPolyMatrix[i]);
262  }
263
264  if ((k == 0) && (strcmp(algorithm, "Bareiss") == 0)
265      && (!rField_is_Ring_Z()) && (!allDifferent))
266  {
267    /* In this case, we call an optimized procedure, dating back to
268       Wilfried Pohl. It may be used whenever
269       - all minors are requested,
270       - requested minors need not be mutually distinct, and
271       - coefficients come from a field (i.e., the ring Z is not
272         allowed for this implementation). */
273    iii = (iSB == 0 ? idMinors(mat, minorSize) : idMinors(mat, minorSize,
274                                                          iSB));
275  }
276  else
277  {
278    iii = getMinorIdeal_Poly(nfPolyMatrix, rowCount, columnCount, minorSize,
279                             k, algorithm, iSB, allDifferent);
280  }
281
282  /* clean up */
283  for (int j = 0; j < length; j++) pDelete(&nfPolyMatrix[j]);
284  delete [] nfPolyMatrix;
285
286  return iii;
287}
288
289/* special implementation for the case that the matrix has only number entries;
290   if i is not the zero pointer, then it is assumed to contain a std basis, and
291   the number entries of the matrix are then assumed to be reduced w.r.t. i and
292   modulo the characteristic of the gound field/ring;
293   this method should also work when currRing == null, i.e. when no ring has
294   been declared */
295ideal getMinorIdealCache_Int(const int* intMatrix, const int rowCount,
296                             const int columnCount, const int minorSize,
297                             const int k, const ideal i,
298                             const int cacheStrategy, const int cacheN,
299                             const int cacheW, const bool allDifferent)
300{
301  /* setting up a MinorProcessor for matrices with integer entries: */
302  IntMinorProcessor mp;
303  mp.defineMatrix(rowCount, columnCount, intMatrix);
304  int myRowIndices[rowCount];
305  for (int j = 0; j < rowCount; j++) myRowIndices[j] = j;
306  int myColumnIndices[columnCount];
307  for (int j = 0; j < columnCount; j++) myColumnIndices[j] = j;
308  mp.defineSubMatrix(rowCount, myRowIndices, columnCount, myColumnIndices);
309  mp.setMinorSize(minorSize);
310  MinorValue::SetRankingStrategy(cacheStrategy);
311  Cache<MinorKey, IntMinorValue> cch(cacheN, cacheW);
312
313  /* containers for all upcoming results: */
314  IntMinorValue theMinor;
315  int value = 0;
316  int collectedMinors = 0;
317  int characteristic = 0; if (currRing != 0) characteristic = rChar(currRing);
318
319  /* the ideal to be returned: */
320  ideal iii = idInit(1, 0);
321
322  bool zeroOk = ((k < 0) ? true : false); /* for k = 0, all minors are
323                                             requested, omitting zero minors */
324  bool duplicatesOk = (allDifferent ? false : true);
325  int kk = ((k < 0) ? -k : k); /* absolute value of k */
326
327  /* looping over all minors: */
328  while (mp.hasNextMinor() && ((kk == 0) || (collectedMinors < kk)))
329  {
330    /* retrieving the next minor: */
331    theMinor = mp.getNextMinor(cch, characteristic, i);
332    poly f = NULL;
333    if (theMinor.getResult() != 0) f = pISet(theMinor.getResult());
334    if (idInsertPolyWithTests(iii, collectedMinors, f, zeroOk, duplicatesOk))
335      collectedMinors++;
336  }
337
338  /* before we return the result, let's omit zero generators
339     in iii which come after the computed minors */
340  ideal jjj;
341  if (collectedMinors == 0) jjj = idInit(1, 0);
342  else                      jjj = idCopyFirstK(iii, collectedMinors);
343  idDelete(&iii);
344  return jjj;
345}
346
347/* special implementation for the case that the matrix has non-number,
348   i.e. real poly entries;
349   if i is not the zero pointer, then it is assumed to contain a std basis,
350   and the entries of the matrix are then assumed to be reduced w.r.t. i */
351ideal getMinorIdealCache_Poly(const poly* polyMatrix, const int rowCount,
352                              const int columnCount, const int minorSize,
353                              const int k, const ideal i,
354                              const int cacheStrategy, const int cacheN,
355                              const int cacheW, const bool allDifferent)
356{ 
357  /* setting up a MinorProcessor for matrices with polynomial entries: */
358  PolyMinorProcessor mp;
359  mp.defineMatrix(rowCount, columnCount, polyMatrix);
360  int myRowIndices[rowCount];
361  for (int j = 0; j < rowCount; j++) myRowIndices[j] = j;
362  int myColumnIndices[columnCount];
363  for (int j = 0; j < columnCount; j++) myColumnIndices[j] = j;
364  mp.defineSubMatrix(rowCount, myRowIndices, columnCount, myColumnIndices);
365  mp.setMinorSize(minorSize);
366  MinorValue::SetRankingStrategy(cacheStrategy);
367  Cache<MinorKey, PolyMinorValue> cch(cacheN, cacheW);
368
369  /* containers for all upcoming results: */
370  PolyMinorValue theMinor;
371  poly f = NULL;
372  int collectedMinors = 0;
373
374  /* the ideal to be returned: */
375  ideal iii = idInit(1, 0);
376
377  bool zeroOk = ((k < 0) ? true : false); /* for k = 0, all minors are
378                                             requested, omitting zero minors */
379  bool duplicatesOk = (allDifferent ? false : true);
380  int kk = ((k < 0) ? -k : k); /* absolute value of k */
381#ifdef COUNT_AND_PRINT_OPERATIONS
382  printCounters ("starting", true);
383  int qqq = 0;
384#endif
385  /* looping over all minors: */
386  while (mp.hasNextMinor() && ((kk == 0) || (collectedMinors < kk)))
387  {
388    /* retrieving the next minor: */
389    theMinor = mp.getNextMinor(cch, i);
390#if (defined COUNT_AND_PRINT_OPERATIONS) && (COUNT_AND_PRINT_OPERATIONS > 1)
391    qqq++;
392    printf("after %d", qqq);
393    printCounters ("-th minor", false);
394#endif
395    f = theMinor.getResult();
396    if (idInsertPolyWithTests(iii, collectedMinors, pCopy(f), zeroOk,
397                              duplicatesOk))
398      collectedMinors++;
399  }
400#ifdef COUNT_AND_PRINT_OPERATIONS
401  printCounters ("ending", true);
402#endif
403
404  /* before we return the result, let's omit zero generators
405     in iii which come after the computed minors */
406  ideal jjj;
407  if (collectedMinors == 0) jjj = idInit(1, 0);
408  else                      jjj = idCopyFirstK(iii, collectedMinors);
409  idDelete(&iii);
410  return jjj;
411}
412
413ideal getMinorIdealCache_toBeDone (const matrix mat, const int minorSize,
414                                   const int k, const ideal iSB,
415                                   const int cacheStrategy, const int cacheN,
416                                   const int cacheW, const bool allDifferent)
417{
418  int rowCount = mat->nrows;
419  int columnCount = mat->ncols;
420  poly* myPolyMatrix = (poly*)(mat->m);
421  ideal iii; /* the ideal to be filled and returned */
422  int zz = 0;
423
424  /* divert to special implementation when myPolyMatrix has only number
425     entries: */
426  int*  myIntMatrix  = new int [rowCount * columnCount];
427  poly* nfPolyMatrix = new poly[rowCount * columnCount];
428  if (arrayIsNumberArray(myPolyMatrix, iSB, rowCount * columnCount,
429                         myIntMatrix, nfPolyMatrix, zz))
430    iii = getMinorIdealCache_Int(myIntMatrix, rowCount, columnCount,
431                                 minorSize, k, iSB, cacheStrategy, cacheN,
432                                 cacheW, allDifferent);
433  else
434    iii = getMinorIdealCache_Poly(nfPolyMatrix, rowCount, columnCount,
435                                  minorSize, k, iSB, cacheStrategy, cacheN,
436                                  cacheW, allDifferent);
437
438  /* clean up */
439  delete [] myIntMatrix;
440  for (int j = 0; j < rowCount * columnCount; j++) pDelete(&nfPolyMatrix[j]);
441  delete [] nfPolyMatrix;
442
443  return iii;
444}
445
446ideal getMinorIdealCache (const matrix mat, const int minorSize, const int k,
447                          const ideal iSB, const int cacheStrategy,
448                          const int cacheN, const int cacheW,
449                          const bool allDifferent)
450{
451  /* Note that this method should be replaced by getMinorIdealCache_toBeDone,
452     to enable faster computations in the case of matrices which contain
453     only numbers. But so far, this method is not yet usable as it replaces
454     the numbers by ints which may result in overflows during computations
455     of minors. */
456  int rowCount = mat->nrows;
457  int columnCount = mat->ncols;
458  poly* myPolyMatrix = (poly*)(mat->m);
459  int length = rowCount * columnCount;
460  poly* nfPolyMatrix = new poly[length];
461  ideal iii; /* the ideal to be filled and returned */
462
463  /* copy all polynomials and reduce them w.r.t. iSB
464     (if iSB is present, i.e., not the NULL pointer) */
465  for (int i = 0; i < length; i++)
466  {
467    nfPolyMatrix[i] = pCopy(myPolyMatrix[i]);
468    if (iSB != 0) nfPolyMatrix[i] = kNF(iSB, currRing->qideal,
469                                        nfPolyMatrix[i]);
470  }
471
472  iii = getMinorIdealCache_Poly(nfPolyMatrix, rowCount, columnCount,
473                                minorSize, k, iSB, cacheStrategy,
474                                cacheN, cacheW, allDifferent);
475
476  /* clean up */
477  for (int j = 0; j < length; j++) pDelete(&nfPolyMatrix[j]);
478  delete [] nfPolyMatrix;
479
480  return iii;
481}
482
483ideal getMinorIdealHeuristic (const matrix mat, const int minorSize,
484                              const int k, const ideal iSB,
485                              const bool allDifferent)
486{
487  int vars = 0; if (currRing != 0) vars = currRing->N;
488  int rowCount = mat->nrows;
489  int columnCount = mat->ncols;
490
491  /* here comes the heuristic, as of 29 January 2010:
492
493     integral domain and minorSize <= 2                -> Bareiss
494     integral domain and minorSize >= 3 and vars <= 2  -> Bareiss
495     field case and minorSize >= 3 and vars = 3
496       and c in {2, 3, ..., 32003}                     -> Bareiss
497
498     otherwise:
499     if not all minors are requested                   -> Laplace, no Caching
500     otherwise:
501     minorSize >= 3 and vars <= 4 and
502       (rowCount over minorSize)*(columnCount over minorSize) >= 100
503                                                       -> Laplace with Caching
504     minorSize >= 3 and vars >= 5 and
505       (rowCount over minorSize)*(columnCount over minorSize) >= 40
506                                                       -> Laplace with Caching
507
508     otherwise:                                        -> Laplace, no Caching
509  */
510
511  bool b = false; /* Bareiss */
512  bool l = false; /* Laplace without caching */
513  bool c = false; /* Laplace with caching */
514  if (currRingIsOverIntegralDomain())
515  { /* the field case or ring Z */
516    if      (minorSize <= 2)                                     b = true;
517    else if (vars <= 2)                                          b = true;
518    else if (currRingIsOverField() && (vars == 3)
519             && (currRing->ch >= 2) && (currRing->ch <= 32003))  b = true;
520  }
521  if (!b)
522  { /* the non-Bareiss cases */
523    if (k != 0) /* this means, not all minors are requested */   l = true;
524    else
525    { /* k == 0, i.e., all minors are requested */
526      int minorCount = 1;
527      for (int i = rowCount - minorSize + 1; i <= rowCount; i++)
528        minorCount = minorCount * i;
529      for (int i = 2; i <= minorSize; i++) minorCount = minorCount / i;
530      for (int i = columnCount - minorSize + 1; i <= columnCount; i++)
531        minorCount = minorCount * i;
532      for (int i = 2; i <= minorSize; i++) minorCount = minorCount / i;
533      /* now: minorCount =   (rowCount over minorSize)
534                           * (columnCount over minorSize) */
535      if      ((minorSize >= 3) && (vars <= 4)
536               && (minorCount >= 100))                           c = true;
537      else if ((minorSize >= 3) && (vars >= 5)
538               && (minorCount >= 40))                            c = true;
539      else                                                       l = true;
540    }
541  }
542
543  if      (b)    return getMinorIdeal(mat, minorSize, k, "Bareiss", iSB,
544                                      allDifferent);
545  else if (l)    return getMinorIdeal(mat, minorSize, k, "Laplace", iSB,
546                                      allDifferent);
547  else /* (c) */ return getMinorIdealCache(mat, minorSize, k, iSB,
548                                      3, 200, 100000, allDifferent);
549}
Note: See TracBrowser for help on using the repository browser.