source: git/Singular/MinorInterface.cc @ 894057

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