source: git/Singular/LIB/symodstd.lib @ 61fbaf

spielwiese
Last change on this file since 61fbaf was 4bde6b, checked in by Hans Schoenemann <hannes@…>, 4 years ago
spelling p1
  • Property mode set to 100644
File size: 40.0 KB
Line 
1////////////////////////////////////////////////////////////////////////////
2version="version symodstd.lib 4.1.2.0 Feb_2019 "; // $Id$
3category = "Commutative Algebra";
4info="
5LIBRARY:  symodstd.lib    Procedures for computing Groebner basis of ideals
6                          being invariant under certain variable permutations.
7
8AUTHOR:   Stefan Steidel, steidel@mathematik.uni-kl.de
9
10OVERVIEW:
11
12   A library for computing the Groebner basis of an ideal in the polynomial
13   ring over the rational numbers, that is invariant under certain permutations
14   of the variables, using the symmetry and modular methods.
15   More precisely let I = <f1,...,fr> be an ideal in Q[x(1),...,x(n)] and
16   sigma a permutation of order k in Sym(n) such that sigma(I) = I.
17   We assume that sigma({f1,...,fr}) = {f1,...,fr}. This can always be obtained
18   by adding sigma(fi) to {f1,...,fr}.
19   To compute a standard basis of I we apply a modification of the modular
20   version of the standard basis algorithm (improving the calculations in
21   positive characteristic). Therefore we only allow primes p such that p-1 is
22   divisible by k. This guarantees the existence of a k-th primitive root of
23   unity in Z/pZ.
24
25PROCEDURES:
26 genSymId(I,sigma);      compute ideal J such that sigma(J) = J and J includes I
27 isSymmetric(I,sigma);   check if I is invariant under permutation sigma
28 primRoot(p,k);          int describing a k-th primitive root of unity in Z/pZ
29 eigenvalues(I,sigma);   list of eigenvalues of generators of I under sigma
30 symmStd(I,sigma);       standard basis of I using invariance of I under sigma
31 syModStd(I,sigma);      SB of I using modular methods and sigma(I) = I
32";
33
34LIB "brnoeth.lib";
35LIB "modstd.lib";
36LIB "parallel.lib";
37LIB "ring.lib";
38
39////////////////////////////////////////////////////////////////////////////////
40
41proc genSymId(ideal I, intvec sigma)
42"USAGE:  genSymId(I,sigma); I ideal, sigma intvec
43ASSUME:  size(sigma) = nvars(basering =: n
44RETURN:  ideal J such that sigma(J) = J and J includes I
45NOTE:    sigma is a permutation of the variables of the basering, i.e.
46@*       sigma: var(i) ----> var(sigma[i]), 1 <= i <= n.
47EXAMPLE: example genSymId; shows an example
48"
49{
50   if(nvars(basering) != size(sigma))
51   {
52      ERROR("The input is no permutation of the ring-variables!!");
53   }
54
55   int i;
56
57   ideal perm;
58   for(i = 1; i <= size(sigma); i++)
59   {
60      perm[size(perm)+1] = var(sigma[i]);
61   }
62
63   map f = basering, perm;
64   ideal J = I;
65   ideal helpJ = I;
66   for(i = 1; i <= order(sigma) - 1; i++)
67   {
68      helpJ = f(helpJ);
69      J = J, helpJ;
70   }
71
72   return(simplify(simplify(J,4),2));
73}
74example
75{ "EXAMPLE:"; echo = 2;
76   ring R = 0,(u,v,w,x,y),dp;
77   intvec pi = 2,3,4,5,1;
78   ideal I = u2v + x3y - w2;
79   genSymId(I,pi);
80}
81
82////////////////////////////////////////////////////////////////////////////////
83
84proc isSymmetric(ideal I, intvec sigma)
85"USAGE:  isSymmetric(I,sigma); I ideal, sigma intvec
86ASSUME:  size(sigma) = nvars(basering) =: n
87RETURN:  1, if the set of generators of I is invariant under sigma;
88@*       0, if the set of generators of I is not invariant under sigma
89NOTE:    sigma is a permutation of the variables of the basering, i.e.
90@*       sigma: var(i) ----> var(sigma[i]), 1 <= i <= n.
91EXAMPLE: example isSymmetric; shows an example
92"
93{
94   if(nvars(basering) != size(sigma))
95   {
96      ERROR("The input is no permutation of the ring-variables!!");
97   }
98
99   int i, j;
100
101   list L;
102   for(i = 1; i <= size(I); i++)
103   {
104      L[size(L)+1] = I[i];
105   }
106
107   ideal perm;
108   for(i = 1; i <= size(sigma); i++)
109   {
110      perm[size(perm)+1] = var(sigma[i]);
111   }
112
113   map f = basering, perm;
114   ideal J = f(I);
115
116   poly g;
117   while(size(L) > 0)
118   {
119      j = size(L);
120      g = L[1];
121
122      for(i = 1; i <= size(J); i++)
123      {
124         if(g - J[i] == 0)
125         {
126            L = delete(L, 1);
127            break;
128         }
129      }
130
131      if(j == size(L))
132      {
133         return(0);
134      }
135   }
136
137   return(1);
138}
139example
140{ "EXAMPLE:"; echo = 2;
141   ring R = 0,x(1..5),dp;
142   ideal I = cyclic(5);
143   intvec pi = 2,3,4,5,1;
144   isSymmetric(I,pi);
145   intvec tau = 2,5,1,4,3;
146   isSymmetric(I,tau);
147}
148
149////////////////////////////////////////////////////////////////////////////////
150
151static proc permute(intvec v, intvec P)
152{
153// permute the intvec v according to the permutation given by P
154
155   int s = size(v);
156   int n = size(P);
157   int i;
158   if(s < n)
159   {
160      for(i = s+1; i <= n; i = i+1)
161      {
162         v[i] = 0;
163      }
164      s = size(v);
165   }
166   intvec auxv = v;
167   for(i = 1; i <= n; i = i+1)
168   {
169      auxv[i] = v[P[i]];
170   }
171
172   return(auxv);
173}
174
175////////////////////////////////////////////////////////////////////////////////
176
177static proc order(intvec sigma)
178{
179// compute the order of sigma in Sym({1,...,n}) with n := size(sigma)
180
181   int ORD = 1;
182   intvec id = 1..size(sigma);
183   intvec tau = sigma;
184
185   while(tau != id)
186   {
187      tau = permute(tau, sigma);
188      ORD = ORD + 1;
189   }
190
191   return(ORD);
192}
193
194////////////////////////////////////////////////////////////////////////////////
195
196static proc modExpo(bigint x, bigint a, bigint n)
197{
198// compute x^a mod n
199
200   bigint z = 1;
201
202   while(a != 0)
203   {
204      while((a mod 2) == 0)
205      {
206         a = a div 2;
207         x = x^2 mod n;
208      }
209
210      a = a - 1;
211      z = (z*x) mod n;
212   }
213
214   return(z);
215}
216
217////////////////////////////////////////////////////////////////////////////////
218
219proc primRoot(int p, int k)
220"USAGE:  primRoot(p,k); p,k integers
221ASSUME:  p is a prime and k divides p-1.
222RETURN:  int: a k-th primitive root of unity in Z/pZ
223EXAMPLE: example primRoot; shows an example
224"
225{
226   if(k == 2)
227   {
228      return(-1);
229   }
230
231   if(p == 0)
232   {
233      return(0);
234   }
235
236   int i, j;
237
238   if(((p-1) mod k) != 0)
239   {
240      ERROR("There is no "+string(k)+"-th primitive root of unity "
241             +"in Z/"+string(p)+"Z.");
242      return(0);
243   }
244
245   list PF = primefactors(p-1)[1];
246
247   bigint a;
248
249   for(i = 2; i <= p-1; i++)
250   {
251      a = i;
252
253      for(j = 1; j <= size(PF); j++)
254      {
255         if(modExpo(a, (p-1) div PF[j], p) == 1)
256         {
257            break;
258         }
259      }
260
261      if(j == size(PF)+1)
262      {
263         a = modExpo(a, (p-1) div k, p);
264
265         string str = "int xi = "+string(a);
266         execute(str);
267
268         return(xi);
269      }
270   }
271}
272example
273{ "EXAMPLE:";  echo = 2;
274   primRoot(181,10);
275   ring R = 2147482801, x, lp;
276   number a = primRoot(2147482801,5);
277   a;
278   a^2;
279   a^3;
280   a^4;
281   a^5;
282}
283
284////////////////////////////////////////////////////////////////////////////////
285
286static proc permMat(intvec sigma, list #)
287{
288// compute an intmat such that i-th row describes sigma^i
289
290   int i;
291   int n = size(sigma);
292
293   if(size(#) == 0)
294   {
295      int ORD = order(sigma);
296   }
297   else
298   {
299      int ORD = #[1];
300   }
301
302   intmat P[ORD][n];
303   intvec sigmai = sigma;
304   for(i = 1; i <= ORD; i++)
305   {
306      P[i,1..n] = sigmai;
307      sigmai = permute(sigmai, sigma);
308   }
309
310   return(P);
311}
312
313////////////////////////////////////////////////////////////////////////////////
314
315static proc genTransId(intvec sigma, list #)
316{
317// list L of two ideals such that
318// - L[1] describes the transformation and
319// - L[2] describes the retransformation (inverse mapping).
320// ORD is the order of sigma in Sym({1,...,n}) with n := size(sigma) and
321// sigma: {1,...,n} ---> {1,...,n}: sigma(j) = sigma[j]. Since sigma is a
322// permutation of variables it induces an automorphism phi of the
323// basering, more precisely a linear variable transformation which is
324// generated by this procedure. In terms it holds:
325//
326//             phi : basering  --------->  basering
327//                    var(i)     |---->     L[1][i]
328//                    L[2][i]    <----|     var(i)
329
330   int n = nvars(basering);
331
332   if(n != size(sigma))
333   {
334      ERROR("The input is no permutation of the ring-variables!!");
335   }
336
337   int i, j, k;
338
339   if(size(#) == 0)
340   {
341      int CHAR = char(basering);
342      int ORD = order(sigma);
343
344      if((((CHAR - 1) mod ORD) != 0) && (CHAR > 0))
345      {
346         ERROR("Basering of characteristic "+string(CHAR)+" has no "
347                +string(ORD)+"-th primitive root of unity!!");
348      }
349
350      if((CHAR == 0) && (ORD > 2))
351      {
352         "========================================
353          ========================================";
354         "If basering really has a "+string(ORD)+"-th "
355          +"primitive root of unity then insert it as input!!";
356         "========================================
357          ========================================";
358         return(list());
359      }
360      else
361      {
362         int xi = primRoot(CHAR, ORD);
363         number a = xi;
364      }
365   }
366   else
367   {
368      int ORD = #[1];
369      number a = #[2];
370   }
371
372   intmat PERM = permMat(sigma,ORD);
373
374   ideal TR, RETR;
375   poly s_trans;
376   matrix C;
377
378//-------------- retransformation ideal RETR is generated here -----------------
379   for(i = 1; i <= n; i++)
380   {
381      for(j = 0; j < ORD; j++)
382      {
383         for(k = 1; k <= ORD; k++)
384         {
385            // for each variable var(i):
386            // s_trans^(j) = sum_{k=1}^{ORD} a^(k*j)*sigma^k(var(i))
387            // for j = 0,...,ORD-1
388            s_trans = s_trans + a^(k*j)*var(PERM[k,i]);
389         }
390         RETR = RETR + simplify(s_trans, 1);
391         s_trans = 0;
392      }
393   }
394
395//---------------- transformation ideal TR is generated here -------------------
396   for(i = 1; i <= n; i++)
397   {
398      for(j = 1; j <= size(RETR); j++)
399      {
400         C = coeffs(RETR[j], var(i));
401         if(nrows(C) > 1)
402         {
403            // var(j) = RETR[j] = sum_{i in J} c_ij*var(i), J subset {1,...,n},
404            // and therefore var(i) = (sum_{j} s(j)/c_ij)/#(summands)
405            s_trans = s_trans + var(j)/(C[nrows(C),1]);
406         }
407      }
408
409      TR = TR + s_trans/number(size(s_trans));
410      s_trans = 0;
411   }
412
413   return(list(TR,RETR));
414}
415
416////////////////////////////////////////////////////////////////////////////////
417
418proc eigenvalues(ideal I, intvec sigma)
419"USAGE:  eigenvalues(I,sigma); I ideal, sigma intvec
420ASSUME:  size(sigma) = nvars(basering) =: n
421RETURN:  list of eigenvalues of generators of I under permutation sigma
422NOTE:    sigma is a permutation of the variables of the basering, i.e.
423         sigma: var(i) ----> var(sigma[i]), 1 <= i <= n.
424EXAMPLE: example eigenvalues; shows an example
425"
426{
427   int i, j;
428
429   def A = basering;
430   int n = nvars(A);
431
432   poly ev;
433   list EV;
434   poly s, help_var;
435   matrix C1, C2;
436
437   ideal perm;
438   for(i = 1; i <= n; i++)
439   {
440      perm[size(perm)+1] = var(sigma[i]);
441   }
442
443   map f = A, perm;
444
445   for(i = 1; i <= size(I); i++)
446   {
447//-------------- s is the image of I[i] under permutation sigma ----------------
448      s = I[i];
449      s = f(s);
450
451      for(j = 1; j <= n; j++)
452      {
453         C1 = coeffs(I[i], var(j));
454         C2 = coeffs(s, var(j));
455         if(nrows(C1) > 1)
456         {
457            ev = C2[nrows(C2),1]/C1[nrows(C1),1];
458
459//------ Furthermore check that I[i] is eigenvector of permutation sigma. ------
460            if(s == ev*I[i])
461            {
462               break;
463            }
464            else
465            {
466               ERROR("I["+string(i)+"] is no eigenvector "
467                      +"of permutation sigma!!");
468            }
469         }
470      }
471
472      EV[size(EV)+1] = ev;
473   }
474
475   return(EV);
476}
477example
478{ "EXAMPLE:";  echo = 2;
479   ring R = 11, x(1..5), dp;
480   poly p1 = x(1)+x(2)+x(3)+x(4)+x(5);
481   poly p2 = x(1)+4*x(2)+5*x(3)-2*x(4)+3*x(5);
482   poly p3 = x(1)+5*x(2)+3*x(3)+4*x(4)-2*x(5);
483   poly p4 = x(1)-2*x(2)+4*x(3)+3*x(4)+5*x(5);
484   poly p5 = x(1)+3*x(2)-2*x(3)+5*x(4)+4*x(5);
485   ideal I = p1,p2,p3,p4,p5;
486   intvec tau = 2,3,4,5,1;
487   eigenvalues(I,tau);
488}
489
490////////////////////////////////////////////////////////////////////////////////
491
492proc symmStd(ideal I, intvec sigma, list #)
493"USAGE:  symmStd(I,sigma,#); I ideal, sigma intvec
494ASSUME:  size(sigma) = nvars(basering) =: n, basering has an order(sigma)-th
495         primitive root of unity a (if char(basering) > 0) and sigma(I) = I
496RETURN:  ideal, a standard basis of I
497NOTE:    Assuming that the ideal I is invariant under the variable permutation
498         sigma and the basering has an order(sigma)-th primitive root of unity
499         the procedure uses linear transformation of variables in order to
500         improve standard basis computation.
501         If char(basering) = 0 all computations are done in the polynomial ring
502         over the smallest field extension that has an order(sigma)-th primitive
503         root of unity.
504EXAMPLE: example symmStd; shows an example
505"
506{
507   if((nvars(basering) != size(sigma)) || (!isSymmetric(I,sigma)))
508   {
509      ERROR("The input is no permutation of the ring-variables!!");
510   }
511
512   option(redSB);
513
514   def R = basering;
515   int CHAR = char(R);
516   int n = nvars(R);
517
518   int t;
519
520//-------- (1) Compute the order of variable permutation sigma. ----------------
521   int ORD = order(sigma);
522   if((((CHAR - 1) mod ORD) != 0) && (CHAR > 0))
523   {
524      ERROR("Basering of characteristic "+string(CHAR)+" has no "
525             +string(ORD)+"-th primitive root of unity!!");
526   }
527
528//-------- (2) Compute the order(sigma)-th primitive root of unity -------------
529//--------     in basering or move to ring extension.              -------------
530   if((CHAR == 0) && (ORD > 2))
531   {
532      def save_ring=basering;
533      ring ext_ring=0,p,lp;
534      def S = changechar(ringlist(ext_ring),save_ring);
535      setring S;
536      kill ext_ring;
537      kill save_ring;
538      minpoly = rootofUnity(ORD);
539      ideal I = imap(R, I);
540      number a = p;
541   }
542   else
543   {
544      int xi = primRoot(CHAR, ORD);
545      number a = xi;
546   }
547
548//--------- (3) Define the linear transformation of variables with -------------
549//---------     respect to sigma.                                  -------------
550   list L = genTransId(sigma,ORD,a);
551   ideal TR = L[1];
552   ideal RETR = L[2];
553
554//--------- (4) Compute the eigenvalues of the "new" variables of --------------
555//---------     sigma after transformation.                       --------------
556   list EV = eigenvalues(RETR, sigma);
557
558//--------- (5) Transformation of the input-ideal is done here. ----------------
559   map f = basering, TR;
560   t = timer;
561   ideal I_trans = f(I);
562   if(printlevel >= 11) { "Transformation: "+string(timer - t)+" seconds"; }
563
564//--------- (6) Compute a standard basis of the transformed ideal. -------------
565   t = timer;
566   if(size(#) > 0) { ideal sI_trans = std(I_trans, #[1]); }
567   else { ideal sI_trans = std(I_trans); }
568   if(printlevel >= 11) { "1st Groebner basis: "+string(timer - t)+" seconds"; }
569
570//--------- (7) Retransformation is done here. ---------------------------------
571   map g = basering, RETR;
572   t = timer;
573   ideal I_retrans = g(sI_trans);
574   if(printlevel >= 11) { "Reverse Transformation: "+string(timer - t)
575                           +" seconds"; }
576
577//--------- (8) Compute a standard basis of the retransformaed ideal -----------
578//---------     which is then a standard basis of the input-ideal.   -----------
579   t = timer;
580   ideal sI_retrans = std(I_retrans);
581   if(printlevel >= 11) { "2nd Groebner basis: "+string(timer - t)+" seconds"; }
582
583   if((CHAR == 0) && (ORD > 2))
584   {
585      setring R;
586      ideal sI_retrans = fetch(S, sI_retrans);
587      return(sI_retrans);
588   }
589   else
590   {
591      return(sI_retrans);
592   }
593}
594example
595{ "EXAMPLE:";  echo = 2;
596   ring R = 0, x(1..4), dp;
597   ideal I = cyclic(4);
598   I;
599   intvec pi = 2,3,4,1;
600   ideal sI = symmStd(I,pi);
601   sI;
602
603   ring S = 31, (x,y,z), dp;
604   ideal J;
605   J[1] = xy-y2+xz;
606   J[2] = xy+yz-z2;
607   J[3] = -x2+xz+yz;
608   intvec tau = 3,1,2;
609   ideal sJ = symmStd(J,tau);
610   sJ;
611}
612
613////////////////////////////////////////////////////////////////////////////////
614
615proc divPrimeTest(def II, bigint p, int k)
616{
617   if((p - 1) mod k != 0) { return(0); }
618
619   if(typeof(II) == "string")
620   {
621      execute("ideal I = "+II+";");
622   }
623   else
624   {
625      ideal I = II;
626   }
627
628   int i,j;
629   poly f;
630   number cnt;
631   for(i = 1; i <= size(I); i++)
632   {
633      f = cleardenom(I[i]);
634      if(f == 0) { return(0); }
635      cnt = leadcoef(I[i])/leadcoef(f);
636      if((bigint(numerator(cnt)) mod p) == 0) { return(0); }
637      if((bigint(denominator(cnt)) mod p) == 0) { return(0); }
638      for(j = size(f); j > 0; j--)
639      {
640         if((bigint(leadcoef(f[j])) mod p) == 0) { return(0); }
641      }
642   }
643   return(1);
644}
645
646////////////////////////////////////////////////////////////////////////////////
647
648proc divPrimeList(int k, ideal I, int n, list #)
649{
650// the intvec of n greatest primes p <= 2147483647 (resp. n greatest primes
651// < L[size(L)] union with L) such that each (p-1) is divisible by k, and none
652// of these primes divides any coefficient occurring in I
653// --> similar to procedure primeList in modstd.lib
654
655   intvec L;
656   int i,p;
657   int ncores = 1;
658
659//-----------------  Initialize optional parameter ncores  ---------------------
660   if(size(#) > 0)
661   {
662      if(size(#) == 1)
663      {
664         if(typeof(#[1]) == "int")
665         {
666            ncores = #[1];
667            # = list();
668         }
669      }
670      else
671      {
672         ncores = #[2];
673      }
674   }
675
676   if(size(#) == 0)
677   {
678      p = 2147483647;
679      while(!divPrimeTest(I,p,k))
680      {
681         p = prime(p-1);
682         if(p == 2) { ERROR("No more primes."); }
683      }
684      L[1] = p;
685   }
686   else
687   {
688      L = #[1];
689      p = prime(L[size(L)]-1);
690      while(!divPrimeTest(I,p,k))
691      {
692         p = prime(p-1);
693         if(p == 2) { ERROR("No more primes."); }
694      }
695      L[size(L)+1] = p;
696   }
697   if(p == 2) { ERROR("No more primes."); }
698   if(ncores == 1)
699   {
700      for(i = 2; i <= n; i++)
701      {
702         p = prime(p-1);
703         while(!divPrimeTest(I,p,k))
704         {
705            p = prime(p-1);
706            if(p == 2) { ERROR("no more primes"); }
707         }
708         L[size(L)+1] = p;
709      }
710   }
711   else
712   {
713      int neededSize = size(L)+n-1;;
714      list parallelResults;
715      list arguments;
716      int neededPrimes = neededSize-size(L);
717      while(neededPrimes > 0)
718      {
719         arguments = list();
720         for(i = ((neededPrimes div ncores)+1-(neededPrimes%ncores == 0))
721            *ncores; i > 0; i--)
722         {
723            p = prime(p-1);
724            if(p == 2) { ERROR("no more primes"); }
725            arguments[i] = list("I", p, k);
726         }
727         parallelResults = parallelWaitAll("divPrimeTest", arguments, 0,
728            ncores);
729         for(i = size(arguments); i > 0; i--)
730         {
731            if(parallelResults[i])
732            {
733               L[size(L)+1] = arguments[i][2];
734            }
735         }
736         neededPrimes = neededSize-size(L);
737      }
738      if(size(L) > neededSize)
739      {
740         L = L[1..neededSize];
741      }
742   }
743   return(L);
744}
745example
746{ "EXAMPLE:"; echo = 2;
747   ring r = 0,(x,y,z),dp;
748   ideal I = 2147483647x+y, z-181;
749   intvec L = divPrimeList(4,I,10,10);
750   size(L);
751   L[1];
752   L[size(L)];
753   L = divPrimeList(4,I,5,L,5);
754   size(L);
755   L[size(L)];
756}
757
758////////////////////////////////////////////////////////////////////////////////
759
760proc spTestSB(ideal I, ideal J, list L, intvec sigma, int variant, list #)
761"USAGE:  spTestSB(I,J,L,sigma,variant,#); I,J ideals, L intvec of primes,
762                                          sigma intvec, variant integer
763RETURN:  1 (resp. 0) if for a randomly chosen prime p, that is not in L and
764         divisible by the order of sigma, J mod p is (resp. is not) a standard
765         basis of I mod p
766EXAMPLE: example spTestSB; shows an example
767"
768{
769   int i,j,k,p;
770   int ORD = order(sigma);
771   def R = basering;
772   list r = ringlist(R);
773
774   while(!j)
775   {
776      j = 1;
777      while(((p - 1) mod ORD) != 0)
778      {
779         p = prime(random(1000000000,2134567879));
780         if(p == 2){ ERROR("no more primes"); }
781      }
782      for(i = 1; i <= size(L); i++)
783      {
784         if(p == L[i]){ j = 0; break }
785      }
786      if(j)
787      {
788         for(i = 1; i <= ncols(I); i++)
789         {
790            for(k = 2; k <= size(I[i]); k++)
791            {
792               if((bigint(denominator(leadcoef(I[i][k]))) mod p) == 0){ j = 0; break; }
793            }
794            if(!j){ break; }
795         }
796      }
797      if(j)
798      {
799         if(!primeTest(I,p)) { j = 0; }
800      }
801   }
802   r[1] = p;
803   def @R = ring(r);
804   setring @R;
805   ideal I = imap(R,I);
806   ideal J = imap(R,J);
807   attrib(J,"isSB",1);
808
809   int t = timer;
810   j = 1;
811   if(isIncluded(I,J) == 0){ j = 0; }
812
813   if(printlevel >= 11)
814   {
815      "isIncluded(I,J) takes "+string(timer - t)+" seconds";
816      "j = "+string(j);
817   }
818
819   t = timer;
820   if(j)
821   {
822      if(size(#) > 0)
823      {
824         ideal K = smpStd(I,sigma,p,variant,#[1])[1];
825      }
826      else
827      {
828         ideal K = smpStd(I,sigma,p,variant)[1];
829      }
830      t = timer;
831      if(isIncluded(J,K) == 0){ j = 0; }
832
833      if(printlevel >= 11)
834      {
835         "isIncluded(J,K) takes "+string(timer - t)+" seconds";
836         "j = "+string(j);
837      }
838   }
839   setring R;
840   return(j);
841}
842example
843{ "EXAMPLE:"; echo = 2;
844   intvec L = 2,3,5;
845   ring r = 0,(x,y,z),dp;
846   ideal I = x+1,y+1;
847   intvec sigma = 2,1,3;
848   ideal J = x+1,y;
849   spTestSB(I,J,L,sigma,2);
850   spTestSB(J,I,L,sigma,2);
851}
852
853////////////////////////////////////////////////////////////////////////////////
854
855proc smpStd(ideal I, intvec sigma, int p, int variant, list #)
856"USAGE:  smpStd(I,sigma,p,#); I ideal, sigma intvec, p integer, variant integer
857ASSUME:  If size(#) > 0, then #[1] is an intvec describing the Hilbert series.
858RETURN:  ideal - a standard basis of I mod p, integer - p
859NOTE:    The procedure computes a standard basis of the ideal I modulo p and
860         fetches the result to the basering. If size(#) > 0 the Hilbert driven
861         standard basis computation symmStd(.,.,#[1]) is used in symmStd.
862         The standard basis computation modulo p does also vary depending on the
863         integer variant, namely
864@*       - variant = 1: symmStd(.,.,#[1]) resp. symmStd,
865@*       - variant = 2: symmStd,
866@*       - variant = 3: homog. - symmStd(.,.,#[1]) resp. symmStd - dehomog.,
867@*       - variant = 4: fglm.
868EXAMPLE: example smpStd; shows an example
869"
870{
871   def R0 = basering;
872   list rl = ringlist(R0);
873   rl[1] = p;
874   def @r = ring(rl);
875   setring @r;
876   ideal i = fetch(R0,I);
877
878   option(redSB);
879
880   if(variant == 1)
881   {
882      if(size(#) > 0)
883      {
884         i = symmStd(i, sigma, #[1]);
885      }
886      else
887      {
888         i = symmStd(i, sigma);
889      }
890   }
891
892   if(variant == 2)
893   {
894      i = symmStd(i, sigma);
895   }
896
897   if(variant == 3)
898   {
899      list rl = ringlist(@r);
900      int nvar@r = nvars(@r);
901
902      int k;
903      intvec w;
904      for(k = 1; k <= nvar@r; k++)
905      {
906         w[k] = deg(var(k));
907      }
908      w[nvar@r + 1] = 1;
909
910      rl[2][nvar@r + 1] = "homvar";
911      rl[3][2][2] = w;
912
913      def HomR = ring(rl);
914      setring HomR;
915      ideal i = imap(@r, i);
916      i = homog(i, homvar);
917      intvec tau = sigma, size(sigma)+1;
918
919      if(size(#) > 0)
920      {
921         if(w == 1)
922         {
923            i = symmStd(i, tau, #[1]);
924         }
925         else
926         {
927            i = symmStd(i, tau, #[1], w);
928         }
929      }
930      else
931      {
932         i = symmStd(i, tau);
933      }
934
935      i = subst(i, homvar, 1);
936      i = simplify(i, 34);
937
938      setring @r;
939      i = imap(HomR, i);
940      i = interred(i);
941      kill HomR;
942   }
943
944   if(variant == 4)
945   {
946      def R1 = changeord(list(list("dp",1:nvars(basering))));
947      setring R1;
948      ideal i = fetch(@r,i);
949      i = symmStd(i, sigma);
950      setring @r;
951      i = fglm(R1,i);
952   }
953
954   setring R0;
955   return(list(fetch(@r,i),p));
956}
957example
958{ "EXAMPLE:"; echo = 2;
959   ring r1 = 0, x(1..4), dp;
960   ideal I = cyclic(4);
961   intvec sigma = 2,3,4,1;
962   int p = 181;
963   list P = smpStd(I,sigma,p,2);
964   P;
965
966   ring r2 = 0, x(1..5), lp;
967   ideal I = cyclic(5);
968   intvec tau = 2,3,4,5,1;
969   int q = 31981;
970   list Q = smpStd(I,tau,q,4);
971   Q;
972}
973
974////////////////////////////////////////////////////////////////////////////////
975
976proc syModStd(ideal I, intvec sigma, list #)
977"USAGE:  syModStd(I,sigma); I ideal, sigma intvec
978ASSUME:  size(sigma) = nvars(basering) and sigma(I) = I. If size(#) > 0, then
979         # contains either 1, 2 or 4 integers such that
980@*       - #[1] is the number of available processors for the computation,
981@*       - #[2] is an optional parameter for the exactness of the computation,
982                if #[2] = 1, the procedure computes a standard basis for sure,
983@*       - #[3] is the number of primes until the first lifting,
984@*       - #[4] is the constant number of primes between two liftings until
985           the computation stops.
986RETURN:  ideal, a standard basis of I if no warning appears;
987NOTE:    The procedure computes a standard basis of the ideal I (over the
988         rational numbers) by using modular methods and the fact that I is
989         invariant under the variable permutation sigma.
990         By default the procedure computes a standard basis of I for sure, but
991         if the optional parameter #[2] = 0, it computes a standard basis of I
992         with high probability.
993         The procedure distinguishes between different variants for the standard
994         basis computation in positive characteristic depending on the ordering
995         of the basering, the parameter #[2] and if the ideal I is homogeneous.
996@*       - variant = 1, if I is homogeneous,
997@*       - variant = 2, if I is not homogeneous, 1-block-ordering,
998@*       - variant = 3, if I is not homogeneous, complicated ordering (lp or
999                        > 1 block),
1000@*       - variant = 4, if I is not homogeneous, ordering lp, dim(I) = 0.
1001EXAMPLE: example syModStd; shows an example
1002"
1003{
1004   if((nvars(basering) != size(sigma)) || (!isSymmetric(I,sigma)))
1005   {
1006      ERROR("The input is no permutation of the ring-variables!!");
1007   }
1008
1009   int TT = timer;
1010   int RT = rtimer;
1011
1012   def R0 = basering;
1013   list rl = ringlist(R0);
1014   if((npars(R0) > 0) || (rl[1] > 0))
1015   {
1016      ERROR("Characteristic of basering should be zero, basering should
1017             have no parameters.");
1018   }
1019
1020   int index = 1;
1021   int i,k,c;
1022   int j = 1;
1023   int pTest, sizeTest;
1024   int en = 2134567879;
1025   int an = 1000000000;
1026   bigint N;
1027   int ORD = order(sigma);
1028
1029//--------------------  Initialize optional parameters  ------------------------
1030   if(size(#) > 0)
1031   {
1032      if(size(#) == 1)
1033      {
1034         int n1 = #[1];
1035         int exactness = 1;
1036         if(n1 >= 10)
1037         {
1038            int n2 = n1 + 1;
1039            int n3 = n1;
1040         }
1041         else
1042         {
1043            int n2 = 10;
1044            int n3 = 10;
1045         }
1046      }
1047      if(size(#) == 2)
1048      {
1049         int n1 = #[1];
1050         int exactness = #[2];
1051         if(n1 >= 10)
1052         {
1053            int n2 = n1 + 1;
1054            int n3 = n1;
1055         }
1056         else
1057         {
1058            int n2 = 10;
1059            int n3 = 10;
1060         }
1061      }
1062      if(size(#) == 4)
1063      {
1064         int n1 = #[1];
1065         int exactness = #[2];
1066         if(n1 >= #[3])
1067         {
1068            int n2 = n1 + 1;
1069         }
1070         else
1071         {
1072            int n2 = #[3];
1073         }
1074         if(n1 >= #[4])
1075         {
1076            int n3 = n1;
1077         }
1078         else
1079         {
1080            int n3 = #[4];
1081         }
1082      }
1083   }
1084   else
1085   {
1086      int n1 = 1;
1087      int exactness = 1;
1088      int n2 = 10;
1089      int n3 = 10;
1090   }
1091
1092   if(printlevel >= 10)
1093   {
1094      "n1 = "+string(n1)+", n2 = "+string(n2)+", n3 = "+string(n3)
1095       +", exactness = "+string(exactness);
1096   }
1097
1098//-------------------------- Save current options ------------------------------
1099   intvec opt = option(get);
1100
1101   option(redSB);
1102
1103//--------------------  Initialize the list of primes  -------------------------
1104   int tt = timer;
1105   int rt = rtimer;
1106   intvec L = divPrimeList(ORD,I,n2,n1);
1107   if(printlevel >= 10)
1108   {
1109      "CPU-time for divPrimeList: "+string(timer-tt)+" seconds.";
1110      "Real-time for divPrimeList: "+string(rtimer-rt)+" seconds.";
1111   }
1112
1113//---------------------  Decide which variant to take  -------------------------
1114   int variant;
1115   int h = homog(I);
1116
1117   tt = timer;
1118   rt = rtimer;
1119
1120   if(!hasMixedOrdering())
1121   {
1122      if(h)
1123      {
1124         variant = 1;
1125         if(printlevel >= 10) { "variant = 1"; }
1126
1127         rl[1] = L[5];
1128         def @r = ring(rl);
1129         setring @r;
1130         def @s = changeord(list(list("dp",1:nvars(basering))));
1131         setring @s;
1132         ideal I = std(fetch(R0,I));
1133         intvec hi = hilb(I,1);
1134         setring R0;
1135         kill @r,@s;
1136      }
1137      else
1138      {
1139         string ordstr_R0 = ordstr(R0);
1140         int neg = 1 - attrib(R0,"global");
1141
1142         if((find(ordstr_R0, "M") > 0) || (find(ordstr_R0, "a") > 0) || neg)
1143         {
1144            variant = 2;
1145            if(printlevel >= 10) { "variant = 2"; }
1146         }
1147         else
1148         {
1149            string order;
1150            if(system("nblocks") <= 2)
1151            {
1152               if(find(ordstr_R0, "M") + find(ordstr_R0, "lp")
1153                                       + find(ordstr_R0, "rp") <= 0)
1154               {
1155                  order = "simple";
1156               }
1157            }
1158
1159            if((order == "simple") || (size(rl) > 4))
1160            {
1161               variant = 2;
1162               if(printlevel >= 10) { "variant = 2"; }
1163            }
1164            else
1165            {
1166               rl[1] = L[5];
1167               def @r = ring(rl);
1168               setring @r;
1169
1170               def @s = changeord(list(list("dp",1:nvars(basering))));
1171               setring @s;
1172               ideal I = std(fetch(R0,I));
1173               if(dim(I) == 0)
1174               {
1175                  variant = 4;
1176                  if(printlevel >= 10) { "variant = 4"; }
1177               }
1178               else
1179               {
1180                  variant = 3;
1181                  if(printlevel >= 10) { "variant = 3"; }
1182
1183                  int nvar@r = nvars(@r);
1184                  intvec w;
1185                  for(i = 1; i <= nvar@r; i++)
1186                  {
1187                     w[i] = deg(var(i));
1188                  }
1189                  w[nvar@r + 1] = 1;
1190
1191                  list hiRi = hilbRing(fetch(R0,I),w);
1192                  intvec W = hiRi[2];
1193                  @s = hiRi[1];
1194                  setring @s;
1195                  intvec tau = sigma, size(sigma)+1;
1196
1197                  Id(1) = symmStd(Id(1),tau);
1198                  intvec hi = hilb(Id(1), 1, W);
1199               }
1200
1201               setring R0;
1202               kill @r,@s;
1203            }
1204         }
1205      }
1206   }
1207   else
1208   {
1209      if(exactness == 1) { return(groebner(I)); }
1210      if(h)
1211      {
1212         variant = 1;
1213         if(printlevel >= 10) { "variant = 1"; }
1214         rl[1] = L[5];
1215         def @r = ring(rl);
1216         setring @r;
1217         def @s = changeord(list(list("dp",1:nvars(basering))));
1218         setring @s;
1219         ideal I = std(fetch(R0,I));
1220         intvec hi = hilb(I,1);
1221         setring R0;
1222         kill @r,@s;
1223      }
1224      else
1225      {
1226         string ordstr_R0 = ordstr(R0);
1227         int neg = 1 - attrib(R0,"global");
1228
1229         if((find(ordstr_R0, "M") > 0) || (find(ordstr_R0, "a") > 0) || neg)
1230         {
1231            variant = 2;
1232            if(printlevel >= 10) { "variant = 2"; }
1233         }
1234         else
1235         {
1236            string order;
1237            if(system("nblocks") <= 2)
1238            {
1239               if(find(ordstr_R0, "M") + find(ordstr_R0, "lp")
1240                                       + find(ordstr_R0, "rp") <= 0)
1241               {
1242                  order = "simple";
1243               }
1244            }
1245
1246            if((order == "simple") || (size(rl) > 4))
1247            {
1248               variant = 2;
1249               if(printlevel >= 10) { "variant = 2"; }
1250            }
1251            else
1252            {
1253               variant = 3;
1254               if(printlevel >= 10) { "variant = 3"; }
1255
1256               rl[1] = L[5];
1257               def @r = ring(rl);
1258               setring @r;
1259               int nvar@r = nvars(@r);
1260               intvec w;
1261               for(i = 1; i <= nvar@r; i++)
1262               {
1263                  w[i] = deg(var(i));
1264               }
1265               w[nvar@r + 1] = 1;
1266
1267               list hiRi = hilbRing(fetch(R0,I),w);
1268               intvec W = hiRi[2];
1269               def @s = hiRi[1];
1270               setring @s;
1271               intvec tau = sigma, size(sigma)+1;
1272
1273               Id(1) = symmStd(Id(1),tau);
1274               intvec hi = hilb(Id(1), 1, W);
1275
1276               setring R0;
1277               kill @r,@s;
1278            }
1279         }
1280      }
1281   }
1282
1283   list P,T1,T2,T3,LL;
1284
1285   ideal J,K,H;
1286
1287//-----  If there is more than one processor available, we parallelize the  ----
1288//-----  main standard basis computations in positive characteristic        ----
1289
1290   if(n1 > 1)
1291   {
1292      ideal I_for_fork = I;
1293      export(I_for_fork);           // I available for each link
1294
1295//-----  Create n1 links l(1),...,l(n1), open all of them and compute  ---------
1296//-----  standard basis for the primes L[2],...,L[n1 + 1].             ---------
1297
1298      for(i = 1; i <= n1; i++)
1299      {
1300         //link l(i) = "MPtcp:fork";
1301         link l(i) = "ssi:fork";
1302         open(l(i));
1303         if((variant == 1) || (variant == 3))
1304         {
1305            write(l(i), quote(smpStd(I_for_fork, eval(sigma), eval(L[i + 1]),
1306                                                 eval(variant), eval(hi))));
1307         }
1308         if((variant == 2) || (variant == 4))
1309         {
1310            write(l(i), quote(smpStd(I_for_fork, eval(sigma), eval(L[i + 1]),
1311                                                 eval(variant))));
1312         }
1313      }
1314
1315      int t = timer;
1316      if((variant == 1) || (variant == 3))
1317      {
1318         P = smpStd(I_for_fork, sigma, L[1], variant, hi);
1319      }
1320      if((variant == 2) || (variant == 4))
1321      {
1322         P = smpStd(I_for_fork, sigma, L[1], variant);
1323      }
1324      t = timer - t;
1325      if(t > 60) { t = 60; }
1326      int i_sleep = system("sh", "sleep "+string(t));
1327      T1[1] = P[1];
1328      T2[1] = bigint(P[2]);
1329      index++;
1330
1331      j = j + n1 + 1;
1332   }
1333
1334//--------------  Main standard basis computations in positive  ----------------
1335//----------------------  characteristic start here  ---------------------------
1336
1337   list arguments_farey, results_farey;
1338
1339   while(1)
1340   {
1341      tt = timer; rt = rtimer;
1342
1343      if(printlevel >= 10) { "size(L) = "+string(size(L)); }
1344
1345      if(n1 > 1)
1346      {
1347         while(j <= size(L) + 1)
1348         {
1349            for(i = 1; i <= n1; i++)
1350            {
1351               //--- ask if link l(i) is ready otherwise sleep for t seconds ---
1352               if(status(l(i), "read", "ready"))
1353               {
1354                  //--- read the result from l(i) ---
1355                  P = read(l(i));
1356                  T1[index] = P[1];
1357                  T2[index] = bigint(P[2]);
1358                  index++;
1359
1360                  if(j <= size(L))
1361                  {
1362                     if((variant == 1) || (variant == 3))
1363                     {
1364                        write(l(i), quote(smpStd(I_for_fork, eval(sigma),
1365                                        eval(L[j]), eval(variant), eval(hi))));
1366                        j++;
1367                     }
1368                     if((variant == 2) || (variant == 4))
1369                     {
1370                        write(l(i), quote(smpStd(I_for_fork, eval(sigma),
1371                                        eval(L[j]), eval(variant))));
1372                        j++;
1373                     }
1374                  }
1375                  else
1376                  {
1377                     k++;
1378                     close(l(i));
1379                  }
1380               }
1381            }
1382            //--- k describes the number of closed links ---
1383            if(k == n1)
1384            {
1385               j++;
1386            }
1387            i_sleep = system("sh", "sleep "+string(t));
1388         }
1389      }
1390      else
1391      {
1392         while(j <= size(L))
1393         {
1394            if((variant == 1) || (variant == 3))
1395            {
1396               P = smpStd(I, sigma, L[j], variant, hi);
1397            }
1398            if((variant == 2) || (variant == 4))
1399            {
1400               P = smpStd(I, sigma, L[j], variant);
1401            }
1402
1403            T1[index] = P[1];
1404            T2[index] = bigint(P[2]);
1405            index++;
1406            j++;
1407         }
1408      }
1409
1410      if(printlevel >= 10)
1411      {
1412         "CPU-time for computing list is "+string(timer - tt)+" seconds.";
1413         "Real-time for computing list is "+string(rtimer - rt)+" seconds.";
1414      }
1415
1416//------------------------  Delete unlucky primes  -----------------------------
1417//-------------  unlucky if and only if the leading ideal is wrong  ------------
1418
1419      LL = deleteUnluckyPrimes(T1,T2,h);
1420      T1 = LL[1];
1421      T2 = LL[2];
1422
1423//-------------------  Now all leading ideals are the same  --------------------
1424//-------------------  Lift results to basering via farey  ---------------------
1425
1426      tt = timer; rt = rtimer;
1427      N = T2[1];
1428      for(i = 2; i <= size(T2); i++) { N = N*T2[i]; }
1429      H = chinrem(T1,T2);
1430      if(n1 == 1)
1431      {
1432         J = farey(H,N);
1433      }
1434      else
1435      {
1436         for(i = ncols(H); i > 0; i--)
1437         {
1438            arguments_farey[i] = list(ideal(H[i]), N);
1439         }
1440         results_farey = parallelWaitAll("farey", arguments_farey, 0, n1);
1441         for(i = ncols(H); i > 0; i--)
1442         {
1443            J[i] = results_farey[i][1];
1444         }
1445      }
1446      if(printlevel >= 10)
1447      {
1448         "CPU-time for lifting-process is "+string(timer - tt)+" seconds.";
1449         "Real-time for lifting-process is "+string(rtimer - rt)+" seconds.";
1450      }
1451
1452//----------------  Test if we already have a standard basis of I --------------
1453
1454      tt = timer; rt = rtimer;
1455      if((variant == 1) || (variant == 3))
1456      {
1457         pTest = spTestSB(I,J,L,sigma,variant,hi);
1458      }
1459      if((variant == 2) || (variant == 4))
1460      {
1461         pTest = spTestSB(I,J,L,sigma,variant);
1462      }
1463
1464      if(printlevel >= 10)
1465      {
1466         "CPU-time for pTest is "+string(timer - tt)+" seconds.";
1467         "Real-time for pTest is "+string(rtimer - rt)+" seconds.";
1468      }
1469
1470      if(pTest)
1471      {
1472         if(printlevel >= 10)
1473         {
1474            "CPU-time for computation without final tests is "
1475            +string(timer - TT)+" seconds.";
1476            "Real-time for computation without final tests is "
1477            +string(rtimer - RT)+" seconds.";
1478         }
1479
1480         attrib(J,"isSB",1);
1481
1482         if(exactness == 0)
1483         {
1484            option(set, opt);
1485            if(n1 > 1) { kill I_for_fork; }
1486            return(J);
1487         }
1488
1489         if(exactness == 1)
1490         {
1491            tt = timer; rt = rtimer;
1492            sizeTest = 1 - isIncluded(I,J,n1);
1493
1494            if(printlevel >= 10)
1495            {
1496               "CPU-time for checking if I subset <G> is "
1497               +string(timer - tt)+" seconds.";
1498               "Real-time for checking if I subset <G> is "
1499               +string(rtimer - rt)+" seconds.";
1500            }
1501
1502            if(sizeTest == 0)
1503            {
1504               tt = timer; rt = rtimer;
1505               K = std(J);
1506
1507               if(printlevel >= 10)
1508               {
1509                  "CPU-time for last std-computation is "
1510                  +string(timer - tt)+" seconds.";
1511                  "Real-time for last std-computation is "
1512                  +string(rtimer - rt)+" seconds.";
1513               }
1514
1515               if(size(reduce(K,J,5)) == 0)
1516               {
1517                  option(set, opt);
1518                  if(n1 > 1) { kill I_for_fork; }
1519                  return(J);
1520               }
1521            }
1522         }
1523      }
1524
1525//--------------  We do not already have a standard basis of I  ----------------
1526//-----------  Therefore do the main computation for more primes  --------------
1527
1528      T1 = H;
1529      T2 = N;
1530      index = 2;
1531
1532      j = size(L) + 1;
1533      tt = timer; rt = rtimer;
1534      L = divPrimeList(ORD,I,n3,L,n1);
1535      if(printlevel >= 10)
1536      {
1537         "CPU-time for divPrimeList: "+string(timer-tt)+" seconds.";
1538         "Real-time for divPrimeList: "+string(rtimer-rt)+" seconds.";
1539      }
1540
1541      if(n1 > 1)
1542      {
1543         for(i = 1; i <= n1; i++)
1544         {
1545            open(l(i));
1546            if((variant == 1) || (variant == 3))
1547            {
1548               write(l(i), quote(smpStd(I_for_fork, eval(sigma), eval(L[j+i-1]),
1549                                                    eval(variant), eval(hi))));
1550            }
1551            if((variant == 2) || (variant == 4))
1552            {
1553               write(l(i), quote(smpStd(I_for_fork, eval(sigma), eval(L[j+i-1]),
1554                                                    eval(variant))));
1555            }
1556         }
1557         j = j + n1;
1558         k = 0;
1559      }
1560   }
1561}
1562example
1563{ "EXAMPLE:"; echo = 2;
1564   ring R1 = 0, (x,y,z), dp;
1565   ideal I;
1566   I[1] = -2xyz4+xz5+xz;
1567   I[2] = -2xyz4+yz5+yz;
1568   intvec sigma = 2,1,3;
1569   ideal sI = syModStd(I,sigma);
1570   sI;
1571
1572   ring R2 = 0, x(1..4), dp;
1573   ideal I = cyclic(4);
1574   I;
1575   intvec pi = 2,3,4,1;
1576   ideal sJ1 = syModStd(I,pi,1);
1577   ideal sJ2 = syModStd(I,pi,1,0);
1578   size(reduce(sJ1,sJ2));
1579   size(reduce(sJ2,sJ1));
1580}
Note: See TracBrowser for help on using the repository browser.