source: git/Singular/LIB/schreyer.lib @ 370468

spielwiese
Last change on this file since 370468 was 370468, checked in by Oleksandr Motsak <motsak@…>, 10 years ago
Final overview of schreyer.lib
  • Property mode set to 100644
File size: 32.2 KB
Line 
1///////////////////////////////////////////////////////////////////////////
2version="version schreyer.lib 4.0.0.0 Jun_2013 "; // $Id$
3category="General purpose";
4info="
5LIBRARY: schreyer.lib     Helpers for computing a Schreyer resolution in @code{derham.lib}
6AUTHOR:  Oleksandr Motsak <U@D>, where U={motsak}, D={mathematik.uni-kl.de}
7KEYWORDS: Schreyer ordering; Schreyer resolution; syzygy
8OVERVIEW:
9@* The library contains helper procedures for computing a Schreyer resoltion (cf. [SFO]),
10   originally meant to be used by @code{derham.lib} (which requires resolutions over the homogenized Weyl algebra).
11   The library works both in the commutative and non-commutative setting (cf. [MO]).
12   Here, we call a free resolution a Schreyer resolution if any higher syzygy module is a Groebner basis of a previous one
13   with respect to the corresponding Schreyer ordering.
14   A Schreyer resolution can be much bigger than a minimal resolution of the same module, but may be easier to construct.
15@* The input for the resolution computations is a set of vectors @code{M} in form of a module over some basering @code{R}.
16   The ring @code{R} may be non-commutative, in which case the ring ordering should be global.
17@* These procedures produce/work with partial Schreyer resolutions of @code{(R^rank(M))/M} in form of
18   a ring (endowed with a special ring ordering that will be extended in the course of a resolution computation)
19   containing a list of modules @code{RES} and a module @code{MRES}:
20@* The list of modules @code{RES} contains the images of maps (also called syzygy modules) substituting the
21   computed beginning of a Schreyer resolution, that is, each syzygy module is a Groebner basis
22   of the previous one with respect to a corresponding Schreyer induced ordering.
23@* The list @code{RES} starts with a zero map given by @code{rank(M)} zero generators indicating that the image of
24   the first differential map is zero. The second map @code{RES[2]} is given by @code{M}, which indicates that
25   the resolution of @code{(R^rank(M))/M} is being computed.
26@* The module @code{MRES} is a direct sum of modules from @code{RES} and thus comprises all computed differentials.
27@* Syzygies are shifted so that @code{gen(i)} is mapped to @code{MRES[i]} under the differential map.
28@* The Schreyer ordering succesively extends the starting module ordering on @code{M} (defined in Singular by the basering @code{R})
29   and is extended to higher syzygies using the following definition:
30@*        a < b if and only if (d(a) < d(b)) OR ( (d(a) = d(b) AND (comp(a) < comp(b)) ),
31@* where @code{d(a)} is the image of a under the differential (given by @code{MRES}),
32   and @code{comp(a)} is the module component, for any module terms @code{a} and @code{b} from the same higher syzygy module.
33REFERENCES:
34[SFO] Schreyer, F.O.: Die Berechnung von Syzygien mit dem verallgemeinerten Weierstrassschen Divisionssatz,
35      Master's thesis, Univ. Hamburg, 1980.
36[MO]  Motsak, O.: Non-commutative Computer Algebra with applications: Graded commutative algebra and related
37      structures in Singular with applications, Ph.D. thesis, TU Kaiserslautern, 2010
38
39NOTE:  requires the dynamic or built-in module @code{syzextra}
40
41PROCEDURES:
42  Sres(M,len)     compute Schreyer resolution of module M of maximal length len
43  Ssyz(M)         compute Schreyer resolution of module M of length 1
44  Scontinue(len)  extend currently active resolution by (at most) len syszygies
45";
46
47static proc prepareSyz( module I, list # )
48{
49  int i;
50  int k = 0;
51  int r = nrows(I);
52  int c = ncols(I);
53
54
55  if( size(#) > 0 )
56  {
57    if( typeof(#[1]) == "int" || typeof(#[1]) == "bigint" )
58    {
59      k = #[1];
60    }
61  }
62
63  if( k < r )
64  {
65    "// *** Wrong k: ", k, " < nrows: ", r, " => setting k = r = ", r;
66    k = r;
67  }
68
69//   "k: ", k;  "c: ", c;   "I: ", I;
70
71  for( i = c; i > 0; i-- )
72  {
73    I[i] = I[i] + gen(k + i);
74  }
75
76//  DetailedPrint(I);
77
78  return(I);
79}
80
81static proc separateSyzGB( module J, int c )
82{
83  module II, G; vector v; int i;
84
85  J = simplify(J, 2);
86
87  for( i = ncols(J); i > 0; i-- )
88  {
89    v = J[i];
90    if( leadcomp(v) > c )
91    {
92      II[i] = v;
93    } else
94    {
95      G[i] = v; // leave only gen(i): i <= c
96    }
97  }
98
99  II = simplify(II, 2);
100  G = simplify(G, 2);
101
102  return (list(G, II));
103}
104
105static proc splitSyzGB( module J, int c )
106{
107  module JJ; vector v, vv; int i;
108
109  for( i = ncols(J); i > 0; i-- )
110  {
111    v = J[i];
112
113    vv = 0;
114   
115    while( leadcomp(v) <= c )
116    {
117      vv = vv + lead(v);
118      v  = v  - lead(v);
119    }
120
121    J[i] = vv;
122    JJ[i] = v;
123  }
124
125  J = simplify(J, 2);
126  JJ = simplify(JJ, 2);
127
128  return (list(J, JJ));
129}
130
131
132static proc Sinit(module M)
133{
134  def @save = basering;
135 
136  int @DEBUG = !system("with", "ndebug");
137  if( @DEBUG )
138  {
139    "Sinit::Input";
140    type(M);
141    DetailedPrint(M);
142    attrib(M);
143  }
144
145  int @RANK = nrows(M); int @SIZE = ncols(M);
146
147  int @IS_A_SB = attrib(M, "isSB"); // ??? only if all weights were zero?!
148
149  if( !@IS_A_SB )
150  {
151    M = std(M); // this should be faster than computing std in S (later on)
152  }
153
154  def S = MakeInducedSchreyerOrdering(1); // 1 puts history terms to the back
155  // TODO: NOTE: +1 causes trouble to Singular interpreter!!!???
156  setring S; // a new ring with a Schreyer ordering
157
158  if( @DEBUG )
159  {
160    "Sinit::StartingISRing";
161    basering;
162//    DetailedPrint(basering);
163  }
164
165  // Setup the leading syzygy^{-1} module to zero:
166  module Z = 0; Z[@RANK] = 0; attrib(Z, "isHomog", intvec(0)); 
167
168  module MRES = Z;
169 
170  list RES; RES[1] = Z;
171
172  module F = freemodule(@RANK);
173  intvec @V = deg(F[1..@RANK]);
174 
175  module M = imap(@save, M);
176 
177  attrib(M, "isHomog", @V);
178  attrib(M, "isSB", 1);
179
180 
181  if( @DEBUG )
182  {
183    "Sinit::SB_Input: ";
184    type(M);
185    attrib(M);
186    attrib(M, "isHomog");
187    DetailedPrint(M);
188  }
189
190  if( @DEBUG )
191  {
192    // 0^th syz. property
193    if( size(module(transpose( transpose(M) * transpose(MRES) ))) > 0 )
194    {
195      transpose( transpose(M) * transpose(MRES) );
196      "transpose( transpose(M) * transpose(MRES) ) != 0!!!";
197      $
198    }
199  }
200
201  RES[size(RES)+1] = M; // list of all syzygy modules
202  MRES = MRES, M;
203
204  attrib(MRES, "isHomog", @V); 
205
206  attrib(S, "InducionLeads", lead(M));
207  attrib(S, "InducionStart", @RANK); 
208 
209  if( @DEBUG )
210  {
211    "Sinit::MRES";
212    DetailedPrint(MRES);
213    attrib(MRES, "isHomog");
214    attrib(S);
215  }
216
217  export RES;
218  export MRES;
219  return (S);
220}
221
222static proc Sstep()
223{
224  int @DEBUG = !system("with", "ndebug");
225
226  if( @DEBUG )
227  {
228    "Sstep::NextInducedRing";
229    DetailedPrint(basering);
230
231    attrib(basering, "InducionLeads");
232    attrib(basering, "InducionStart");
233
234    GetInducedData();
235  }
236
237  // syzygy step:
238
239/*
240  // is initial weights are all zeroes!
241  def L =  lead(M);
242  intvec @V = deg(M[1..ncols(M)]);  @W;  @V;  @W = @V;  attrib(L, "isHomog", @W); 
243  SetInducedReferrence(L, @RANK, 0);
244*/
245
246//  def L =  lead(MRES);
247//  @W = @W, @V;
248//  attrib(L, "isHomog", @W); 
249
250
251  // General setting:
252//  SetInducedReferrence(MRES, 0, 0); // limit: 0!
253  int @l = size(RES);
254
255  module M = RES[@l];
256
257  module L = attrib(basering, "InducionLeads");
258  int limit = attrib(basering, "InducionStart");
259
260//  L;  limit;
261 
262  int @RANK = ncols(MRES) - ncols(M); // nrows(M); // what if M is zero?!
263
264/*
265  if( @RANK !=  nrows(M) )
266  {
267    type(MRES);
268    @RANK;
269    type(M);
270    pause();
271  }
272*/
273 
274  intvec @W = attrib(M, "isHomog");
275  intvec @V = deg(M[1..ncols(M)]);
276  @V = @W, @V;
277   
278  if( @DEBUG )
279  {
280    "Sstep::NextInput: ";
281    M;
282    deg(M[1..ncols(M)]); // no use of @W :(?
283    @RANK;   
284    DetailedPrint(MRES);
285    attrib(MRES, "isHomog"); @W;
286    deg(MRES[1..ncols(MRES)]);
287  }
288
289 
290     
291  SetInducedReferrence(L, limit, 0);
292 
293  def K = prepareSyz(M, @RANK);
294//  K;
295 
296//   attrib(K, "isHomog", @V);   DetailedPrint(K, 1000);
297
298//  pause();
299 
300  K = idPrepare(K, @RANK); // std(K); // ?
301  K = simplify(K, 2);
302
303//  K;
304
305  module N = separateSyzGB(K, @RANK)[2]; // 1^st syz. module: vectors which start in lower part (comp >= @RANK)
306
307// "N_0: "; N; DetailedPrint(N, 10);
308
309//  basering; print(@V); type(N);
310//  attrib(N, "isHomog", @V);  // TODO: fix "wrong weights"!!!? deg is wrong :(((
311  N = std(N);
312  attrib(N, "isHomog", @V);
313
314//  N;
315 
316  if( @DEBUG )
317  {
318    if( size(N) > 0 )
319    {
320      // next syz. property
321      if( size(module(transpose( transpose(N) * transpose(MRES) ))) > 0 )
322      {
323        MRES;
324
325        "N: "; N; DetailedPrint(N, 10);
326
327        "K:"; K; DetailedPrint(K, 10);
328
329        "RANKS: ", @RANK;
330
331        "transpose( transpose(N) * transpose(MRES) ) != 0!!!";
332        transpose( transpose(N) * transpose(MRES) );
333
334        "transpose(N) * transpose(MRES): ";
335        transpose(N) * transpose(MRES);
336        DetailedPrint(module(_), 2);
337        $
338      }
339    }
340  }
341 
342  RES[@l + 1] = N; // list of all syzygy modules
343 
344  MRES = MRES, N;
345  attrib(MRES, "isHomog", @V);
346
347
348  L = L, lead(N);
349  attrib(basering, "InducionLeads", L);
350
351  if( @DEBUG )
352  {
353    "Sstep::NextSyzOutput: ";
354    DetailedPrint(N);
355    attrib(N, "isHomog");
356  }
357
358}
359
360proc Scontinue(int l)
361"USAGE:  Scontinue(int len)
362RETURN:  nothing, instead it changes the currently active resolution
363PURPOSE: extends the currently active resolution by at most len syzygies
364ASSUME:  must be used within a ring returned by Sres or Ssyz
365EXAMPLE: example Scontinue; shows an example
366"
367{
368  def data = GetInducedData();
369           
370  if( (!defined(RES)) || (!defined(MRES)) || (typeof(data) != "list") || (size(data) != 2) )
371  {
372    ERROR("Sorry, but basering does not seem to be returned by Sres or Ssyz");
373  }
374  for (;  (l != 0) && (size(RES[size(RES)]) > 0); l-- )
375  {
376    Sstep();
377  }
378}
379example
380{ "EXAMPLE:"; echo = 2;
381  ring r;
382  module M = maxideal(1); M;
383  def S = Ssyz(M); setring S; S;
384  "Only the first syzygy: ";
385  RES; MRES;
386  "More syzygies: ";
387  Scontinue(10);
388  RES; MRES;
389}
390
391proc Ssyz(module M)
392"USAGE:  Ssyz(module M)
393RETURN:  ring, containing a Schreyer resolution
394PURPOSE: computes a Schreyer resolution of M of length 1 (see the library overview)
395SEE ALSO: Sres
396EXAMPLE: example Ssyz; shows an example
397"
398{
399  def S = Sinit(M); setring S;
400 
401  Sstep(); // NOTE: what if M is zero?
402
403  return (S);
404}
405example
406{ "EXAMPLE:"; echo = 2;
407  ring r;
408  module M = maxideal(1); M;
409  def S = Ssyz(M); setring S; S;
410  "Only the first syzygy: ";
411  RES;
412  MRES; // Note gen(i)
413  kill S;
414  setring r; kill M;
415
416  module M = 0;
417  def S = Ssyz(M); setring S; S;
418  "Only the first syzygy: ";
419  RES;
420  MRES;
421}
422
423proc Sres(module M, int l)
424"USAGE:  Sres(module M, int len)
425RETURN:  ring, containing a Schreyer resolution
426PURPOSE: computes a Schreyer resolution of M of length at most len (see the library overview)
427NOTE:    If given len is zero then nvars(basering) + 1 is used instead.
428SEE ALSO: Ssyz
429EXAMPLE: example Sres; shows an example
430"
431{
432  def S = Sinit(M); setring S;
433
434  if (l == 0)
435  {
436    l = nvars(basering) + 1; // not really an estimate...?!
437  }
438 
439  Sstep(); l = l - 1;
440 
441  Scontinue(l);
442 
443  return (S);
444}
445example
446{ "EXAMPLE:"; echo = 2;
447  ring r;
448  module M = maxideal(1); M;
449  def S = Sres(M, 0); setring S; S;
450  RES;
451  MRES;
452  kill S;
453  setring r; kill M;
454
455  def A = nc_algebra(-1,0); setring A;
456  ideal Q = var(1)^2, var(2)^2, var(3)^2;
457  qring SCA = twostd(Q);
458  basering;
459
460  module M = maxideal(1);
461  def S = Sres(M, 2); setring S; S;
462  RES;
463  MRES;
464}
465
466
467
468// ================================================================== //
469
470
471LIB "general.lib"; // for sort
472
473/* static proc Tail(def M) // DONE: in C++ (dyn. module: syzextra)!
474{
475  int i = ncols(M); def m;
476  while (i > 0)
477  {
478    m = M[i];
479    m = m - lead(m); // m = tail(m)   
480    M[i] = m;   
481    i--;
482  }
483  return (M);
484}*/
485
486
487/* static */ proc SSinit(def M)
488{
489  if( (typeof(M) != "module") && (typeof(M) != "ideal") )
490  {
491    ERROR("Sorry: need an ideal or a module for input");
492  }
493
494  // TODO! DONE?
495  def @save = basering;
496 
497  int @DEBUG = !system("with", "ndebug");
498  int @SYZCHECK = 1 || @DEBUG; // TODO: only for now!!
499 
500  if( @DEBUG )
501  {
502    "SSinit::Input";
503    type(M);
504//    DetailedPrint(M);
505    attrib(M);
506  }
507
508  int @RANK = nrows(M); int @SIZE = ncols(M);
509
510  int @IS_A_SB = attrib(M, "isSB"); // ??? only if all weights were zero?!
511
512  if( !@IS_A_SB )
513  {
514    def opts = option(get);
515    option(redSB); option(redTail);
516    M = std(M);
517    option(set, opts);
518    kill opts;
519  } else
520  {
521    M = simplify(M, 2 + 4 + 32);
522  }
523
524  def LEAD = lead(M);
525
526  // sort wrt neg.deg.rev.lex!
527  intvec iv_ds = sort(LEAD, "ds", 1)[2]; // ,1 => reversed!
528
529  M = M[iv_ds]; // sort M wrt ds on current leading terms
530  LEAD = LEAD[iv_ds];
531 
532  def TAIL = Tail(M);
533 
534  intvec @DEGS = deg(M[1..@SIZE]); // store actuall degrees of input elements
535 
536  // TODO: what about real modules? weighted ones?
537 
538  list @l = ringlist(@save);
539
540  int @z = 0; ideal @m = maxideal(1); intvec @wdeg = deg(@m[1..ncols(@m)]);
541
542  // NOTE: @wdeg will be ignored anyway :(
543  @l[3] = list(list("C", @z), list("lp", @wdeg));
544
545  kill @z, @wdeg; // since these vars are ring independent!
546
547  def S = ring(@l); // --MakeInducedSchreyerOrdering(1);
548
549  module F = freemodule(@RANK);
550  intvec @V = deg(F[1..@RANK]);
551 
552  setring S; // ring with an easy divisibility test ("C, lex")
553
554  if( @DEBUG )
555  {
556    "SSinit::NewRing(C, lex)";
557    basering;
558//    DetailedPrint(basering);
559  }
560
561  // Setup the leading syzygy^{-1} module to zero:
562  module Z = 0; Z[@RANK] = 0; attrib(Z, "isHomog", intvec(0)); 
563
564  module MRES = Z;
565 
566  list RES;  RES[1] = Z;
567  list LRES; LRES[1] = Z;
568  list TRES; TRES[1] = Z;
569 
570  def M = imap(@save, M);
571
572  attrib(M, "isHomog", @V);
573  attrib(M, "isSB", 1);
574  attrib(M, "degrees", @DEGS); 
575 
576  def LEAD = imap(@save, LEAD);
577 
578  attrib(LEAD, "isHomog", @V);
579  attrib(LEAD, "isSB", 1); 
580 
581  def TAIL = imap(@save, TAIL);
582
583  if( @DEBUG )
584  {
585    "SSinit::(sorted) SB_Input: ";
586    type(M);
587    attrib(M);
588    attrib(M, "isHomog");
589//    DetailedPrint(M);
590  }
591
592  if( @SYZCHECK )
593  {
594    // 0^th syz. property
595    if( size(module(transpose( transpose(M) * transpose(MRES) ))) > 0 )
596    {
597      transpose( transpose(M) * transpose(MRES) );
598      "ERROR: transpose( transpose(M) * transpose(MRES) ) != 0!!!";
599      $
600    }
601  }
602
603  RES[size(RES)+1] = M; // list of all syzygy modules
604  LRES[size(LRES)+1] = LEAD; // list of all syzygy modules
605  TRES[size(TRES)+1] = TAIL; // list of all syzygy modules
606 
607  MRES = MRES, M; //?
608
609  attrib(MRES, "isHomog", @V);
610 
611//  attrib(S, "InducionStart", @RANK);
612  attrib(S, "LEAD2SYZ", 1);
613  attrib(S, "TAILREDSYZ", 0);
614  attrib(S, "DEBUG", @DEBUG);
615  attrib(S, "SYZCHECK", @SYZCHECK);
616 
617  if( @DEBUG )
618  {
619    "SSinit::MRES";
620    MRES;
621//    DetailedPrint(MRES);
622    attrib(MRES, "isHomog");
623    attrib(S);
624  }
625
626  export RES;
627  export MRES;
628  export LRES;
629  export TRES;
630  return (S);
631}
632example
633{ "EXAMPLE:"; echo = 2;
634  ring R = 0, (w, x, y, z), dp;
635
636  def M = maxideal(1);
637  def S = SSinit(M); setring S; S;
638 
639  "Only the first initialization: ";
640  RES; LRES; TRES;
641  MRES;
642
643  kill S; setring R; kill M;
644 
645  ideal M = w^2 - x*z,  w*x - y*z,  x^2 - w*y, x*y - z^2, y^2 - w*z;
646  def S = SSinit(M); setring S; S;
647
648  "Only the first initialization: ";
649  RES; LRES; TRES;
650  MRES;
651
652  kill S; setring R; kill M;
653}
654
655
656LIB "poly.lib"; // for lcm
657
658
659
660/// Compute L(Syz(L))
661proc SSComputeLeadingSyzygyTerms(def L)
662{
663  if( typeof( attrib(basering, "DEBUG") ) == "int" )
664  {
665    int @DEBUG = attrib(basering, "DEBUG");
666  } else
667  {
668    int @DEBUG = !system("with", "ndebug");
669  }
670
671  if( @DEBUG )
672  {
673    "SSComputeLeadingSyzygyTerms::Input: ";
674    L;
675  }
676
677  int i, j, r; intvec iv_ds;
678  int N = ncols(L);
679  def a, b;
680  poly aa, bb;
681
682  bigint c;
683
684  ideal M;
685
686  module S = 0;
687 
688  for(i = 1; i <= N; i++)
689  {
690    a = L[i];
691//    "a: ", a;
692    c = leadcomp(a);
693    r = int(c);
694
695    if(r > 0)
696    {
697      aa = a[r];
698    } else
699    {
700      aa = a;
701    }
702
703    M = 0;
704   
705    for(j = i-1; j > 0; j--)
706    {
707      b = L[j];
708//      "b: ", b;
709
710      if( leadcomp(b) == c )
711      {
712        if(r > 0)
713        {
714          bb = b[r];
715        } else
716        {
717          bb = b;
718        }
719
720        M[j] = (lcm(aa, bb) / aa);
721      }
722    }
723   
724    // TODO: add quotient relations here...
725
726    M = simplify(M, 1 + 2 + 32);
727
728    iv_ds = sort(M, "ds", 1)[2]; // ,1 => reversed!
729
730    M = M[iv_ds];
731   
732    S = S, M * gen(i);
733  }
734
735  S = simplify(S, 2);
736
737  S = sort(S, "ds", 1)[1]; // ,1 => reversed! // TODO: not needed?
738 
739  if( @DEBUG )
740  {
741    "SSComputeLeadingSyzygyTerms::Output: ";
742    S;
743  } 
744
745  attrib(S, "isSB", 1);
746
747  return (S);
748}
749
750/// Compute Syz(L), where L is a monomial (leading) module
751proc SSCompute2LeadingSyzygyTerms(def L, int @TAILREDSYZ)
752{
753  if( typeof( attrib(basering, "DEBUG") ) == "int" )
754  {
755    int @DEBUG = attrib(basering, "DEBUG");
756  } else
757  {
758    int @DEBUG = !system("with", "ndebug");
759  }
760
761  if( typeof( attrib(basering, "SYZCHECK") ) == "int" )
762  {
763    int @SYZCHECK = attrib(basering, "SYZCHECK");
764  } else
765  {
766    int @SYZCHECK = @DEBUG;
767  }
768 
769
770  if( @DEBUG )
771  {
772    "SSCompute2LeadingSyzygyTerms::Input: ";
773    L;
774    "@TAILREDSYZ: ", @TAILREDSYZ;
775  }
776
777  int i, j, r;
778  int N = ncols(L);
779  def a, b;
780
781  poly aa, bb, @lcm;
782
783  bigint c;
784
785  module M;
786
787  module S = 0;
788
789  for(i = 1; i <= N; i++)
790  {
791    a = L[i];
792//    "a: ", a;
793    c = leadcomp(a);
794    r = int(c);
795
796    aa = leadmonomial(a);
797
798    M = 0;
799
800    for(j = i-1; j > 0; j--)
801    {
802      b = L[j];
803//      "b: ", b;
804
805      if( leadcomp(b) == c )
806      {
807        bb = leadmonomial(b);
808        @lcm = lcm(aa, bb);
809
810        M[j] = (@lcm / aa)* gen(i) - (@lcm / bb)* gen(j);
811      }
812    }
813   
814    M = simplify(M, 2);
815
816    // TODO: add quotient relations here...
817    S = S, M;
818  }
819
820  if( @TAILREDSYZ )
821  {
822    // Make sure that 2nd syzygy terms are not reducible by 1st
823    def opts = option(get);
824    option(redSB); option(redTail);
825    S = std(S); // binomial module
826    option(set, opts);
827    //  kill opts;
828  } else
829  {
830    S = simplify(S, 2 + 32);
831  }
832
833  S = sort(S, "ds", 1)[1]; // ,1 => reversed!
834
835  if( @DEBUG )
836  {
837    "SSCompute2LeadingSyzygyTerms::Syz(LEAD): "; S;
838  }
839
840  if( @SYZCHECK )
841  {
842    if( size(S) > 0 and size(L) > 0 )
843    {
844      if( size(module(transpose( transpose(S) * transpose(L) ))) > 0 )
845      {
846        transpose( transpose(S) * transpose(L) );
847        "ERROR: transpose( transpose(S) * transpose(L) ) != 0!!!";
848        $
849      }
850    }
851  }
852
853  module S2 = Tail(S);
854  S = lead(S); // (C,lp) on base ring!
855             
856  if( @DEBUG )
857  {
858    "SSCompute2LeadingSyzygyTerms::Output: "; S; S2;
859  } 
860 
861  attrib(S, "isSB", 1);
862
863  return (S, S2);
864}
865
866// -------------------------------------------------------- //
867
868/// TODO: save shortcut LM(m) * "t" -> ?
869proc SSReduceTerm(poly m, def t, def L, def T, list #)
870{
871  if( typeof( attrib(basering, "DEBUG") ) == "int" )
872  {
873    int @DEBUG = attrib(basering, "DEBUG");
874  } else
875  {
876    int @DEBUG = !system("with", "ndebug");
877  }
878
879  if( @DEBUG )
880  {
881    "SSReduce::Input: ";
882
883    "mult: ", m;
884    "term: ", t;
885    "L: ", L;
886    "T: ", T;
887    if( size(#) > 0 )
888    {
889      "LSyz: ", #;
890    }
891//    "attrib(LS, 'isSB')", attrib(LS, "isSB");
892  }
893 
894  vector s = 0;
895
896  if( t == 0 )
897  {
898    return (s);
899  }
900
901  def product = m * t;
902
903  bigint c = leadcomp(t);
904  int r = int(c);
905 
906  def a, b, nf, bb;
907
908  // looking for an appropriate reducer
909  for( int k = ncols(L); k > 0; k-- )
910  {
911    a = L[k];
912    // with the same mod. component
913    if( leadcomp(a) == c )
914    {
915      b = - (leadmonomial(product) / leadmonomial(L[k]));
916     
917      // which divides the product
918      if( b != 0 )
919      {
920//        "b: ", b;
921        bb = b * gen(k);
922        nf = bb;
923
924        if( size(#) > 0 )
925        {
926          if( typeof(#[1]) == "module" )
927          {
928            nf = NF(bb, #[1]);
929//        "NF: ", nf;
930          }
931        }
932
933        // while the complement (the fraction) is not reducible by leading syzygies
934        if( nf != 0 )
935        {
936          /// TODO: save shortcut LM(m) * T[i] -> ?
937
938          // choose ANY such reduction... (with the biggest index?)
939          s = bb + SSTraverseTail(b, T[k], L, T, #);
940          break;
941        }
942      }
943    }
944  } 
945  if( @DEBUG )
946  {
947    "SSReduceTerm::Output: ", s;
948  }
949  return (s);
950}
951
952// TODO: store m * @tail -.-^-.-^-.--> ?
953proc SSTraverseTail(poly m, def @tail, def L, def T, list #)
954{
955  if( typeof( attrib(basering, "DEBUG") ) == "int" )
956  {
957    int @DEBUG = attrib(basering, "DEBUG");
958  } else
959  {
960    int @DEBUG = !system("with", "ndebug");
961  }
962
963  if( @DEBUG )
964  {
965    "SSTraverse::Input: ";
966
967    "mult: ", m;
968    "tail: ", @tail; // T[i];
969
970    if( size(#) > 0 )
971    {
972      "LSyz: "; #[1];
973    }
974  }
975
976  vector s = 0;
977
978  def @l;
979
980  // iterate tail-terms in ANY order!
981  while( size(@tail) > 0 )
982  {
983    @l = lead(@tail);
984    s = s + SSReduceTerm(m, @l, L, T, #);
985    @tail = @tail - @l;
986  }
987
988  if( @DEBUG )
989  {
990    "SSTraverseTail::Output: ", s;
991  }
992  return (s);
993}
994
995// -------------------------------------------------------- //
996
997// module (N, LL, TT) = SSComputeSyzygy(L, T);
998// Compute Syz(L ++ T) = N = LL ++ TT
999proc SSComputeSyzygy(def L, def T)
1000{
1001  if( typeof( attrib(basering, "DEBUG") ) == "int" )
1002  {
1003    int @DEBUG = attrib(basering, "DEBUG");
1004  } else
1005  {
1006    int @DEBUG = !system("with", "ndebug");
1007  }
1008 
1009  if( @DEBUG )
1010  {
1011    "SSComputeSyzygy::Input";
1012    "basering: ", basering; attrib(basering);
1013//    DetailedPrint(basering);
1014
1015//    "iCompShift: ", iCompShift;
1016
1017    "L: "; L;
1018    "T: "; T;
1019  }
1020
1021  def a; bigint c; int r, k; poly aa;
1022
1023  int @LEAD2SYZ = 0;
1024  if( typeof( attrib(basering, "LEAD2SYZ") ) == "int" )
1025  {
1026    @LEAD2SYZ = attrib(basering, "LEAD2SYZ");
1027  }
1028
1029  int @TAILREDSYZ = 1;
1030  if( typeof( attrib(basering, "TAILREDSYZ") ) == "int" )
1031  {
1032    @TAILREDSYZ = attrib(basering, "TAILREDSYZ");
1033//    @TAILREDSYZ;
1034  }
1035 
1036  /// Get the critical leading syzygy terms
1037  if( @LEAD2SYZ ) // & 2nd syz. term
1038  {
1039    def a2; int r2; poly aa2; 
1040    module LL, LL2;
1041    (LL, LL2) = SSCompute2LeadingSyzygyTerms(L, @TAILREDSYZ); // ++
1042  } else
1043  {
1044    module LL = SSComputeLeadingSyzygyTerms(L);
1045  }
1046
1047  module TT, SYZ;
1048
1049  if( size(LL) > 0 )
1050  {
1051    list LS;
1052
1053    if( @TAILREDSYZ )
1054    {
1055      LS = list(LL);
1056    }
1057   
1058    vector @tail;
1059
1060    for(k = ncols(LL); k > 0; k-- )
1061    {
1062      // leading syz. term:
1063      a = LL[k]; c = leadcomp(a); r = int(c); aa = leadmonomial(a);
1064      //    "A: ", a, " --->>>> ", aa, " **** [", r, "]: ";
1065
1066      /// TODO: save shortcut (aa) * T[r] -> ?
1067      @tail = SSTraverseTail(aa, T[r], L, T, LS);
1068             
1069      // get the 2nd syzygy term...
1070     
1071      if( @LEAD2SYZ ) // with the 2nd syz. term:
1072      {     
1073        a2 = LL2[k]; c = leadcomp(a2); r2 = int(c); aa2 = leadmonomial(a2);
1074        @tail = @tail +
1075             /// TODO: save shortcut (aa2) * T[r2] -> ?
1076             a2 + SSTraverseTail(aa2, T[r2], L, T, LS);
1077      } else
1078      {
1079        @tail = @tail + SSReduceTerm(aa, L[r], L, T, LS);
1080      }
1081     
1082     
1083      TT[k] = @tail;
1084      SYZ[k] = a + @tail;
1085    }
1086  }
1087
1088/*
1089  def opts = option(get); option(redSB); option(redTail);
1090  module SYZ = std(syz(M));
1091  option(set, opts); kill opts;
1092 
1093  module LL = lead(SYZ); // TODO: WRONG ORDERING!!!!!!!!
1094  module TT = Tail(SYZ);
1095*/
1096 
1097  if( @DEBUG )
1098  {
1099    "SSComputeSyzygy::Output";
1100
1101    "SYZ: "; SYZ;
1102    "LL: "; LL;
1103    "TT: "; TT;
1104  }
1105
1106  return (SYZ, LL, TT);
1107}
1108
1109// resolution/syzygy step:
1110static proc SSstep()
1111{
1112  if( typeof( attrib(basering, "DEBUG") ) == "int" )
1113  {
1114    int @DEBUG = attrib(basering, "DEBUG");
1115  } else
1116  {
1117    int @DEBUG = !system("with", "ndebug");
1118  }
1119
1120
1121  if( typeof( attrib(basering, "SYZCHECK") ) == "int" )
1122  {
1123    int @SYZCHECK = attrib(basering, "SYZCHECK");
1124  } else
1125  {
1126    int @SYZCHECK = @DEBUG;
1127  }
1128
1129  if( @DEBUG )
1130  {
1131    "SSstep::NextInducedRing";
1132    "basering: ", basering; attrib(basering);
1133  }
1134
1135/*
1136  // is initial weights are all zeroes!
1137  def L =  lead(M);
1138  intvec @V = deg(M[1..ncols(M)]);  @W;  @V;  @W = @V;  attrib(L, "isHomog", @W); 
1139  SetInducedReferrence(L, @RANK, 0);
1140*/
1141
1142//  def L =  lead(MRES);
1143//  @W = @W, @V;
1144//  attrib(L, "isHomog", @W); 
1145
1146
1147  // General setting:
1148//  SetInducedReferrence(MRES, 0, 0); // limit: 0!
1149  int @l = size(RES);
1150
1151  def M =  RES[@l];
1152
1153  def L = LRES[@l];
1154  def T = TRES[@l];
1155
1156
1157  //// TODO: wrong !!!!!
1158  int @RANK = ncols(MRES) - ncols(M); // nrows(M); // what if M is zero?!
1159
1160 
1161
1162/*
1163  if( @RANK !=  nrows(M) )
1164  {
1165    type(MRES);
1166    @RANK;
1167    type(M);
1168    pause();
1169  }
1170*/
1171 
1172  intvec @W = attrib(M, "isHomog"); intvec @V = attrib(M, "degrees"); @V = @W, @V;
1173   
1174  if( @DEBUG )
1175  {
1176    "Sstep::NextInput: ";
1177    M;
1178    L;
1179    @V;
1180    @RANK;
1181//    DetailedPrint(MRES);
1182    attrib(MRES, "isHomog");
1183  }
1184
1185     
1186  // TODO: N  = SYZ( M )!!!
1187  module N, LL, TT;
1188  (N, LL, TT) = SSComputeSyzygy(/*M, */L, T/*, @RANK*/);
1189
1190  // shift syz.comp by @RANK:
1191  module Z;
1192  Z = 0; Z[@RANK] = 0; Z = Z, transpose(LL);   LL = transpose(Z);
1193  Z = 0; Z[@RANK] = 0; Z = Z, transpose(TT);   TT = transpose(Z);
1194  Z = 0; Z[@RANK] = 0; Z = Z, transpose(N);     N = transpose(Z);
1195
1196
1197  if( @SYZCHECK )
1198  {
1199    if( size(N) > 0 )
1200    {
1201      // next syz. property
1202      if( size(module(transpose( transpose(N) * transpose(MRES) ))) > 0 )
1203      {
1204        "MRES", MRES;
1205
1206        "N: "; N; // DetailedPrint(N, 2);
1207
1208        "LL:"; LL; // DetailedPrint(LL, 1);
1209        "TT:"; TT; // DetailedPrint(TT, 10);
1210
1211        "RANKS: ", @RANK;
1212
1213        "transpose( transpose(N) * transpose(MRES) ) != 0!!!";
1214        transpose( transpose(N) * transpose(MRES) );
1215
1216        "transpose(N) * transpose(MRES): ";
1217        transpose(N) * transpose(MRES);
1218        // DetailedPrint(module(_), 2);
1219        $
1220      }
1221    }
1222  }
1223
1224  attrib(N, "isHomog", @V);
1225
1226  // TODO: correct the following:
1227  intvec @DEGS = deg(N[1..ncols(N)]); // no mod. comp. weights :(
1228
1229 
1230  attrib(N, "degrees", @DEGS);
1231 
1232   RES[@l + 1] = N; // list of all syzygy modules
1233  LRES[@l + 1] = LL; // list of all syzygy modules
1234  TRES[@l + 1] = TT; // list of all syzygy modules
1235
1236  MRES = MRES, N;
1237 
1238  attrib(MRES, "isHomog", @V);
1239
1240//  L = L, lead(N);  attrib(basering, "InducionLeads", L);
1241
1242  if( @DEBUG )
1243  {
1244    "SSstep::NextSyzOutput: ";
1245    N;
1246//    DetailedPrint(N);
1247    attrib(N);
1248  }
1249
1250}
1251
1252proc SScontinue(int l)
1253"USAGE:  SScontinue(l)
1254RETURN:  nothing, instead it changes RES and MRES variables in the current ring
1255PURPOSE: computes further (at most l) syzygies
1256NOTE:    must be used within a ring returned by Sres or Ssyz. RES and MRES are
1257         explained in Sres
1258EXAMPLE: example Scontinue; shows an example
1259"
1260{
1261
1262  /// TODO!
1263//  def data = GetInducedData();
1264
1265  if( (!defined(RES)) || (!defined(MRES)) ) /* || (typeof(data) != "list") || (size(data) != 2) */
1266  {
1267    ERROR("Sorry, but basering does not seem to be returned by Sres or Ssyz");
1268  }
1269  for (;  (l != 0) && (size(RES[size(RES)]) > 0); l-- )
1270  {
1271    SSstep();
1272  }
1273}
1274example
1275{ "EXAMPLE:"; echo = 2;
1276  ring r;
1277  module M = maxideal(1); M;
1278  def S = SSsyz(M); setring S; S;
1279  "Only the first syzygy: ";
1280  RES; MRES;
1281  "More syzygies: ";
1282  SScontinue(10);
1283  RES; MRES;
1284}
1285
1286proc SSsyz(def M)
1287"USAGE:  SSsyz(M)
1288RETURN:  ring, containing a list of modules RES and a module MRES
1289PURPOSE: computes the first syzygy module of M (wrt some Schreyer ordering)?
1290NOTE:    The output is explained in Sres
1291EXAMPLE: example Ssyz; shows an example
1292"
1293{
1294  if( (typeof(M) != "module") && (typeof(M) != "ideal") )
1295  {
1296    ERROR("Sorry: need an ideal or a module for input");
1297  }
1298
1299  def SS = SSinit(M); setring SS;
1300 
1301  SSstep(); // NOTE: what if M is zero?
1302
1303  return (SS);
1304}
1305example
1306{ "EXAMPLE:"; echo = 2;
1307  ring r;
1308
1309/*  ideal M = 0;
1310  def S = SSsyz(M); setring S; S;
1311  "Only the first syzygy: ";
1312  RES; LRES; TRES;
1313  MRES;
1314 
1315  kill S; setring r; kill M;
1316*/ 
1317
1318  module M = maxideal(1); M;
1319  def S = SSres(M, 0); setring S; S;
1320  MRES;
1321  RES;
1322  "";
1323  LRES;
1324  "";
1325  TRES;
1326
1327  kill S; setring r; kill M;
1328
1329  kill r;
1330 
1331  ring R = 0, (w, x, y, z), dp;
1332  ideal M = w^2 - x*z,  w*x - y*z,  x^2 - w*y, x*y - z^2, y^2 - w*z;
1333 
1334  def S = SSres(M, 0); setring S; S;
1335  MRES;
1336  RES;
1337  "";
1338  LRES;
1339  "";
1340  TRES;
1341}
1342
1343proc SSres(def M, int l)
1344"USAGE:  SSres(I, l)
1345RETURN:  ring, containing a list of modules RES and a module MRES
1346PURPOSE: computes (at most l) syzygy modules of M wrt the classical Schreyer
1347         induced ordering with gen(i) > gen(j) if i > j, provided both gens
1348         are from the same syzygy level.???
1349NOTE:    RES contains the images of maps subsituting the beginning of the
1350         Schreyer free resolution of baseRing^r/M, while MRES is a sum of
1351         these images in a big free sum, containing all the syzygy modules.
1352         The syzygy modules are shifted so that gen(i) correspons to MRES[i].
1353         The leading zero module RES[0] indicates the fact that coker of the
1354         first map is zero. The number of zeroes inducates the rank of input.
1355NOTE:    If l == 0 then l is set to be nvars(basering) + 1
1356EXAMPLE: example SSres; shows an example
1357"
1358{
1359  if( (typeof(M) != "module") && (typeof(M) != "ideal") )
1360  {
1361    ERROR("Sorry: need an ideal or a module for input");
1362  }
1363
1364  def SS = SSinit(M); setring SS;
1365
1366  if (l == 0)
1367  {
1368    l = nvars(basering) + 1; // not really an estimate...?!
1369  }
1370
1371  SSstep(); l = l - 1;
1372
1373  SScontinue(l);
1374
1375  return (SS);
1376}
1377example
1378{ "EXAMPLE:"; echo = 2;
1379  ring r;
1380  module M = maxideal(1); M;
1381  def S = SSres(M, 0); setring S; S;
1382  RES;
1383  MRES;
1384  kill S;
1385  setring r; kill M;
1386
1387  def A = nc_algebra(-1,0); setring A;
1388  ideal Q = var(1)^2, var(2)^2, var(3)^2;
1389  qring SCA = twostd(Q);
1390  basering;
1391
1392  module M = maxideal(1);
1393  def S = SSres(M, 2); setring S; S;
1394  RES;
1395  MRES;
1396}
1397
1398
1399
1400static proc loadme()
1401{
1402  int @DEBUG = !system("with", "ndebug");
1403
1404  if( @DEBUG )
1405  {
1406   
1407    "ndebug?: ", system("with", "ndebug");
1408    "om_ndebug?: ", system("with", "om_ndebug");
1409
1410    listvar(Top);
1411    listvar(Schreyer);
1412  }
1413//  listvar(Syzextra); listvar(Syzextra_g);
1414
1415  if( !defined(DetailedPrint) )
1416  {
1417    if( 1 )
1418    {
1419
1420      if( @DEBUG )
1421      {
1422        "Loading the Release version!";
1423      }
1424      load("syzextra.so");
1425
1426      if( @DEBUG )
1427      {
1428        listvar(Syzextra);
1429      }
1430
1431      exportto(Top, Syzextra::ClearContent);
1432      exportto(Top, Syzextra::ClearDenominators);
1433     
1434//      export Syzextra;
1435
1436//      exportto(Schreyer, Syzextra::noop);
1437      exportto(Schreyer, Syzextra::DetailedPrint);
1438      exportto(Schreyer, Syzextra::leadmonomial);
1439      exportto(Schreyer, Syzextra::leadcomp);
1440//      exportto(Schreyer, Syzextra::leadrawexp);
1441//      exportto(Schreyer, Syzextra::ISUpdateComponents);
1442      exportto(Schreyer, Syzextra::SetInducedReferrence);
1443      exportto(Schreyer, Syzextra::GetInducedData);
1444//      exportto(Schreyer, Syzextra::GetAMData);
1445//      exportto(Schreyer, Syzextra::SetSyzComp);
1446      exportto(Schreyer, Syzextra::MakeInducedSchreyerOrdering);
1447//      exportto(Schreyer, Syzextra::MakeSyzCompOrdering);
1448      exportto(Schreyer, Syzextra::idPrepare);
1449//      exportto(Schreyer, Syzextra::reduce_syz);
1450//      exportto(Schreyer, Syzextra::p_Content);
1451
1452      exportto(Schreyer, Syzextra::ProfilerStart); exportto(Schreyer, Syzextra::ProfilerStop);
1453
1454      exportto(Schreyer, Syzextra::Tail);
1455
1456      exportto(Schreyer, Syzextra::m2_end);
1457    }
1458/*
1459    else
1460    {
1461      if( @DEBUG )
1462      {
1463        "Loading the Debug version!";
1464      }
1465
1466      load("syzextra.so");
1467
1468      if( @DEBUG )
1469      {     
1470        listvar(Syzextra_g);
1471      }
1472     
1473      exportto(Top, Syzextra_g::ClearContent);
1474      exportto(Top, Syzextra_g::ClearDenominators);
1475
1476//      export Syzextra_g;
1477//      exportto(Schreyer, Syzextra_g::noop);
1478      exportto(Schreyer, Syzextra_g::DetailedPrint);
1479      exportto(Schreyer, Syzextra_g::leadmonomial);
1480      exportto(Schreyer, Syzextra_g::leadcomp);
1481//      exportto(Schreyer, Syzextra_g::leadrawexp);
1482//      exportto(Schreyer, Syzextra_g::ISUpdateComponents);
1483      exportto(Schreyer, Syzextra_g::SetInducedReferrence);
1484      exportto(Schreyer, Syzextra_g::GetInducedData);
1485//      exportto(Schreyer, Syzextra_g::GetAMData);
1486//      exportto(Schreyer, Syzextra_g::SetSyzComp);
1487      exportto(Schreyer, Syzextra_g::MakeInducedSchreyerOrdering);
1488//      exportto(Schreyer, Syzextra_g::MakeSyzCompOrdering);
1489      exportto(Schreyer, Syzextra_g::idPrepare);
1490//      exportto(Schreyer, Syzextra_g::reduce_syz);
1491//      exportto(Schreyer, Syzextra_g::p_Content);
1492
1493      exportto(Schreyer, Syzextra_g::ProfilerStart); exportto(Schreyer, Syzextra_g::ProfilerStop);
1494
1495      exportto(Schreyer, Syzextra_g::Tail);
1496     
1497     
1498      exportto(Schreyer, Syzextra_g::m2_end);
1499    }
1500*/
1501
1502    exportto(Top, DetailedPrint);
1503    exportto(Top, GetInducedData);
1504
1505    if( @DEBUG )
1506    {
1507      listvar(Top);
1508      listvar(Schreyer);
1509    }
1510  }
1511 
1512  if( !defined(GetInducedData) )
1513  {
1514    ERROR("Sorry but we are missing the dynamic module (syzextra.so)...");
1515  }
1516
1517}
1518
1519static proc mod_init()
1520{
1521  loadme();
1522}
1523
1524
1525proc testallSexamples()
1526{
1527  example Ssyz;
1528  example Scontinue;
1529  example Sres; 
1530}
1531
1532proc testallSSexamples()
1533{
1534  example SSsyz;
1535  example SScontinue;
1536  example SSres; 
1537}
1538
1539example
1540{ "EXAMPLE:"; echo = 2;
1541  testallSexamples();
1542  testallSSexamples();
1543}
Note: See TracBrowser for help on using the repository browser.