source: git/Singular/LIB/symodstd.lib

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