source: git/Singular/LIB/gitfan.lib @ dc8eb2

spielwiese
Last change on this file since dc8eb2 was 3686937, checked in by Oleksandr Motsak <motsak@…>, 11 years ago
Added '$Id$' as a comment to all libs (LIB/*.lib)
  • Property mode set to 100644
File size: 14.0 KB
Line 
1///////////////////////////////////////////////////////////////////
2version="version gitfan.lib 4.0.0.0 Jun_2013 "; // $Id$
3category="Algebraic Geometry";
4info="
5LIBRARY:  gitfan.lib       Compute GIT-fans.
6
7AUTHORS:  Janko Boehm      boehm@mathematik.uni-kl.de
8@*        Simon Keicher    keicher@mail.mathematik.uni-tuebingen.de
9@*        Yue Ren          ren@mathematik.uni-kl.de
10
11OVERVIEW:
12This library computes GIT-fans, torus orbits and GKZ-fans.
13It uses the package 'gfanlib' by Anders N. Jensen
14and some algorithms have been outsourced to C++ to improve the performance.
15Check https://github.com/skeicher/gitfan_singular for updates.
16
17KEYWORDS: library; gitfan; GIT; geometric invariant theory; quotients
18
19PROCEDURES:
20afaces(ideal);                      Returns a list of intvecs that correspond to all a-faces
21gitCone(ideal,bigintmat,bigintmat); Returns the GIT-cone around the given weight vector w
22gitFan(ideal,bigintmat);            Returns the GIT-fan of the H-action defined by Q on V(a)
23gkzFan(bigintmat);                  Returns the GKZ-fan of the matrix Q
24isAface(ideal,intvec);              Checks whether intvec corresponds to an ideal-face
25orbitCones(ideal,bigintmat);        Returns the list of all projected a-faces
26";
27
28LIB "parallel.lib"; // for parallelWaitAll
29LIB "general.lib";
30
31////////////////////////////////////////////////////
32
33proc int2face(int n, int r)
34{
35  int k = r-1;
36  intvec v;
37  int n0 = n;
38
39  while(n0 > 0){
40    while(2^k > n0){
41      k--;
42    }
43
44    v = k+1,v;
45    n0 = n0 - 2^k;
46    k--;
47  }
48  v = v[1..size(v)-1];
49  return(v);
50}
51
52/////////////////////////////////
53
54proc isAface(ideal a, intvec gam0, int n)
55"USAGE:  isAface(a,gam0); a: ideal, gam0:intvec
56PURPOSE: Checks whether the face of the positive orthant,
57         that is spanned by all i-th unit vectors,
58         where i ranges amongst the entries of gam0,
59         is an a-face.
60RETURN:  int
61EXAMPLE: example isaface; shows an example
62"
63{
64  // special case: gam0 is the zero-cone:
65  if (size(gam0) == 1 and gam0[1] == 0){
66    poly pz; ideal G;
67
68    // is an a-face if and only if RL0(0,...,0) = const
69    // set all entries to 0:
70    int i;
71    for (int k = 1; k <= size(a); k++) {
72      pz = subst(a[k], var(1), 0);
73      for (i = 2; i <= nvars(basering); i++) {
74        pz = subst(pz, var(i), 0);
75      }
76      G = G, pz;
77    }
78
79    G = std(G);
80
81    // monomial inside?:
82    if(1 == G){
83      return(0);
84    }
85
86    return(1);
87  }
88
89  // ring is too big: Switch to KK[T_i | e_i\in gam0] instead:
90  intvec w=ringlist(basering)[3][1][2];
91  intvec w0;
92  string initNewRing = "ring Rgam0 = 0,(";
93
94  for (int i=1; i<size(gam0); i++){
95    initNewRing = initNewRing + string(var(gam0[i])) + ",";
96    w0[i]=w[gam0[i]];
97  }
98
99  w0 = w0,w[gam0[i]],1;
100  initNewRing = initNewRing + string(var(gam0[size(gam0)])) + ",U),Wp("+string(w0)+");";
101  def R = basering;
102  execute(initNewRing);
103
104  ideal agam0 = imap(R,a);
105
106  for (i = 1; i<=size(agam0); i=i+1)
107  {
108    if (size(agam0[i]) == 1)
109    { return(0,0); }
110  }
111
112  poly p = var(1); // first entry of g; p = prod T_i with i element of g
113  for ( i = 2; i <= nvars(basering); i++ ) {
114      p = p * var(i);
115    }
116  // p is now the product over all T_i, with e_i in gam0
117
118  agam0 = agam0, p - 1; // rad-membership
119  agam0 = timeStd(agam0,5);
120  // "timestd finished after: "+string(timer-t);
121  // int timeout = 0;
122  if (attrib(agam0,"isSB") < 1)
123  {
124    kill agam0; kill Rgam0; kill initNewRing; kill w; kill w0; setring R; kill R;
125    return(0,1);
126    // // "timestd failed in "+string(gam0)+", falling back to saturation!";
127    // setring R; kill Rgam0;
128
129    // initNewRing = "ring Rgam0 = 0,(";
130
131    // w0 = 0;
132    // for (i=1; i<size(gam0); i++){
133    //   initNewRing = initNewRing + string(var(gam0[i])) + ",";
134    //   w0[i]=w[gam0[i]];
135    // }
136
137    // w0 = w0,w[gam0[i]];
138    // initNewRing = initNewRing + string(var(gam0[size(gam0)])) + "),Wp("+string(w0)+");";
139    // execute(initNewRing);
140
141    // ideal G = imap(R,a);
142
143    // timeout = 1;
144    // int t=rtimer;
145    // for(int k=nvars(basering); k>0; k--) { G=sat(G,var(k))[1]; }
146    // t = (rtimer - t) div 1000;
147    // string(n)+": saturation successful after "+string(t)+" with: "+string(G<>1);
148  }
149
150  // does G contain 1?, i.e. is G = 1?
151  if(agam0 <> 1) {
152    kill agam0; kill Rgam0; kill initNewRing; kill w; kill w0; setring R; kill R;
153    return(1,0); // true
154  }
155
156  kill agam0; kill Rgam0; kill initNewRing; kill w; kill w0; setring R; kill R;
157  return(0,0); // false
158}
159example
160{
161  echo = 2;
162
163  ring R = 0,(T(1..4)),dp;
164  ideal I = T(1)*T(2)-T(4);
165
166  intvec w = 1,4;
167  intvec v = 1,2,4;
168
169  isAface(I,w); // should be 0
170  "-----------";
171  isAface(I,v); // should be 1
172}
173
174
175proc isAfaceNonZero(ideal a, intvec gam0)
176{
177  string initNewRing = "ring Rgam0 = 0,(";
178  for (int i=1; i<size(gam0); i++)
179    { initNewRing = initNewRing + string(var(gam0[i])) + ","; }
180  initNewRing = initNewRing + string(var(gam0[size(gam0)])) + "),dp;";
181  def R = basering;
182  execute(initNewRing);
183
184  ideal agam0 = imap(R,a);
185
186  for ( i = 1; i<=size(agam0); i=i+1)
187    { if (size(agam0[i]) == 1) { return(0); } }
188
189  poly p = var(1);
190  for ( i = 2; i <= nvars(basering); i++ )
191    { p = p * var(i); }
192
193  agam0 = agam0, p - 1;
194  ideal G = std(agam0);
195
196  if(G <> 1)
197    { return(1); }
198
199  return(0);
200}
201////////////////////////////////////////////////////
202
203proc afacesPart(ideal a, int d, int start, int end, int r){
204  intvec gam0;
205  int i;
206  list AF;
207
208  for(i = start; i <= end; i=i+1){
209    if(i < 2^r){
210      string(i)+"    "+string(size(AF));
211      gam0 = int2face(i,r);
212
213      // take gam0 only if it has
214      // at least d rays:
215      if(size(gam0) >= d){
216        if (isAface(a,gam0)){
217          AF[size(AF) + 1] = gam0;
218        }
219      }
220    }
221  }
222
223  return(AF);
224}
225
226////////////////////////////////////////////////////
227
228proc afaces(ideal a, list #)
229"USAGE:  afaces(a, b, c); a: ideal, b: int, c: int
230PURPOSE: Returns a list of all a-faces (represented by intvecs).
231         Moreover, it is possible to specify a dimensional bound b,
232         upon which only cones of that dimension and above are returned.
233         Lastly, as the computation is parallizable, one can specify c,
234         the number of cores to be used by the computation.
235RETURN:  a list of intvecs
236EXAMPLE: example afaces; shows an example
237"
238{
239  int d = 1;
240  int ncores = 1;
241
242  if ((size(#) > 0) and (typeof(#[1]) == "int")){
243    d = #[1];
244  }
245
246  if ((size(#) > 1) and (typeof(#[2]) == "int")){
247    ncores = #[2];
248  }
249
250  list AF;
251  intvec gam0;
252  int r = nvars(basering);
253
254  // check if 0 is an a-face:
255  gam0 = 0;
256  if (isAface(a,gam0)){
257      AF[size(AF) + 1] = gam0;
258  }
259
260  // check for other a-faces:
261  // make ncores processes:
262  int step = 2^r div ncores;
263  int i;
264
265  list args;
266  for(int k = 0; k < ncores; k++){
267    args[size(args) + 1] = list(a, d, k * step + 1, (k+1) * step, r);
268  }
269
270  string command = "afacesPart";
271  list out = parallelWaitAll(command, args);
272
273  // do remaining ones:
274  for(i = ncores * step +1; i < 2^r; i=i+1){
275    "another one needed";
276    gam0 = int2face(i,r);
277
278    // take gam0 only if it has
279    // at least d rays:
280    if(size(gam0) >= d){
281      if (isAface(a,gam0)){
282        AF[size(AF) + 1] = gam0;
283      }
284    }
285  }
286
287  int l;
288  // read out afaces of out into AF:
289  for(l = 1; l <= size(out); l++){
290    AF = AF + out[l];
291  }
292
293  return(AF);
294}
295example
296{
297
298  echo = 2;
299  ring R = 0,T(1..3),dp;
300  ideal a = T(1)+T(2)+T(3);
301
302  list F = afaces(a,3,4);
303  print(F);
304  print(size(F));
305
306  // 2nd ex //
307  ring R2 = 0,T(1..3),dp;
308  ideal a2 = T(2)^2*T(3)^2+T(1)*T(3);
309
310  list F2 = afaces(a2,3,4);
311  print(F2);
312  print(size(F2));
313
314  // 3rd ex //
315  ring R3 = 0,T(1..3),dp;
316  ideal a3 = 0;
317
318  list F3 = afaces(a3,3,4);
319  print(F3);
320  print(size(F3));
321
322  // bigger example //
323  ring R = 0,T(1..15),dp;
324  ideal a =
325    T(1)*T(10)-T(2)*T(7)+T(3)*T(6),
326    T(1)*T(11)-T(2)*T(8)+T(4)*T(6),
327    T(1)*T(12)-T(2)*T(9)+T(5)*T(6),
328    T(1)*T(13)-T(3)*T(8)+T(4)*T(7),
329    T(1)*T(14)-T(3)*T(9)+T(5)*T(7),
330    T(1)*T(15)-T(4)*T(9)+T(5)*T(8),
331    T(2)*T(13)-T(3)*T(11)+T(4)*T(10),
332    T(2)*T(14)-T(3)*T(12)+T(5)*T(10),
333    T(2)*T(15)-T(4)*T(12)+T(5)*T(11),
334    T(3)*T(15)-T(4)*T(14)+T(5)*T(13),
335    T(6)*T(13)-T(7)*T(11)+T(8)*T(10),
336    T(6)*T(14)-T(7)*T(12)+T(9)*T(10),
337    T(6)*T(15)-T(8)*T(12)+T(9)*T(11),
338    T(7)*T(15)-T(8)*T(14)+T(9)*T(13),
339    T(10)*T(15)-T(11)*T(14)+T(12)*T(13);
340
341  int t = timer;
342  list F4 = afaces(a,0,2);
343  print(size(F4));
344  timer - t;
345
346  int t = timer;
347  list F4 = afaces(a,0);
348  print(size(F4));
349  timer - t;
350
351}
352
353///////////////////////////////////////
354
355proc orbitCones(ideal a, bigintmat Q, list #)
356"USAGE:  orbitCones(a, Q, b, c); a: ideal, Q: bigintmat, b: int, c: int
357PURPOSE: Returns a list consisting of all cones Q(gam0) where gam0 is an a-face.
358         Moreover, it is possible to specify a dimensional bound b,
359         upon which only cones of that dimension and above are returned.
360         Lastly, as the computation is parallizable, one can specify c,
361         the number of cores to be used by the computation.
362RETURN:  a list of cones
363EXAMPLE: example orbitCones; shows an example
364"
365{
366  list AF;
367
368  if((size(#) > 1) and (typeof(#[2]) == "int")){
369    AF = afaces(a, nrows(Q), #[2]);
370  } else
371  {
372    AF = afaces(a, nrows(Q));
373  }
374
375  int dimensionBound = 0;
376  if((size(#) > 0) and (typeof(#[1]) == "int")){
377    dimensionBound = #[1];
378  }
379
380  list OC;
381  intvec gam0;
382  int j;
383
384  for(int i = 1; i <= size(AF); i++){
385    gam0 = AF[i];
386
387    if(gam0 == 0){
388      bigintmat M[1][nrows(Q)];
389    } else {
390      bigintmat M[size(gam0)][nrows(Q)];
391      for (j = 1; j <= size(gam0); j++){
392        M[j,1..ncols(M)] = Q[1..nrows(Q),gam0[j]];
393      }
394    }
395    cone c = coneViaPoints(M);
396
397    if((dimension(c) >= dimensionBound) and (!(listContainsCone(OC, c)))){
398      OC[size(OC)+1] = c;
399    }
400
401    kill M, c;
402  }
403
404  return(OC);
405}
406example
407{
408  echo=2;
409  intmat Q[3][4] =
410    1,0,1,0,
411    0,1,0,1,
412    0,0,1,1;
413
414  ring R = 0,T(1..4),dp;
415  ideal a = 0;
416
417  orbitCones(a, Q);
418}
419
420///////////////////////////////////////
421
422proc gitCone(ideal a, bigintmat Q, bigintmat w)
423"USAGE: gitCone(a, Q, w); a: ideal, Q:bigintmat, w:bigintmat
424PURPOSE: Returns the GIT-cone lambda(w), i.e. the intersection of all
425orbit cones containing the vector w.
426NOTE: call this only if you are interested in a single GIT-cone.
427RETURN: a cone.
428EXAMPLE: example gitCone; shows an example
429"
430{
431  list OC =  orbitCones(a, Q);
432  cone lambda = nrows(Q);
433
434  for(int i = 1; i <= size(OC); i++){
435    cone c = OC[i];
436
437    if(containsInSupport(c, w)){
438      lambda = convexIntersection(lambda, c);
439    }
440
441    kill c;
442  }
443
444  return(lambda);
445}
446example
447{
448  echo=2;
449  intmat Q[3][4] =
450    1,0,1,0,
451    0,1,0,1,
452    0,0,1,1;
453
454  ring R = 0,T(1..4),dp;
455  ideal a = 0;
456
457  bigintmat w[1][3] = 3,3,1;
458  cone lambda = gitCone(a, Q, w);
459  rays(lambda);
460
461  bigintmat w2[1][3] = 1,1,1;
462  cone lambda2 = gitCone(a, Q, w2);
463  rays(lambda2);
464}
465
466/////////////////////////////////////
467
468proc gitFan(ideal a, bigintmat Q, list #)
469"USAGE: gitFan(a, Q); a: ideal, Q:bigintmat
470PURPOSE: Returns the GIT-fan of the H-action defined by Q on V(a).
471An optional third parameter of type 'int' is interpreted as the
472number of CPU-cores you would like to use.
473Note that 'system("cpu");' returns the number of cpu available
474in your system.
475RETURN: a fan.
476EXAMPLE: example gitFan; shows an example
477"
478{
479  list OC = orbitCones(a, Q, #);
480
481  fan f = refineCones(OC, Q);
482  return(f);
483}
484example
485{
486  echo=2;
487  intmat Q[3][4] =
488    1,0,1,0,
489    0,1,0,1,
490    0,0,1,1;
491
492  ring R = 0,T(1..4),dp;
493  ideal a = 0;
494
495  gitFan(a, Q);
496
497  // 2nd example //
498  kill Q;
499  intmat Q[3][6] =
500    1,1,0,0,-1,-1,
501    0,1,1,-1,-1,0,
502    1,1,1,1,1,1;
503
504  ring R = 0,T(1..6),dp;
505  ideal a = T(1)*T(6) + T(2)*T(5) + T(3)*T(4);
506
507  int t = rtimer;
508  fan F = gitFan(a, Q);
509  t = rtimer - t;
510
511  int tt = rtimer;
512  fan F = gitFan(a, Q, 4);
513  tt = rtimer - tt;
514
515  t;
516  tt;
517  "--------";
518  kill R, Q, t, tt;
519  // next example //
520  ring R = 0,T(1..10),dp;
521  ideal a = T(5)*T(10)-T(6)*T(9)+T(7)*T(8),
522    T(1)*T(9)-T(2)*T(7)+T(4)*T(5),
523    T(1)*T(8)-T(2)*T(6)+T(3)*T(5),
524    T(1)*T(10)-T(3)*T(7)+T(4)*T(6),
525    T(2)*T(10)-T(3)*T(9)+T(4)*T(8);
526
527  bigintmat Q[4][10] =
528    1,0,0,0,1,1,1,0,0,0,
529    0,1,0,0,1,0,0,1,1,0,
530    0,0,1,0,0,1,0,1,0,1,
531    0,0,0,1,0,0,1,0,1,1;
532
533  int t = rtimer;
534  fan F = gitFan(a, Q);
535  t = rtimer - t;
536
537  int tt = rtimer;
538  fan F = gitFan(a, Q, 4);
539  tt = rtimer - tt;
540
541  t;
542  tt;
543
544  "--------";
545  kill R, Q, t, tt;
546  // next example //
547  ring R = 0,T(1..15),dp;
548  ideal a =
549    T(1)*T(10)-T(2)*T(7)+T(3)*T(6),
550    T(1)*T(11)-T(2)*T(8)+T(4)*T(6),
551    T(1)*T(12)-T(2)*T(9)+T(5)*T(6),
552    T(1)*T(13)-T(3)*T(8)+T(4)*T(7),
553    T(1)*T(14)-T(3)*T(9)+T(5)*T(7),
554    T(1)*T(15)-T(4)*T(9)+T(5)*T(8),
555    T(2)*T(13)-T(3)*T(11)+T(4)*T(10),
556    T(2)*T(14)-T(3)*T(12)+T(5)*T(10);
557
558  bigintmat Q[5][15] =
559    1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,
560    0,1,0,0,0,1,0,0,0,1,1,1,0,0,0,
561    0,0,1,0,0,0,1,0,0,1,0,0,1,1,0,
562    0,0,0,1,0,0,0,1,0,0,1,0,1,0,1,
563    0,0,0,0,1,0,0,0,1,0,0,1,0,1,1;
564
565  int t = rtimer;
566  fan F = gitFan(a, Q);
567  t = rtimer - t;
568
569  int tt = rtimer;
570  fan F = gitFan(a, Q, 4);
571  tt = rtimer - tt;
572
573  t;
574  tt;
575
576}
577
578/////////////////////////////////////
579// Computes all simplicial orbit cones
580// w.r.t. the 0-ideal:
581
582static proc simplicialToricOrbitCones(bigintmat Q){
583  intvec gam0;
584  list OC;
585  cone c;
586  int r = ncols(Q);
587  int j;
588
589  for(int i = 1; i < 2^r; i++ ){
590    gam0 = int2face(i,r);
591
592    // each simplicial cone is generated by
593    // exactly nrows(Q) many columns of Q:
594    if(size(gam0) == nrows(Q)){
595      bigintmat M[size(gam0)][nrows(Q)];
596
597      for(j = 1; j <= size(gam0); j++){
598        M[j,1..ncols(M)] = Q[1..nrows(Q),gam0[j]];
599      }
600
601      c = coneViaPoints(M);
602
603      if((dimension(c) == nrows(Q)) and (!(listContainsCone(OC, c)))){
604        OC[size(OC)+1] = c;
605      }
606
607      kill M;
608    }
609  }
610
611  return(OC);
612}
613
614/////////////////////////////////////
615
616proc gkzFan(bigintmat Q)
617"USAGE: gkzFan(Q); a: ideal, Q:bigintmat
618PURPOSE: Returns the GKZ-fan of the matrix Q.
619RETURN: a fan.
620EXAMPLE: example gkzFan; shows an example
621"
622{
623  // only difference to gitFan:
624  // it suffices to consider all faces
625  // that are simplicial:
626  list OC = simplicialToricOrbitCones(Q);
627
628  fan f = refineCones(OC, Q);
629  return(f);
630}
631example
632{
633  echo=2;
634  intmat Q[3][4] =
635    1,0,1,0,
636    0,1,0,1,
637    0,0,1,1;
638
639  gkzFan(Q);
640}
Note: See TracBrowser for help on using the repository browser.