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

spielwiese
Last change on this file since cb8103a was f63b13, checked in by Oleksandr Motsak <motsak@…>, 11 years ago
Optional starting of Google Profiler NOTE: also needs to link with -lprofiler (google tools) NOTE: with the use of schreyer.lib: use ProfilerStart(file_name)/ProfilerStop()
  • Property mode set to 100644
File size: 30.0 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    deg(M[1..ncols(M)]); // no use of @W :(?
253    @RANK;   
254    DetailedPrint(MRES);
255    attrib(MRES, "isHomog"); @W;
256    deg(MRES[1..ncols(MRES)]);
257  }
258
259 
260     
261  SetInducedReferrence(L, limit, 0);
262 
263  def K = prepareSyz(M, @RANK);
264//  K;
265 
266//   attrib(K, "isHomog", @V);   DetailedPrint(K, 1000);
267
268//  pause();
269 
270  K = idPrepare(K, @RANK); // std(K); // ?
271  K = simplify(K, 2);
272
273//  K;
274
275  module N = separateSyzGB(K, @RANK)[2]; // 1^st syz. module: vectors which start in lower part (comp >= @RANK)
276
277// "N_0: "; N; DetailedPrint(N, 10);
278
279//  basering; print(@V); type(N);
280//  attrib(N, "isHomog", @V);  // TODO: fix "wrong weights"!!!? deg is wrong :(((
281  N = std(N);
282  attrib(N, "isHomog", @V);
283
284//  N;
285 
286  if( @DEBUG )
287  {
288    if( size(N) > 0 )
289    {
290      // next syz. property
291      if( size(module(transpose( transpose(N) * transpose(MRES) ))) > 0 )
292      {
293        MRES;
294
295        "N: "; N; DetailedPrint(N, 10);
296
297        "K:"; K; DetailedPrint(K, 10);
298
299        "RANKS: ", @RANK;
300
301        "transpose( transpose(N) * transpose(MRES) ) != 0!!!";
302        transpose( transpose(N) * transpose(MRES) );
303
304        "transpose(N) * transpose(MRES): ";
305        transpose(N) * transpose(MRES);
306        DetailedPrint(module(_), 2);
307        $
308      }
309    }
310  }
311 
312  RES[@l + 1] = N; // list of all syzygy modules
313 
314  MRES = MRES, N;
315  attrib(MRES, "isHomog", @V);
316
317
318  L = L, lead(N);
319  attrib(basering, "InducionLeads", L);
320
321  if( @DEBUG )
322  {
323    "Sstep::NextSyzOutput: ";
324    DetailedPrint(N);
325    attrib(N, "isHomog");
326  }
327
328}
329
330proc Scontinue(int l)
331"USAGE:  Scontinue(l)
332RETURN:  nothing, instead it changes RES and MRES variables in the current ring
333PURPOSE: computes further (at most l) syzygies
334NOTE:    must be used within a ring returned by Sres or Ssyz. RES and MRES are
335         explained in Sres
336EXAMPLE: example Scontinue; shows an example
337"
338{
339  def data = GetInducedData();
340           
341  if( (!defined(RES)) || (!defined(MRES)) || (typeof(data) != "list") || (size(data) != 2) )
342  {
343    ERROR("Sorry, but basering does not seem to be returned by Sres or Ssyz");
344  }
345  for (;  (l != 0) && (size(RES[size(RES)]) > 0); l-- )
346  {
347    Sstep();
348  }
349}
350example
351{ "EXAMPLE:"; echo = 2;
352  ring r;
353  module M = maxideal(1); M;
354  def S = Ssyz(M); setring S; S;
355  "Only the first syzygy: ";
356  RES; MRES;
357  "More syzygies: ";
358  Scontinue(10);
359  RES; MRES;
360}
361
362proc Ssyz(module M)
363"USAGE:  Ssyz(M)
364RETURN:  ring, containing a list of modules RES and a module MRES
365PURPOSE: computes the first syzygy module of M (wrt some Schreyer ordering)
366NOTE:    The output is explained in Sres
367EXAMPLE: example Ssyz; shows an example
368"
369{
370  def S = Sinit(M); setring S;
371 
372  Sstep(); // NOTE: what if M is zero?
373
374  return (S);
375}
376example
377{ "EXAMPLE:"; echo = 2;
378  ring r;
379  module M = maxideal(1); M;
380  def S = Ssyz(M); setring S; S;
381  "Only the first syzygy: ";
382  RES;
383  MRES; // Note gen(i)
384  kill S;
385  setring r; kill M;
386
387  module M = 0;
388  def S = Ssyz(M); setring S; S;
389  "Only the first syzygy: ";
390  RES;
391  MRES;
392}
393
394proc Sres(module M, int l)
395"USAGE:  Sres(M, l)
396RETURN:  ring, containing a list of modules RES and a module MRES
397PURPOSE: computes (at most l) syzygy modules of M wrt the classical Schreyer
398         induced ordering with gen(i) > gen(j) if i > j, provided both gens
399         are from the same syzygy level.
400NOTE:    RES contains the images of maps subsituting the beginning of the
401         Schreyer free resolution of baseRing^r/M, while MRES is a sum of
402         these images in a big free sum, containing all the syzygy modules.
403         The syzygy modules are shifted so that gen(i) correspons to MRES[i].
404         The leading zero module RES[0] indicates the fact that coker of the
405         first map is zero. The number of zeroes inducates the rank of input.
406NOTE:    If l == 0 then l is set to be nvars(basering) + 1
407EXAMPLE: example Sres; shows an example
408"
409{
410  def S = Sinit(M); setring S;
411
412  if (l == 0)
413  {
414    l = nvars(basering) + 1; // not really an estimate...?!
415  }
416 
417  Sstep(); l = l - 1;
418 
419  Scontinue(l);
420 
421  return (S);
422}
423example
424{ "EXAMPLE:"; echo = 2;
425  ring r;
426  module M = maxideal(1); M;
427  def S = Sres(M, 0); setring S; S;
428  RES;
429  MRES;
430  kill S;
431  setring r; kill M;
432
433  def A = nc_algebra(-1,0); setring A;
434  ideal Q = var(1)^2, var(2)^2, var(3)^2;
435  qring SCA = twostd(Q);
436  basering;
437
438  module M = maxideal(1);
439  def S = Sres(M, 2); setring S; S;
440  RES;
441  MRES;
442}
443
444
445
446// ================================================================== //
447
448
449LIB "general.lib"; // for sort
450
451/* static proc Tail(def M) // DONE: in C++ (dyn. module: syzextra)!
452{
453  int i = ncols(M); def m;
454  while (i > 0)
455  {
456    m = M[i];
457    m = m - lead(m); // m = tail(m)   
458    M[i] = m;   
459    i--;
460  }
461  return (M);
462}*/
463
464
465/* static */ proc SSinit(def M)
466{
467  if( (typeof(M) != "module") && (typeof(M) != "ideal") )
468  {
469    ERROR("Sorry: need an ideal or a module for input");
470  }
471
472  // TODO! DONE?
473  def @save = basering;
474 
475  int @DEBUG = !system("with", "ndebug");
476  int @SYZCHECK = 1 || @DEBUG; // TODO: only for now!!
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( @SYZCHECK )
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  attrib(S, "SYZCHECK", @SYZCHECK);
594 
595  if( @DEBUG )
596  {
597    "SSinit::MRES";
598    MRES;
599//    DetailedPrint(MRES);
600    attrib(MRES, "isHomog");
601    attrib(S);
602  }
603
604  export RES;
605  export MRES;
606  export LRES;
607  export TRES;
608  return (S);
609}
610example
611{ "EXAMPLE:"; echo = 2;
612  ring R = 0, (w, x, y, z), dp;
613
614  def M = maxideal(1);
615  def S = SSinit(M); setring S; S;
616 
617  "Only the first initialization: ";
618  RES; LRES; TRES;
619  MRES;
620
621  kill S; setring R; kill M;
622 
623  ideal M = w^2 - x*z,  w*x - y*z,  x^2 - w*y, x*y - z^2, y^2 - w*z;
624  def S = SSinit(M); setring S; S;
625
626  "Only the first initialization: ";
627  RES; LRES; TRES;
628  MRES;
629
630  kill S; setring R; kill M;
631}
632
633
634LIB "poly.lib"; // for lcm
635
636
637
638/// Compute L(Syz(L))
639proc SSComputeLeadingSyzygyTerms(def L)
640{
641  if( typeof( attrib(basering, "DEBUG") ) == "int" )
642  {
643    int @DEBUG = attrib(basering, "DEBUG");
644  } else
645  {
646    int @DEBUG = !system("with", "ndebug");
647  }
648
649  if( @DEBUG )
650  {
651    "SSComputeLeadingSyzygyTerms::Input: ";
652    L;
653  }
654
655  int i, j, r; intvec iv_ds;
656  int N = ncols(L);
657  def a, b;
658  poly aa, bb;
659
660  bigint c;
661
662  ideal M;
663
664  module S = 0;
665 
666  for(i = 1; i <= N; i++)
667  {
668    a = L[i];
669//    "a: ", a;
670    c = leadcomp(a);
671    r = int(c);
672
673    if(r > 0)
674    {
675      aa = a[r];
676    } else
677    {
678      aa = a;
679    }
680
681    M = 0;
682   
683    for(j = i-1; j > 0; j--)
684    {
685      b = L[j];
686//      "b: ", b;
687
688      if( leadcomp(b) == c )
689      {
690        if(r > 0)
691        {
692          bb = b[r];
693        } else
694        {
695          bb = b;
696        }
697
698        M[j] = (lcm(aa, bb) / aa);
699      }
700    }
701   
702    // TODO: add quotient relations here...
703
704    M = simplify(M, 1 + 2 + 32);
705
706    iv_ds = sort(M, "ds", 1)[2]; // ,1 => reversed!
707
708    M = M[iv_ds];
709   
710    S = S, M * gen(i);
711  }
712
713  S = simplify(S, 2);
714
715  S = sort(S, "ds", 1)[1]; // ,1 => reversed! // TODO: not needed?
716 
717  if( @DEBUG )
718  {
719    "SSComputeLeadingSyzygyTerms::Output: ";
720    S;
721  } 
722
723  attrib(S, "isSB", 1);
724
725  return (S);
726}
727
728/// Compute Syz(L), where L is a monomial (leading) module
729proc SSCompute2LeadingSyzygyTerms(def L, int @TAILREDSYZ)
730{
731  if( typeof( attrib(basering, "DEBUG") ) == "int" )
732  {
733    int @DEBUG = attrib(basering, "DEBUG");
734  } else
735  {
736    int @DEBUG = !system("with", "ndebug");
737  }
738
739  if( typeof( attrib(basering, "SYZCHECK") ) == "int" )
740  {
741    int @SYZCHECK = attrib(basering, "SYZCHECK");
742  } else
743  {
744    int @SYZCHECK = @DEBUG;
745  }
746 
747
748  if( @DEBUG )
749  {
750    "SSCompute2LeadingSyzygyTerms::Input: ";
751    L;
752    "@TAILREDSYZ: ", @TAILREDSYZ;
753  }
754
755  int i, j, r;
756  int N = ncols(L);
757  def a, b;
758
759  poly aa, bb, @lcm;
760
761  bigint c;
762
763  module M;
764
765  module S = 0;
766
767  for(i = 1; i <= N; i++)
768  {
769    a = L[i];
770//    "a: ", a;
771    c = leadcomp(a);
772    r = int(c);
773
774    aa = leadmonomial(a);
775
776    M = 0;
777
778    for(j = i-1; j > 0; j--)
779    {
780      b = L[j];
781//      "b: ", b;
782
783      if( leadcomp(b) == c )
784      {
785        bb = leadmonomial(b);
786        @lcm = lcm(aa, bb);
787
788        M[j] = (@lcm / aa)* gen(i) - (@lcm / bb)* gen(j);
789      }
790    }
791   
792    M = simplify(M, 2);
793
794    // TODO: add quotient relations here...
795    S = S, M;
796  }
797
798  if( @TAILREDSYZ )
799  {
800    // Make sure that 2nd syzygy terms are not reducible by 1st
801    def opts = option(get);
802    option(redSB); option(redTail);
803    S = std(S); // binomial module
804    option(set, opts);
805    //  kill opts;
806  } else
807  {
808    S = simplify(S, 2 + 32);
809  }
810
811  S = sort(S, "ds", 1)[1]; // ,1 => reversed!
812
813  if( @DEBUG )
814  {
815    "SSCompute2LeadingSyzygyTerms::Syz(LEAD): "; S;
816  }
817
818  if( @SYZCHECK )
819  {
820    if( size(S) > 0 and size(L) > 0 )
821    {
822      if( size(module(transpose( transpose(S) * transpose(L) ))) > 0 )
823      {
824        transpose( transpose(S) * transpose(L) );
825        "ERROR: transpose( transpose(S) * transpose(L) ) != 0!!!";
826        $
827      }
828    }
829  }
830
831  module S2 = Tail(S);
832  S = lead(S); // (C,lp) on base ring!
833             
834  if( @DEBUG )
835  {
836    "SSCompute2LeadingSyzygyTerms::Output: "; S; S2;
837  } 
838 
839  attrib(S, "isSB", 1);
840
841  return (S, S2);
842}
843
844// -------------------------------------------------------- //
845
846/// TODO: save shortcut LM(m) * "t" -> ?
847proc SSReduceTerm(poly m, def t, def L, def T, list #)
848{
849  if( typeof( attrib(basering, "DEBUG") ) == "int" )
850  {
851    int @DEBUG = attrib(basering, "DEBUG");
852  } else
853  {
854    int @DEBUG = !system("with", "ndebug");
855  }
856
857  if( @DEBUG )
858  {
859    "SSReduce::Input: ";
860
861    "mult: ", m;
862    "term: ", t;
863    "L: ", L;
864    "T: ", T;
865    if( size(#) > 0 )
866    {
867      "LSyz: ", #;
868    }
869//    "attrib(LS, 'isSB')", attrib(LS, "isSB");
870  }
871 
872  vector s = 0;
873
874  if( t == 0 )
875  {
876    return (s);
877  }
878
879  def product = m * t;
880
881  bigint c = leadcomp(t);
882  int r = int(c);
883 
884  def a, b, nf, bb;
885
886  // looking for an appropriate reducer
887  for( int k = ncols(L); k > 0; k-- )
888  {
889    a = L[k];
890    // with the same mod. component
891    if( leadcomp(a) == c )
892    {
893      b = - (leadmonomial(product) / leadmonomial(L[k]));
894     
895      // which divides the product
896      if( b != 0 )
897      {
898//        "b: ", b;
899        bb = b * gen(k);
900        nf = bb;
901
902        if( size(#) > 0 )
903        {
904          if( typeof(#[1]) == "module" )
905          {
906            nf = NF(bb, #[1]);
907//        "NF: ", nf;
908          }
909        }
910
911        // while the complement (the fraction) is not reducible by leading syzygies
912        if( nf != 0 )
913        {
914          /// TODO: save shortcut LM(m) * T[i] -> ?
915
916          // choose ANY such reduction... (with the biggest index?)
917          s = bb + SSTraverseTail(b, T[k], L, T, #);
918          break;
919        }
920      }
921    }
922  } 
923  if( @DEBUG )
924  {
925    "SSReduceTerm::Output: ", s;
926  }
927  return (s);
928}
929
930// TODO: store m * @tail -.-^-.-^-.--> ?
931proc SSTraverseTail(poly m, def @tail, def L, def T, list #)
932{
933  if( typeof( attrib(basering, "DEBUG") ) == "int" )
934  {
935    int @DEBUG = attrib(basering, "DEBUG");
936  } else
937  {
938    int @DEBUG = !system("with", "ndebug");
939  }
940
941  if( @DEBUG )
942  {
943    "SSTraverse::Input: ";
944
945    "mult: ", m;
946    "tail: ", @tail; // T[i];
947
948    if( size(#) > 0 )
949    {
950      "LSyz: "; #[1];
951    }
952  }
953
954  vector s = 0;
955
956  def @l;
957
958  // iterate tail-terms in ANY order!
959  while( size(@tail) > 0 )
960  {
961    @l = lead(@tail);
962    s = s + SSReduceTerm(m, @l, L, T, #);
963    @tail = @tail - @l;
964  }
965
966  if( @DEBUG )
967  {
968    "SSTraverseTail::Output: ", s;
969  }
970  return (s);
971}
972
973// -------------------------------------------------------- //
974
975// module (N, LL, TT) = SSComputeSyzygy(L, T);
976// Compute Syz(L ++ T) = N = LL ++ TT
977proc SSComputeSyzygy(def L, def T)
978{
979  if( typeof( attrib(basering, "DEBUG") ) == "int" )
980  {
981    int @DEBUG = attrib(basering, "DEBUG");
982  } else
983  {
984    int @DEBUG = !system("with", "ndebug");
985  }
986 
987  if( @DEBUG )
988  {
989    "SSComputeSyzygy::Input";
990    "basering: ", basering; attrib(basering);
991//    DetailedPrint(basering);
992
993//    "iCompShift: ", iCompShift;
994
995    "L: "; L;
996    "T: "; T;
997  }
998
999  def a; bigint c; int r, k; poly aa;
1000
1001  int @LEAD2SYZ = 0;
1002  if( typeof( attrib(basering, "LEAD2SYZ") ) == "int" )
1003  {
1004    @LEAD2SYZ = attrib(basering, "LEAD2SYZ");
1005  }
1006
1007  int @TAILREDSYZ = 1;
1008  if( typeof( attrib(basering, "TAILREDSYZ") ) == "int" )
1009  {
1010    @TAILREDSYZ = attrib(basering, "TAILREDSYZ");
1011//    @TAILREDSYZ;
1012  }
1013 
1014  /// Get the critical leading syzygy terms
1015  if( @LEAD2SYZ ) // & 2nd syz. term
1016  {
1017    def a2; int r2; poly aa2; 
1018    module LL, LL2;
1019    (LL, LL2) = SSCompute2LeadingSyzygyTerms(L, @TAILREDSYZ); // ++
1020  } else
1021  {
1022    module LL = SSComputeLeadingSyzygyTerms(L);
1023  }
1024
1025  module TT, SYZ;
1026
1027  if( size(LL) > 0 )
1028  {
1029    list LS;
1030
1031    if( @TAILREDSYZ )
1032    {
1033      LS = list(LL);
1034    }
1035   
1036    vector @tail;
1037
1038    for(k = ncols(LL); k > 0; k-- )
1039    {
1040      // leading syz. term:
1041      a = LL[k]; c = leadcomp(a); r = int(c); aa = leadmonomial(a);
1042      //    "A: ", a, " --->>>> ", aa, " **** [", r, "]: ";
1043
1044      /// TODO: save shortcut (aa) * T[r] -> ?
1045      @tail = SSTraverseTail(aa, T[r], L, T, LS);
1046             
1047      // get the 2nd syzygy term...
1048     
1049      if( @LEAD2SYZ ) // with the 2nd syz. term:
1050      {     
1051        a2 = LL2[k]; c = leadcomp(a2); r2 = int(c); aa2 = leadmonomial(a2);
1052        @tail = @tail +
1053             /// TODO: save shortcut (aa2) * T[r2] -> ?
1054             a2 + SSTraverseTail(aa2, T[r2], L, T, LS);
1055      } else
1056      {
1057        @tail = @tail + SSReduceTerm(aa, L[r], L, T, LS);
1058      }
1059     
1060     
1061      TT[k] = @tail;
1062      SYZ[k] = a + @tail;
1063    }
1064  }
1065
1066/*
1067  def opts = option(get); option(redSB); option(redTail);
1068  module SYZ = std(syz(M));
1069  option(set, opts); kill opts;
1070 
1071  module LL = lead(SYZ); // TODO: WRONG ORDERING!!!!!!!!
1072  module TT = Tail(SYZ);
1073*/
1074 
1075  if( @DEBUG )
1076  {
1077    "SSComputeSyzygy::Output";
1078
1079    "SYZ: "; SYZ;
1080    "LL: "; LL;
1081    "TT: "; TT;
1082  }
1083
1084  return (SYZ, LL, TT);
1085}
1086
1087// resolution/syzygy step:
1088static proc SSstep()
1089{
1090  if( typeof( attrib(basering, "DEBUG") ) == "int" )
1091  {
1092    int @DEBUG = attrib(basering, "DEBUG");
1093  } else
1094  {
1095    int @DEBUG = !system("with", "ndebug");
1096  }
1097
1098
1099  if( typeof( attrib(basering, "SYZCHECK") ) == "int" )
1100  {
1101    int @SYZCHECK = attrib(basering, "SYZCHECK");
1102  } else
1103  {
1104    int @SYZCHECK = @DEBUG;
1105  }
1106
1107  if( @DEBUG )
1108  {
1109    "SSstep::NextInducedRing";
1110    "basering: ", basering; attrib(basering);
1111  }
1112
1113/*
1114  // is initial weights are all zeroes!
1115  def L =  lead(M);
1116  intvec @V = deg(M[1..ncols(M)]);  @W;  @V;  @W = @V;  attrib(L, "isHomog", @W); 
1117  SetInducedReferrence(L, @RANK, 0);
1118*/
1119
1120//  def L =  lead(MRES);
1121//  @W = @W, @V;
1122//  attrib(L, "isHomog", @W); 
1123
1124
1125  // General setting:
1126//  SetInducedReferrence(MRES, 0, 0); // limit: 0!
1127  int @l = size(RES);
1128
1129  def M =  RES[@l];
1130
1131  def L = LRES[@l];
1132  def T = TRES[@l];
1133
1134
1135  //// TODO: wrong !!!!!
1136  int @RANK = ncols(MRES) - ncols(M); // nrows(M); // what if M is zero?!
1137
1138 
1139
1140/*
1141  if( @RANK !=  nrows(M) )
1142  {
1143    type(MRES);
1144    @RANK;
1145    type(M);
1146    pause();
1147  }
1148*/
1149 
1150  intvec @W = attrib(M, "isHomog"); intvec @V = attrib(M, "degrees"); @V = @W, @V;
1151   
1152  if( @DEBUG )
1153  {
1154    "Sstep::NextInput: ";
1155    M;
1156    L;
1157    @V;
1158    @RANK;
1159//    DetailedPrint(MRES);
1160    attrib(MRES, "isHomog");
1161  }
1162
1163     
1164  // TODO: N  = SYZ( M )!!!
1165  module N, LL, TT;
1166  (N, LL, TT) = SSComputeSyzygy(/*M, */L, T/*, @RANK*/);
1167
1168  // shift syz.comp by @RANK:
1169  module Z;
1170  Z = 0; Z[@RANK] = 0; Z = Z, transpose(LL);   LL = transpose(Z);
1171  Z = 0; Z[@RANK] = 0; Z = Z, transpose(TT);   TT = transpose(Z);
1172  Z = 0; Z[@RANK] = 0; Z = Z, transpose(N);     N = transpose(Z);
1173
1174
1175  if( @SYZCHECK )
1176  {
1177    if( size(N) > 0 )
1178    {
1179      // next syz. property
1180      if( size(module(transpose( transpose(N) * transpose(MRES) ))) > 0 )
1181      {
1182        "MRES", MRES;
1183
1184        "N: "; N; // DetailedPrint(N, 2);
1185
1186        "LL:"; LL; // DetailedPrint(LL, 1);
1187        "TT:"; TT; // DetailedPrint(TT, 10);
1188
1189        "RANKS: ", @RANK;
1190
1191        "transpose( transpose(N) * transpose(MRES) ) != 0!!!";
1192        transpose( transpose(N) * transpose(MRES) );
1193
1194        "transpose(N) * transpose(MRES): ";
1195        transpose(N) * transpose(MRES);
1196        // DetailedPrint(module(_), 2);
1197        $
1198      }
1199    }
1200  }
1201
1202  attrib(N, "isHomog", @V);
1203
1204  // TODO: correct the following:
1205  intvec @DEGS = deg(N[1..ncols(N)]); // no mod. comp. weights :(
1206
1207 
1208  attrib(N, "degrees", @DEGS);
1209 
1210   RES[@l + 1] = N; // list of all syzygy modules
1211  LRES[@l + 1] = LL; // list of all syzygy modules
1212  TRES[@l + 1] = TT; // list of all syzygy modules
1213
1214  MRES = MRES, N;
1215 
1216  attrib(MRES, "isHomog", @V);
1217
1218//  L = L, lead(N);  attrib(basering, "InducionLeads", L);
1219
1220  if( @DEBUG )
1221  {
1222    "SSstep::NextSyzOutput: ";
1223    N;
1224//    DetailedPrint(N);
1225    attrib(N);
1226  }
1227
1228}
1229
1230proc SScontinue(int l)
1231"USAGE:  SScontinue(l)
1232RETURN:  nothing, instead it changes RES and MRES variables in the current ring
1233PURPOSE: computes further (at most l) syzygies
1234NOTE:    must be used within a ring returned by Sres or Ssyz. RES and MRES are
1235         explained in Sres
1236EXAMPLE: example Scontinue; shows an example
1237"
1238{
1239
1240  /// TODO!
1241//  def data = GetInducedData();
1242
1243  if( (!defined(RES)) || (!defined(MRES)) ) /* || (typeof(data) != "list") || (size(data) != 2) */
1244  {
1245    ERROR("Sorry, but basering does not seem to be returned by Sres or Ssyz");
1246  }
1247  for (;  (l != 0) && (size(RES[size(RES)]) > 0); l-- )
1248  {
1249    SSstep();
1250  }
1251}
1252example
1253{ "EXAMPLE:"; echo = 2;
1254  ring r;
1255  module M = maxideal(1); M;
1256  def S = SSsyz(M); setring S; S;
1257  "Only the first syzygy: ";
1258  RES; MRES;
1259  "More syzygies: ";
1260  SScontinue(10);
1261  RES; MRES;
1262}
1263
1264proc SSsyz(def M)
1265"USAGE:  SSsyz(M)
1266RETURN:  ring, containing a list of modules RES and a module MRES
1267PURPOSE: computes the first syzygy module of M (wrt some Schreyer ordering)?
1268NOTE:    The output is explained in Sres
1269EXAMPLE: example Ssyz; shows an example
1270"
1271{
1272  if( (typeof(M) != "module") && (typeof(M) != "ideal") )
1273  {
1274    ERROR("Sorry: need an ideal or a module for input");
1275  }
1276
1277  def SS = SSinit(M); setring SS;
1278 
1279  SSstep(); // NOTE: what if M is zero?
1280
1281  return (SS);
1282}
1283example
1284{ "EXAMPLE:"; echo = 2;
1285  ring r;
1286
1287/*  ideal M = 0;
1288  def S = SSsyz(M); setring S; S;
1289  "Only the first syzygy: ";
1290  RES; LRES; TRES;
1291  MRES;
1292 
1293  kill S; setring r; kill M;
1294*/ 
1295
1296  module M = maxideal(1); M;
1297  def S = SSres(M, 0); setring S; S;
1298  MRES;
1299  RES;
1300  "";
1301  LRES;
1302  "";
1303  TRES;
1304
1305  kill S; setring r; kill M;
1306
1307  kill r;
1308 
1309  ring R = 0, (w, x, y, z), dp;
1310  ideal M = w^2 - x*z,  w*x - y*z,  x^2 - w*y, x*y - z^2, y^2 - w*z;
1311 
1312  def S = SSres(M, 0); setring S; S;
1313  MRES;
1314  RES;
1315  "";
1316  LRES;
1317  "";
1318  TRES;
1319}
1320
1321proc SSres(def M, int l)
1322"USAGE:  SSres(I, l)
1323RETURN:  ring, containing a list of modules RES and a module MRES
1324PURPOSE: computes (at most l) syzygy modules of M wrt the classical Schreyer
1325         induced ordering with gen(i) > gen(j) if i > j, provided both gens
1326         are from the same syzygy level.???
1327NOTE:    RES contains the images of maps subsituting the beginning of the
1328         Schreyer free resolution of baseRing^r/M, while MRES is a sum of
1329         these images in a big free sum, containing all the syzygy modules.
1330         The syzygy modules are shifted so that gen(i) correspons to MRES[i].
1331         The leading zero module RES[0] indicates the fact that coker of the
1332         first map is zero. The number of zeroes inducates the rank of input.
1333NOTE:    If l == 0 then l is set to be nvars(basering) + 1
1334EXAMPLE: example SSres; shows an example
1335"
1336{
1337  if( (typeof(M) != "module") && (typeof(M) != "ideal") )
1338  {
1339    ERROR("Sorry: need an ideal or a module for input");
1340  }
1341
1342  def SS = SSinit(M); setring SS;
1343
1344  if (l == 0)
1345  {
1346    l = nvars(basering) + 1; // not really an estimate...?!
1347  }
1348
1349  SSstep(); l = l - 1;
1350
1351  SScontinue(l);
1352
1353  return (SS);
1354}
1355example
1356{ "EXAMPLE:"; echo = 2;
1357  ring r;
1358  module M = maxideal(1); M;
1359  def S = SSres(M, 0); setring S; S;
1360  RES;
1361  MRES;
1362  kill S;
1363  setring r; kill M;
1364
1365  def A = nc_algebra(-1,0); setring A;
1366  ideal Q = var(1)^2, var(2)^2, var(3)^2;
1367  qring SCA = twostd(Q);
1368  basering;
1369
1370  module M = maxideal(1);
1371  def S = SSres(M, 2); setring S; S;
1372  RES;
1373  MRES;
1374}
1375
1376
1377
1378static proc loadme()
1379{
1380  int @DEBUG = !system("with", "ndebug");
1381
1382  if( @DEBUG )
1383  {
1384   
1385    "ndebug?: ", system("with", "ndebug");
1386    "om_ndebug?: ", system("with", "om_ndebug");
1387
1388    listvar(Top);
1389    listvar(Schreyer);
1390  }
1391//  listvar(Syzextra); listvar(Syzextra_g);
1392
1393  if( !defined(DetailedPrint) )
1394  {
1395    if( !@DEBUG )
1396    {
1397
1398      if( @DEBUG )
1399      {
1400        "Loading the Release version!";
1401      }
1402      load("syzextra.so");
1403
1404      if( @DEBUG )
1405      {
1406        listvar(Syzextra);
1407      }
1408
1409      exportto(Top, Syzextra::ClearContent);
1410      exportto(Top, Syzextra::ClearDenominators);
1411     
1412//      export Syzextra;
1413
1414//      exportto(Schreyer, Syzextra::noop);
1415      exportto(Schreyer, Syzextra::DetailedPrint);
1416      exportto(Schreyer, Syzextra::leadmonomial);
1417      exportto(Schreyer, Syzextra::leadcomp);
1418//      exportto(Schreyer, Syzextra::leadrawexp);
1419//      exportto(Schreyer, Syzextra::ISUpdateComponents);
1420      exportto(Schreyer, Syzextra::SetInducedReferrence);
1421      exportto(Schreyer, Syzextra::GetInducedData);
1422//      exportto(Schreyer, Syzextra::GetAMData);
1423//      exportto(Schreyer, Syzextra::SetSyzComp);
1424      exportto(Schreyer, Syzextra::MakeInducedSchreyerOrdering);
1425//      exportto(Schreyer, Syzextra::MakeSyzCompOrdering);
1426      exportto(Schreyer, Syzextra::idPrepare);
1427//      exportto(Schreyer, Syzextra::reduce_syz);
1428//      exportto(Schreyer, Syzextra::p_Content);
1429
1430      exportto(Schreyer, Syzextra::ProfilerStart); exportto(Schreyer, Syzextra::ProfilerStop);
1431
1432      exportto(Schreyer, Syzextra::Tail);
1433
1434      exportto(Schreyer, Syzextra::m2_end);
1435    }
1436    else
1437    {
1438      if( @DEBUG )
1439      {
1440        "Loading the Debug version!";
1441      }
1442
1443      load("syzextra_g.so");
1444
1445      if( @DEBUG )
1446      {     
1447        listvar(Syzextra_g);
1448      }
1449     
1450      exportto(Top, Syzextra_g::ClearContent);
1451      exportto(Top, Syzextra_g::ClearDenominators);
1452
1453//      export Syzextra_g;
1454//      exportto(Schreyer, Syzextra_g::noop);
1455      exportto(Schreyer, Syzextra_g::DetailedPrint);
1456      exportto(Schreyer, Syzextra_g::leadmonomial);
1457      exportto(Schreyer, Syzextra_g::leadcomp);
1458//      exportto(Schreyer, Syzextra_g::leadrawexp);
1459//      exportto(Schreyer, Syzextra_g::ISUpdateComponents);
1460      exportto(Schreyer, Syzextra_g::SetInducedReferrence);
1461      exportto(Schreyer, Syzextra_g::GetInducedData);
1462//      exportto(Schreyer, Syzextra_g::GetAMData);
1463//      exportto(Schreyer, Syzextra_g::SetSyzComp);
1464      exportto(Schreyer, Syzextra_g::MakeInducedSchreyerOrdering);
1465//      exportto(Schreyer, Syzextra_g::MakeSyzCompOrdering);
1466      exportto(Schreyer, Syzextra_g::idPrepare);
1467//      exportto(Schreyer, Syzextra_g::reduce_syz);
1468//      exportto(Schreyer, Syzextra_g::p_Content);
1469
1470      exportto(Schreyer, Syzextra_g::ProfilerStart); exportto(Schreyer, Syzextra_g::ProfilerStop);
1471
1472      exportto(Schreyer, Syzextra_g::Tail);
1473     
1474     
1475      exportto(Schreyer, Syzextra_g::m2_end);
1476    }
1477
1478    exportto(Top, DetailedPrint);
1479    exportto(Top, GetInducedData);
1480
1481    if( @DEBUG )
1482    {
1483      listvar(Top);
1484      listvar(Schreyer);
1485    }
1486  }
1487 
1488  if( !defined(GetInducedData) )
1489  {
1490    ERROR("Sorry but we are missing the dynamic module (syzextra(_g)?.so)...");
1491  }
1492
1493}
1494
1495static proc mod_init()
1496{
1497  loadme();
1498}
1499
1500
1501proc testallSexamples()
1502{
1503  example Ssyz;
1504  example Scontinue;
1505  example Sres; 
1506}
1507
1508proc testallSSexamples()
1509{
1510  example SSsyz;
1511  example SScontinue;
1512  example SSres; 
1513}
1514
1515example
1516{ "EXAMPLE:"; echo = 2;
1517  testallSexamples();
1518  testallSSexamples();
1519}
Note: See TracBrowser for help on using the repository browser.