source: git/Singular/dyn_modules/syzextra/mod_main.cc

spielwiese
Last change on this file was 0f9b03, checked in by Hans Schoenemann <hannes@…>, 17 months ago
fix: syzextra
  • Property mode set to 100644
File size: 10.1 KB
Line 
1#include "kernel/mod2.h"
2
3#include "misc/intvec.h"
4#include "misc/options.h"
5
6#include "coeffs/coeffs.h"
7
8#include "polys/PolyEnumerator.h"
9
10#include "polys/monomials/p_polys.h"
11#include "polys/monomials/ring.h"
12#include "polys/simpleideals.h"
13
14#include "kernel/GBEngine/kstd1.h"
15
16#include "kernel/polys.h"
17
18#include "kernel/GBEngine/syz.h"
19
20#include "Singular/tok.h"
21#include "Singular/ipid.h"
22#include "Singular/lists.h"
23#include "Singular/attrib.h"
24
25#include "Singular/ipid.h"
26#include "Singular/ipshell.h" // For iiAddCproc
27
28// extern coeffs coeffs_BIGINT
29
30#include "syzextra.h"
31
32#include "Singular/mod_lib.h"
33
34
35#include <stdio.h>
36#include <stdlib.h>
37#include <string.h>
38
39#include "polys/monomials/ring.h"
40
41
42// returns TRUE, if idRankFreeModule(m) > 0 ???
43/// test whether this input has vectors among entries or no enties
44/// result must be FALSE for only 0-entries
45static BOOLEAN id_IsModule(ideal id, ring r)
46{
47  id_Test(id, r);
48
49  if( id->rank != 1 ) return TRUE;
50
51  if (rRing_has_Comp(r))
52  {
53    const int l = IDELEMS(id);
54
55    for (int j=0; j<l; j++)
56      if (id->m[j] != NULL && p_GetComp(id->m[j], r) > 0)
57        return TRUE;
58
59    return FALSE; // rank: 1, only zero or no entries? can be an ideal OR module... BUT in the use-case should better be an ideal!
60  }
61
62  return FALSE;
63}
64
65
66
67
68static inline void NoReturn(leftv& res)
69{
70  res->rtyp = NONE;
71  res->data = NULL;
72}
73
74/// wrapper around n_ClearContent
75static BOOLEAN _ClearContent(leftv res, leftv h)
76{
77  NoReturn(res);
78
79  const char *usage = "'ClearContent' needs a (non-zero!) poly or vector argument...";
80
81  if( h == NULL )
82  {
83    WarnS(usage);
84    return TRUE;
85  }
86
87  assume( h != NULL );
88
89  if( !( h->Typ() == POLY_CMD || h->Typ() == VECTOR_CMD) )
90  {
91    WarnS(usage);
92    return TRUE;
93  }
94
95  assume (h->Next() == NULL);
96
97  poly ph = reinterpret_cast<poly>(h->Data());
98
99  if( ph == NULL )
100  {
101    WarnS(usage);
102    return TRUE;
103  }
104
105  const ring r =  currRing;
106  assume( r != NULL ); assume( r->cf != NULL ); const coeffs C = r->cf;
107
108  number n;
109
110  // experimentall (recursive enumerator treatment) of alg. ext
111  CPolyCoeffsEnumerator itr(ph);
112  n_ClearContent(itr, n, C);
113
114  res->data = n;
115  res->rtyp = NUMBER_CMD;
116
117  return FALSE;
118}
119
120/// wrapper around n_ClearDenominators
121static BOOLEAN _ClearDenominators(leftv res, leftv h)
122{
123  NoReturn(res);
124
125  const char *usage = "'ClearDenominators' needs a (non-zero!) poly or vector argument...";
126
127  if( h == NULL )
128  {
129    WarnS(usage);
130    return TRUE;
131  }
132
133  assume( h != NULL );
134
135  if( !( h->Typ() == POLY_CMD || h->Typ() == VECTOR_CMD) )
136  {
137    WarnS(usage);
138    return TRUE;
139  }
140
141  assume (h->Next() == NULL);
142
143  poly ph = reinterpret_cast<poly>(h->Data());
144
145  if( ph == NULL )
146  {
147    WarnS(usage);
148    return TRUE;
149  }
150
151  const ring r =  currRing;
152  assume( r != NULL ); assume( r->cf != NULL ); const coeffs C = r->cf;
153
154  number n;
155
156  // experimentall (recursive enumerator treatment) of alg. ext.
157  CPolyCoeffsEnumerator itr(ph);
158  n_ClearDenominators(itr, n, C);
159
160  res->data = n;
161  res->rtyp = NUMBER_CMD;
162
163  return FALSE;
164}
165
166
167/// try to get an optional (simple) integer argument out of h
168/// or return the default value
169static int getOptionalInteger(const leftv& h, const int _n)
170{
171  if( h!= NULL && h->Typ() == INT_CMD )
172  {
173    int n = (int)(long)(h->Data());
174
175    if( n < 0 )
176      Warn("Negative (%d) optional integer argument", n);
177
178    return (n);
179  }
180
181  return (_n);
182}
183
184static inline number jjLONG2N(long d)
185{
186  return n_Init(d, coeffs_BIGINT);
187}
188
189static inline void view(const intvec* v)
190{
191#ifndef SING_NDEBUG
192  v->view();
193#else
194  // This code duplication is only due to Hannes's #ifndef SING_NDEBUG!
195  Print ("intvec: {rows: %d, cols: %d, length: %d, Values: \n", v->rows(), v->cols(), v->length());
196
197  for (int i = 0; i < v->rows(); i++)
198  {
199    Print ("Row[%3d]:", i);
200    for (int j = 0; j < v->cols(); j++)
201      Print (" %5d", (*v)[j + i * (v->cols())] );
202    PrintLn ();
203  }
204  PrintS ("}\n");
205#endif
206
207}
208
209
210
211/// Get leading component
212static BOOLEAN leadcomp(leftv res, leftv h)
213{
214  if ((h!=NULL) && (h->Typ()==VECTOR_CMD || h->Typ()==POLY_CMD))
215  {
216    const ring r = currRing;
217
218    const poly p = (poly)(h->Data());
219
220    if (p != NULL )
221    {
222      assume( p != NULL );
223      p_LmTest(p, r);
224
225      const unsigned long iComp = p_GetComp(p, r);
226
227  //    assume( iComp > 0 ); // p is a vector
228
229      res->data = reinterpret_cast<void *>(jjLONG2N(iComp));
230    }
231    else
232      res->data = reinterpret_cast<void *>(jjLONG2N(0));
233
234
235    res->rtyp = BIGINT_CMD;
236    return FALSE;
237  }
238
239  WerrorS("`leadcomp(<poly/vector>)` expected");
240  return TRUE;
241}
242
243/// Same for Induced Schreyer ordering (ordering on components is defined by sign!)
244static BOOLEAN MakeInducedSchreyerOrdering(leftv res, leftv h)
245{
246  int sign = 1;
247  if ((h!=NULL) && (h->Typ()==INT_CMD))
248  {
249    const int s = (int)((long)(h->Data()));
250
251    if( s != -1 && s != 1 )
252    {
253      WerrorS("`MakeInducedSchreyerOrdering(<int>)` called with wrong integer argument (must be +-1)!");
254      return TRUE;
255    }
256
257    sign = s;
258  }
259
260  assume( sign == 1 || sign == -1 );
261  res->data = reinterpret_cast<void *>(rAssure_InducedSchreyerOrdering(currRing, TRUE, sign));
262  res->rtyp = RING_CMD; // return new ring!
263  // QRING_CMD?
264  return FALSE;
265}
266
267
268/// ?
269static BOOLEAN GetInducedData(leftv res, leftv h)
270{
271  const ring r = currRing;
272
273  int p = 0; // which IS-block? p^th!
274
275  if ((h!=NULL) && (h->Typ()==INT_CMD))
276  {
277    p = (int)((long)(h->Data())); h=h->next;
278    assume(p >= 0);
279  }
280
281  const int pos = rGetISPos(p, r);
282
283  if(  /*(*/ -1 == pos /*)*/  )
284  {
285    WerrorS("`GetInducedData([int])` called on incompatible ring (not created by 'MakeInducedSchreyerOrdering'!)");
286    return TRUE;
287  }
288
289
290  const int iLimit = r->typ[pos].data.is.limit;
291  const ideal F = r->typ[pos].data.is.F;
292
293  ideal FF = id_Copy(F, r);
294
295  lists l=(lists)omAllocBin(slists_bin);
296  l->Init(2);
297
298  l->m[0].rtyp = INT_CMD;
299  l->m[0].data = reinterpret_cast<void *>(iLimit);
300
301
302  //        l->m[1].rtyp = MODUL_CMD;
303
304  if( id_IsModule(FF, r) ) // ???
305  {
306    l->m[1].rtyp = MODUL_CMD;
307
308    //          Print("before: %d\n", FF->nrows);
309    //          FF->nrows = id_RankFreeModule(FF, r); // ???
310    //          Print("after: %d\n", FF->nrows);
311  }
312  else
313    l->m[1].rtyp = IDEAL_CMD;
314
315  l->m[1].data = reinterpret_cast<void *>(FF);
316
317  res->rtyp = LIST_CMD; // list of int/module
318  res->data = reinterpret_cast<void *>(l);
319
320  return FALSE;
321
322}
323
324/// Returns old SyzCompLimit, can set new limit
325static BOOLEAN SetInducedReferrence(leftv res, leftv h)
326{
327  res->Init();
328  NoReturn(res);
329
330  const ring r = currRing;
331
332  if( !( (h!=NULL) && ( (h->Typ()==IDEAL_CMD) || (h->Typ()==MODUL_CMD))) )
333  {
334    WerrorS("`SetInducedReferrence(<ideal/module>, [int[, int]])` expected");
335    return TRUE;
336  }
337
338  const ideal F = (ideal)h->Data(); ; // No copy!
339  h=h->next;
340
341  int rank = 0;
342
343  if ((h!=NULL) && (h->Typ()==INT_CMD))
344  {
345    rank = (int)((long)(h->Data())); h=h->next;
346    assume(rank >= 0);
347  } else
348    rank = id_RankFreeModule(F, r); // Starting syz-comp (1st: i+1)
349
350  int p = 0; // which IS-block? p^th!
351
352  if ((h!=NULL) && (h->Typ()==INT_CMD))
353  {
354    p = (int)((long)(h->Data())); h=h->next;
355    assume(p >= 0);
356  }
357
358  const int posIS = rGetISPos(p, r);
359
360  if(  /*(*/ -1 == posIS /*)*/  )
361  {
362    WerrorS("`SetInducedReferrence(<ideal/module>, [int[, int]])` called on incompatible ring (not created by 'MakeInducedSchreyerOrdering'!)");
363    return TRUE;
364  }
365
366  // F & componentWeights belong to that ordering block of currRing now:
367  rSetISReference(r, F, rank, p); // F will be copied!
368  return FALSE;
369}
370
371
372/// Get raw syzygies (idPrepare)
373static BOOLEAN idPrepare(leftv res, leftv h)
374{
375  //        extern int rGetISPos(const int p, const ring r);
376
377  const ring r = currRing;
378
379  const bool isSyz = rIsSyzIndexRing(r);
380  const int posIS = rGetISPos(0, r);
381
382
383  if ( !( (h!=NULL) && (h->Typ()==MODUL_CMD) && (h->Data() != NULL) ) )
384  {
385    WerrorS("`idPrepare(<module>)` expected");
386    return TRUE;
387  }
388
389  const ideal I = reinterpret_cast<ideal>(h->Data());
390
391  assume( I != NULL );
392  idTest(I);
393
394  int iComp = -1;
395
396  h=h->next;
397  if ( (h!=NULL) && (h->Typ()==INT_CMD) )
398  {
399    iComp = (int)((long)(h->Data()));
400  }
401  else
402  {
403      if( (!isSyz) && (-1 == posIS) )
404      {
405        WerrorS("`idPrepare(<...>)` called on incompatible ring (not created by 'MakeSyzCompOrdering' or 'MakeInducedSchreyerOrdering'!)");
406        return TRUE;
407      }
408
409    if( isSyz )
410      iComp = rGetCurrSyzLimit(r);
411    else
412      iComp = id_RankFreeModule(r->typ[posIS].data.is.F, r); // ;
413  }
414
415  assume(iComp >= 0);
416
417
418  intvec* w = reinterpret_cast<intvec *>(atGet(h, "isHomog", INTVEC_CMD));
419  tHomog hom = testHomog;
420
421  //           int add_row_shift = 0;
422  //
423  if (w!=NULL)
424  {
425    w = ivCopy(w);
426  //             add_row_shift = ww->min_in();
427  //
428  //             (*ww) -= add_row_shift;
429  //
430  //             if (idTestHomModule(I, currRing->qideal, ww))
431  //             {
432    hom = isHomog;
433  //               w = ww;
434  //             }
435  //             else
436  //             {
437  //               //WarnS("wrong weights");
438  //               delete ww;
439  //               w = NULL;
440  //               hom=testHomog;
441  //             }
442  }
443
444
445  // computes syzygies of h1,
446  // works always in a ring with ringorder_s
447  // NOTE: rSetSyzComp(syzcomp) should better be called beforehand
448  //        ideal idPrepare (ideal  h1, tHomog hom, int syzcomp, intvec **w);
449
450  ideal J = // idPrepare( I, hom, iComp, &w);
451           kStd(I, currRing->qideal, hom, &w, NULL, iComp);
452
453  idTest(J);
454
455  if (w!=NULL)
456    atSet(res, omStrDup("isHomog"), w, INTVEC_CMD);
457  //             if (w!=NULL) delete w;
458
459  res->rtyp = MODUL_CMD;
460  res->data = reinterpret_cast<void *>(J);
461  return FALSE;
462}
463
464extern "C" int SI_MOD_INIT(syzextra)(SModulFunctions* psModulFunctions)
465{
466
467#define ADD(C,D,E) \
468  psModulFunctions->iiAddCproc((currPack->libname? currPack->libname: ""), (char*)C, D, E);
469
470
471  ADD("ClearContent", FALSE, _ClearContent);
472  ADD("ClearDenominators", FALSE, _ClearDenominators);
473
474  ADD("leadcomp", FALSE, leadcomp);
475
476  ADD("SetInducedReferrence", FALSE, SetInducedReferrence);
477  ADD("GetInducedData", FALSE, GetInducedData);
478  ADD("MakeInducedSchreyerOrdering", FALSE, MakeInducedSchreyerOrdering);
479
480  ADD("idPrepare", FALSE, idPrepare);
481
482#undef ADD
483  return MAX_TOK;
484}
Note: See TracBrowser for help on using the repository browser.