source: git/Singular/MinorInterface.cc @ 33b509

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