source: git/Singular/MinorInterface.cc @ 0fb34ba

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