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

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