source: git/Singular/LIB/algebra.lib @ a57b65

spielwiese
Last change on this file since a57b65 was 3686937, checked in by Oleksandr Motsak <motsak@…>, 11 years ago
Added '$Id$' as a comment to all libs (LIB/*.lib)
  • Property mode set to 100644
File size: 35.9 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2version="version algebra.lib 4.0.0.0 Jun_2013 "; // $Id$
3category="Commutative Algebra";
4info="
5LIBRARY:  algebra.lib   Compute with Algbras and Algebra Maps
6AUTHORS:  Gert-Martin Greuel,     greuel@mathematik.uni-kl.de,
7@*        Agnes Eileen Heydtmann, agnes@math.uni-sb.de,
8@*        Gerhard Pfister,        pfister@mathematik.uni-kl.de
9
10PROCEDURES:
11 algebra_containment(); query of algebra containment
12 module_containment();  query of module containment over a subalgebra
13 inSubring(p,I);        test whether polynomial p is in subring generated by I
14 algDependent(I);       computes algebraic relations between generators of I
15 alg_kernel(phi);       computes the kernel of the ringmap phi
16 is_injective(phi);     test for injectivity of ringmap phi
17 is_surjective(phi);    test for surjectivity of ringmap phi
18 is_bijective(phi);     test for bijectivity of ring map phi
19 noetherNormal(id);     noether normalization of ideal id
20 mapIsFinite(R,phi,I);  query for finiteness of map phi:R --> basering/I
21
22 finitenessTest(i,z);   find variables which occur as pure power in lead(i)
23 nonZeroEntry(id);      list describing non-zero entries of an identifier
24";
25
26 LIB "inout.lib";
27 LIB "elim.lib";
28 LIB "ring.lib";
29 LIB "matrix.lib";
30
31///////////////////////////////////////////////////////////////////////////////
32
33proc algebra_containment (poly p, ideal A, list #)
34"USAGE:   algebra_containment(p,A[,k]); p poly, A ideal, k integer.
35@*       A = A[1],...,A[m] generators of subalgebra of the basering
36RETURN:
37@format
38         - k=0 (or if k is not given) an integer:
39           1  : if p is contained in the subalgebra K[A[1],...,A[m]]
40           0  : if p is not contained in K[A[1],...,A[m]]
41         - k=1 : a list, say l, of size 2, l[1] integer, l[2] ring, satisfying
42           l[1]=1 if p is in the subalgebra K[A[1],...,A[m]] and then the ring
43           l[2]: ring, contains poly check = h(y(1),...,y(m)) if p=h(A[1],...,A[m])
44           l[1]=0 if p is not in the subalgebra K[A[1],...,A[m]] and then
45           l[2] contains the poly check = h(x,y(1),...,y(m)) if p satisfies
46           the nonlinear relation p = h(x,A[1],...,A[m]) where
47           x = x(1),...,x(n) denote the variables of the basering
48@end format
49DISPLAY: if k=0 and printlevel >= voice+1 (default) display the polynomial check
50NOTE:    The proc inSubring uses a different algorithm which is sometimes
51         faster.
52THEORY:  The ideal of algebraic relations of the algebra generators A[1],...,
53         A[m] is computed introducing new variables y(i) and the product
54         order with x(i) >> y(i).
55         p reduces to a polynomial only in the y(i) <=> p is contained in the
56         subring generated by the polynomials A[1],...,A[m].
57EXAMPLE: example algebra_containment; shows an example
58"
59{ int DEGB = degBound;
60  degBound = 0;
61    if (size(#)==0)
62    { #[1] = 0;
63    }
64    def br=basering;
65    int n = nvars(br);
66    int m = ncols(A);
67    int i;
68    string mp=string(minpoly);
69    //-----------------
70    // neu CL 10/05:
71    int is_qring;
72    if (size(ideal(br))>0) {
73      is_qring=1;
74      ideal IdQ = ideal(br);
75    }
76    //-----------------
77    // ---------- create new ring with extra variables --------------------
78    execute ("ring R=("+charstr(br)+"),(x(1..n),y(1..m)),(dp(n),dp(m));");
79    execute ("minpoly=number("+mp+");");
80    ideal vars=x(1..n);
81    map emb=br,vars;
82    ideal A=ideal(emb(A));
83    poly check=emb(p);
84    for (i=1;i<=m;i=i+1)
85    { A[i]=A[i]-y(i);
86    }
87    //-----------------
88    // neu CL 10/05:
89    if (is_qring) { A = A,emb(IdQ); }
90    //-----------------
91    A=std(A);
92    check=reduce(check,A);
93    /*alternatively we could use reduce(check,A,1) which is a little faster
94      but result is bigger since it is not tail-reduced
95    */
96  //--- checking whether all variables from old ring have disappeared ------
97  // if so, then the sum of the first n leading exponents is 0, hence i=1
98  // use i also to control the display
99    i = (sum(leadexp(check),1..n)==0);
100  degBound = DEGB;
101    if( #[1] == 0 )
102    { dbprint(printlevel-voice+3,"// "+string(check));
103      return(i);
104    }
105    else
106    { list l = i,R;
107      kill A,vars,emb;
108      export check;
109      dbprint(printlevel-voice+3,"
110// 'algebra_containment' created a ring as 2nd element of the list.
111// The ring contains the polynomial check which defines the algebraic relation.
112// To access to the ring and see check you must give the ring a name,
113// e.g.:
114               def S = l[2]; setring S; check;
115        ");
116     return(l);
117    }
118}
119example
120{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:"; echo=2;
121   int p = printlevel; printlevel = 1;
122   ring R = 0,(x,y,z),dp;
123   ideal A=x2+y2,z2,x4+y4,1,x2z-1y2z,xyz,x3y-1xy3;
124   poly p1=z;
125   poly p2=
126   x10z3-x8y2z3+2x6y4z3-2x4y6z3+x2y8z3-y10z3+x6z4+3x4y2z4+3x2y4z4+y6z4;
127   algebra_containment(p1,A);
128   algebra_containment(p2,A);
129   list L = algebra_containment(p2,A,1);
130   L[1];
131   def S = L[2]; setring S;
132   check;
133   printlevel = p;
134}
135///////////////////////////////////////////////////////////////////////////////
136
137proc module_containment(poly p, ideal P, ideal S, list #)
138"USAGE:   module_containment(p,P,M[,k]); p poly, P ideal, M ideal, k int
139@*       P = P[1],...,P[n] generators of a subalgebra of the basering,
140@*       M = M[1],...,M[m] generators of a module over the subalgebra K[P]
141ASSUME:  ncols(P) = nvars(basering), the P[i] are algebraically independent
142RETURN:
143@format
144         - k=0 (or if k is not given), an integer:
145           1    : if p is contained in the module <M[1],...,M[m]> over K[P]
146           0    : if p is not contained in <M[1],...,M[m]>
147         - k=1, a list, say l, of size 2, l[1] integer, l[2] ring:
148           l[1]=1 : if p is in <M[1],...,M[m]> and then the ring l[2] contains
149             the polynomial check = h(y(1),...,y(m),z(1),...,z(n)) if
150             p = h(M[1],...,M[m],P[1],...,P[n])
151           l[1]=0 : if p is in not in <M[1],...,M[m]>, then l[2] contains the
152             poly check = h(x,y(1),...,y(m),z(1),...,z(n)) if p satisfies
153             the nonlinear relation p = h(x,M[1],...,M[m],P[1],...,P[n]) where
154             x = x(1),...,x(n) denote the variables of the basering
155@end format
156DISPLAY: the polynomial h(y(1),...,y(m),z(1),...,z(n)) if k=0, resp.
157         a comment how to access the relation check if k=1, provided
158         printlevel >= voice+1 (default).
159THEORY:  The ideal of algebraic relations of all the generators p1,...,pn,
160         s1,...,st given by P and S is computed introducing new variables y(j),
161         z(i) and the product order: x^a*y^b*z^c > x^d*y^e*z^f if x^a > x^d
162         with respect to the lp ordering or else if z^c > z^f with respect to
163         the dp ordering or else if y^b > y^e with respect to the lp ordering
164         again. p reduces to a polynomial only in the y(j) and z(i), linear in
165         the z(i) <=> p is contained in the module.
166EXAMPLE: example module_containment; shows an example
167"
168{ def br=basering;
169  int DEGB = degBound;
170  degBound=0;
171  if (size(#)==0)
172  { #[1] = 0;
173  }
174  int n=nvars(br);
175  if ( ncols(P)==n )
176  { int m=ncols(S);
177    string mp=string(minpoly);
178  // ---------- create new ring with extra variables --------------------
179    execute
180   ("ring R=("+charstr(br)+"),(x(1..n),y(1..m),z(1..n)),(lp(n),dp(m),lp(n));");
181    execute ("minpoly=number("+mp+");");
182    ideal vars = x(1..n);
183    map emb = br,vars;
184    ideal P = emb(P);
185    ideal S  = emb(S);
186    poly check = emb(p);
187    ideal I;
188    for (int i=1;i<=m;i=i+1)
189    { I[i]=S[i]-y(i);
190    }
191    for (i=1;i<=n;i=i+1)
192    { I[m+i]=P[i]-z(i);
193    }
194    I=std(I);
195    check = reduce(check,I);
196  //--- checking whether all variables from old ring have disappeared ------
197  // if so, then the sum of the first n leading exponents is 0
198    i = (sum(leadexp(check),1..n)==0);
199    if( #[1] == 0 )
200    { dbprint(i*(printlevel-voice+3),"// "+string(check));
201      return(i);
202    }
203    else
204    { list l = i,R;
205      kill I,vars,emb,P,S;
206      export check;
207      dbprint(printlevel-voice+3,"
208// 'module_containment' created a ring as 2nd element of the list. The
209// ring contains the polynomial check which defines the algebraic relation
210// for p. To access to the ring and see check you must give the ring
211// a name, e.g.:
212     def S = l[2]; setring S; check;
213      ");
214      return(l);
215    }
216  }
217  else
218  { "ERROR: the first ideal must have nvars(basering) entries";
219    return();
220  }
221}
222example
223{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:"; echo=2;
224   int p = printlevel; printlevel = 1;
225   ring R=0,(x,y,z),dp;
226   ideal P = x2+y2,z2,x4+y4;           //algebra generators
227   ideal M = 1,x2z-1y2z,xyz,x3y-1xy3;  //module generators
228   poly p1=
229   x10z3-x8y2z3+2x6y4z3-2x4y6z3+x2y8z3-y10z3+x6z4+3x4y2z4+3x2y4z4+y6z4;
230   module_containment(p1,P,M);
231   poly p2=z;
232   list l = module_containment(p2,P,M,1);
233   l[1];
234   def S = l[2]; setring S; check;
235   printlevel=p;
236}
237///////////////////////////////////////////////////////////////////////////////
238
239proc inSubring(poly p, ideal I)
240"USAGE:   inSubring(p,i); p poly, i ideal
241RETURN:
242@format
243         a list l of size 2, l[1] integer, l[2] string
244         l[1]=1 if and only if p is in the subring generated by i=i[1],...,i[k],
245                and then l[2] = y(0)-h(y(1),...,y(k)) if p = h(i[1],...,i[k])
246         l[1]=0 if and only if p is in not the subring generated by i,
247                and then l[2] = h(y(0),y(1),...,y(k)) where p satisfies the
248                nonlinear relation h(p,i[1],...,i[k])=0.
249@end format
250NOTE:    the proc algebra_containment tests the same using a different
251         algorithm, which is often faster
252         if l[1] == 0 then l[2] may contain more than one relation h(y(0),y(1),...,y(k)),
253         separated by comma
254EXAMPLE: example inSubring; shows an example
255"
256{int z=ncols(I);
257  int i;
258  def gnir=basering;
259  int n = nvars(gnir);
260  string mp=string(minpoly);
261  list l;
262  // neu CL 10/05:
263  int is_qring;
264  if (size(ideal(gnir))>0) {
265    is_qring=1;
266    ideal IdQ = ideal(gnir);
267  }
268  // ---------- create new ring with extra variables --------------------
269  //the intersection of ideal nett=(p-y(0),I[1]-y(1),...)
270  //with the ring k[y(0),...,y(n)] is computed, the result is ker
271   execute ("ring r1= ("+charstr(basering)+"),(x(1..n),y(0..z)),lp;");
272 //  execute ("ring r1= ("+charstr(basering)+"),(y(0..z),x(1..n)),dp;");
273  execute ("minpoly=number("+mp+");");
274  ideal va = x(1..n);
275  map emb = gnir,va;
276  ideal nett = emb(I);
277  for (i=1;i<=z;i++)
278  { nett[i]=nett[i]-y(i);
279  }
280  nett=emb(p)-y(0),nett;
281  // neu CL 10/05:
282  if (is_qring) { nett = nett,emb(IdQ); }
283  //-----------------
284  ideal ker=eliminate(nett,product(va));
285  ker=std(ker);
286  //---------- test wether y(0)-h(y(1),...,y(z)) is in ker --------------
287  l[1]=0;
288  l[2]="";
289  for (i=1;i<=size(ker);i++)
290  { if (deg(ker[i]/y(0))==0)
291     { string str=string(ker[i]);
292        setring gnir;
293        l[1]=1;
294        l[2]=str;
295        return(l);
296     }
297     if (deg(ker[i]/y(0))>0)
298     { if( l[2] != "" ){ l[2] = l[2] + ","; }
299       l[2] = l[2] + string(ker[i]);
300     }
301  }
302  return(l);
303}
304example
305{ "EXAMPLE:"; echo = 2;
306   ring q=0,(x,y,z,u,v,w),dp;
307   poly p=xyzu2w-1yzu2w2+u4w2-1xu2vw+u2vw2+xyz-1yzw+2u2w-1xv+vw+2;
308   ideal I =x-w,u2w+1,yz-v;
309   inSubring(p,I);
310}
311//////////////////////////////////////////////////////////////////////////////
312
313proc algDependent( ideal A, list # )
314"USAGE:   algDependent(f[,c]); f ideal (say, f = f1,...,fm), c integer
315RETURN:
316@format
317         a list l  of size 2, l[1] integer, l[2] ring:
318         - l[1] = 1 if f1,...,fm are algebraic dependent, 0 if not
319         - l[2] is a ring with variables x(1),...,x(n),y(1),...,y(m) if the
320           basering has n variables. It contains the ideal 'ker', depending
321           only on the y(i) and generating the algebraic relations between the
322           f[i], i.e. substituting y(i) by fi yields 0. Of course, ker is
323           nothing but the kernel of the ring map
324              K[y(1),...,y(m)] ---> basering,  y(i) --> fi.
325@end format
326NOTE:    Three different algorithms are used depending on c = 1,2,3.
327         If c is not given or c=0, a heuristically best method is chosen.
328         The basering may be a quotient ring.
329         To access to the ring l[2] and see ker you must give the ring a name,
330         e.g. def S=l[2]; setring S; ker;
331DISPLAY: The above comment is displayed if printlevel >= 0 (default).
332EXAMPLE: example algDependent; shows an example
333"
334{
335    int bestoption = 3;
336    // bestoption is the default algorithm, it may be set to 1,2 or 3;
337    // it should be changed, if another algorithm turns out to be faster
338    // in general. Is perhaps dependent on the input (# vars, size ...)
339    int tt;
340    if( size(#) > 0 )
341    { if( typeof(#[1]) == "int" )
342      { tt = #[1];
343      }
344    }
345    if( size(#) == 0 or tt == 0 )
346    { tt = bestoption;
347    }
348    def br=basering;
349    int n = nvars(br);
350    ideal B = ideal(br);
351    int m = ncols(A);
352    int s = size(B);
353    int i;
354    string mp = string(minpoly);
355 // --------------------- 1st variant of algorithm ----------------------
356 // use internal preimage command (should be equivalent to 2nd variant)
357    if ( tt == 1 )
358    {
359      execute ("ring R1=("+charstr(br)+"),y(1..m),dp;");
360      execute ("minpoly=number("+mp+");");
361      setring br;
362      map phi = R1,A;
363      setring R1;
364      ideal ker = preimage(br,phi,B);
365    }
366 // ---------- create new ring with extra variables --------------------
367    execute ("ring R2=("+charstr(br)+"),(x(1..n),y(1..m)),(dp);");
368    execute ("minpoly=number("+mp+");");
369    if( tt == 1 )
370    {
371      ideal ker = imap(R1,ker);
372    }
373    else
374    {
375      ideal vars = x(1..n);
376      map emb = br,vars;
377      ideal A = emb(A);
378      for (i=1; i<=m; i=i+1)
379      { A[i] = A[i]-y(i);
380      }
381 // --------------------- 2nd variant of algorithm ----------------------
382 // use internal eliminate for eliminating m variables x(i) from
383 // ideal A[i] - y(i) (uses extra eliminating 'first row', a-order)
384      if ( s == 0 and  tt == 2  )
385      { ideal ker = eliminate(A,product(vars));
386      }
387      else
388 // eliminate does not work in qrings
389 // --------------------- 3rd variant of algorithm ----------------------
390 // eliminate m variables x(i) from ideal A[i] - y(i) by choosing product
391 // order
392       {execute ("ring R3=("+charstr(br)+"),(x(1..n),y(1..m)),(dp(n),dp(m));");
393        execute ("minpoly=number("+mp+");");
394        if ( s != 0 )
395        { ideal vars = x(1..n);
396          map emb = br,vars;
397          ideal B = emb(B);
398          attrib(B,"isSB",1);
399          qring Q = B;
400        }
401        ideal A = imap(R2,A);
402        A = std(A);
403        ideal ker = nselect(A,1..n);
404        setring R2;
405        if ( defined(Q)==voice )
406        { ideal ker = imap(Q,ker);
407        }
408        else
409        { ideal ker = imap(R3,ker);
410        }
411        kill A,emb,vars;
412      }
413    }
414 // --------------------------- return ----------------------------------
415    s = size(ker);
416    list L = (s!=0), R2;
417    export(ker);
418    dbprint(printlevel-voice+3,"
419// The 2nd element of the list l is a ring with variables x(1),...,x(n),
420// and y(1),...,y(m) if the basering has n variables and if the ideal
421// is f[1],...,f[m]. The ring contains the ideal ker which depends only
422// on the y(i) and generates the relations between the f[i].
423// I.e. substituting y(i) by f[i] yields 0.
424// To access to the ring and see ker you must give the ring a name,
425// e.g.:
426             def S = l[2]; setring S; ker;
427        ");
428    return (L);
429}
430example
431{ "EXAMPLE:"; echo = 2;
432   int p = printlevel; printlevel = 1;
433   ring R = 0,(x,y,z,u,v,w),dp;
434   ideal I = xyzu2w-1yzu2w2+u4w2-1xu2vw+u2vw2+xyz-1yzw+2u2w-1xv+vw+2,
435             x-w, u2w+1, yz-v;
436   list l = algDependent(I);
437   l[1];
438   def S = l[2]; setring S;
439   ker;
440   printlevel = p;
441}
442//////////////////////////////////////////////////////////////////////////////
443proc alg_kernel( map phi, pr, list #)
444"USAGE:   alg_kernel(phi,pr[,s,c]); phi map to basering, pr preimage ring,
445         s string (name of kernel in pr), c integer.
446RETURN:  a string, the kernel of phi as string.
447         If, moreover, a string s is given, the algorithm creates, in the
448         preimage ring pr the kernel of phi with name s.
449         Three different algorithms are used depending on c = 1,2,3.
450         If c is not given or c=0, a heuristically best method is chosen.
451         (algorithm 1 uses the preimage command)
452NOTE:    Since the kernel of phi lives in pr, it cannot be returned to the
453         basering. If s is given, the user has access to it in pr via s.
454         The basering may be a quotient ring.
455EXAMPLE: example alg_kernel; shows an example
456"
457{   int tt;
458   if( size(#) >0 )
459   { if( typeof(#[1]) == "int")
460     { tt = #[1];
461     }
462     if( typeof(#[1]) == "string")
463     { string nker=#[1];
464     }
465     if( size(#)>1 )
466     {  if( typeof(#[2]) == "string")
467        { string nker=#[2];
468        }
469        if( typeof(#[2]) == "int")
470       {  tt = #[2];
471       }
472     }
473   }
474    int n = nvars(basering);
475    string mp = string(minpoly);
476    ideal A = ideal(phi);
477    //def pr = preimage(phi);
478    //folgendes Auffuellen oder Stutzen ist ev nicht mehr noetig
479    //falls map das richtig macht
480    int m = nvars(pr);
481    ideal j;
482    j[m]=0;
483    A=A,j;
484    A=A[1..m];
485    list L = algDependent(A,tt);
486    // algDependent is called with "bestoption" if tt = 0
487    def S = L[2];
488    execute ("ring R=("+charstr(basering)+"),(@(1..n),"+varstr(pr)+"),(dp);");
489    execute ("minpoly=number("+mp+");");
490    ideal ker = fetch(S,ker);       //in order to have variable names correct
491    string sker = string(ker);
492    if (defined(nker) == voice)
493    { setring pr;
494      execute("ideal "+nker+"="+sker+";");
495      execute("export("+nker+");");
496     }
497    return(sker);
498}
499example
500{ "EXAMPLE:"; echo = 2;
501   ring r = 0,(a,b,c),ds;
502   ring s = 0,(x,y,z,u,v,w),dp;
503   ideal I = x-w,u2w+1,yz-v;
504   map phi = r,I;                // a map from r to s:
505   alg_kernel(phi,r);            // a,b,c ---> x-w,u2w+1,yz-v
506
507   ring S = 0,(a,b,c),ds;
508   ring R = 0,(x,y,z),dp;
509   qring Q = std(x-y);
510   ideal i = x, y, x2-y3;
511   map phi = S,i;                 // a map to a quotient ring
512   alg_kernel(phi,S,"ker",3);     // uses algorithm 3
513   setring S;                     // you have access to kernel in preimage
514   ker;
515}
516//////////////////////////////////////////////////////////////////////////////
517
518proc is_injective( map phi, pr,list #)
519"USAGE:   is_injective(phi,pr[,c,s]); phi map, pr preimage ring, c int, s string
520RETURN:
521@format
522         - 1 (type int) if phi is injective, 0 if not (if s is not given).
523         - If s is given, return a list l of size 2, l[1] int, l[2] ring:
524           l[1] is 1 if phi is injective, 0 if not
525           l[2] is a ring with variables x(1),...,x(n),y(1),...,y(m) if the
526           basering has n variables and the map m components, it contains the
527           ideal 'ker', depending only on the y(i), the kernel of the given map
528@end format
529NOTE:    Three differnt algorithms are used depending on c = 1,2,3.
530         If c is not given or c=0, a heuristically best method is chosen.
531         The basering may be a quotient ring. However, if the preimage ring is
532         a quotient ring, say pr = P/I, consider phi as a map from P and then
533         the algorithm returns 1 if the kernel of phi is 0 mod I.
534         To access to the ring l[2] and see ker you must give the ring a name,
535         e.g. def S=l[2]; setring S; ker;
536DISPLAY: The above comment is displayed if printlevel >= 0 (default).
537EXAMPLE: example is_injective; shows an example
538"
539{  def bsr = basering;
540   int tt;
541   if( size(#) >0 )
542   { if( typeof(#[1]) == "int")
543     { tt = #[1];
544     }
545     if( typeof(#[1]) == "string")
546     { string pau=#[1];
547     }
548     if( size(#)>1 )
549     {  if( typeof(#[2]) == "string")
550        { string pau=#[2];
551        }
552        if( typeof(#[2]) == "int")
553       {  tt = #[2];
554       }
555     }
556   }
557    int n = nvars(basering);
558    string mp = string(minpoly);
559    ideal A = ideal(phi);
560    //def pr = preimage(phi);
561    //folgendes Auffuellen oder Stutzen ist ev nicht mehr noetig
562    //falls map das richtig macht
563    int m = nvars(pr);
564    ideal j;
565    j[m]=0;
566    A=A,j;
567    A=A[1..m];
568    list L = algDependent(A,tt);
569    L[1] = L[1]==0;
570// the preimage ring may be a quotient ring, we still have to check whether
571// the kernel is 0 mod ideal of the quotient ring
572    setring pr;
573    if ( size(ideal(pr)) != 0 )
574    { def S = L[2];
575      ideal proj;
576      proj [n+1..n+m] = maxideal(1);
577      map psi = S,proj;
578      L[1] = size(NF(psi(ker),std(0))) == 0;
579    }
580    if ( defined(pau) != voice )
581    {  return (L[1]);
582    }
583    else
584    {
585      dbprint(printlevel-voice+3,"
586// The 2nd element of the list is a ring with variables x(1),...,x(n),
587// y(1),...,y(m) if the basering has n variables and the map is
588// F[1],...,F[m].
589// It contains the ideal ker, the kernel of the given map y(i) --> F[i].
590// To access to the ring and see ker you must give the ring a name,
591// e.g.:
592     def S = l[2]; setring S; ker;
593        ");
594      return(L);
595    }
596 }
597example
598{ "EXAMPLE:"; echo = 2;
599   int p = printlevel;
600   ring r = 0,(a,b,c),ds;
601   ring s = 0,(x,y,z,u,v,w),dp;
602   ideal I = x-w,u2w+1,yz-v;
603   map phi = r,I;                    // a map from r to s:
604   is_injective(phi,r);              // a,b,c ---> x-w,u2w+1,yz-v
605   ring R = 0,(x,y,z),dp;
606   ideal i = x, y, x2-y3;
607   map phi = R,i;                    // a map from R to itself, z --> x2-y3
608   list l = is_injective(phi,R,"");
609   l[1];
610   def S = l[2]; setring S;
611   ker;
612}
613///////////////////////////////////////////////////////////////////////////////
614
615proc is_surjective( map phi )
616"USAGE:   is_surjective(phi); phi map to basering, or ideal defining it
617RETURN:  an integer,  1 if phi is surjective, 0 if not
618NOTE:    The algorithm returns 1 if and only if all the variables of the basering are
619         contained in the polynomial subalgebra generated by the polynomials
620         defining phi. Hence, it tests surjectivity in the case of a global odering.
621         If the basering has local or mixed ordering or if the preimage ring is a
622         quotient ring (in which case the map may not be well defined) then the return
623         value 1 needs to be interpreted with care.
624EXAMPLE: example is_surjective; shows an example
625"
626{
627  def br=basering;
628    ideal B = ideal(br);
629    int s = size(B);
630    int n = nvars(br);
631    ideal A = ideal(phi);
632    int m = ncols(A);
633    int ii,t=1,1;
634    string mp=string(minpoly);
635  // ------------ create new ring with extra variables ---------------------
636    execute ("ring R=("+charstr(br)+"),(x(1..n),y(1..m)),(dp(n),dp(m));");
637    execute ("minpoly=number("+mp+");");
638    ideal vars = x(1..n);
639    map emb = br,vars;
640    if ( s != 0 )
641    {  ideal B = emb(B);
642       attrib(B,"isSB",1);
643       qring Q = B;
644       ideal vars = x(1..n);
645       map emb = br,vars;
646    }
647    ideal A = emb(A);
648    for ( ii=1; ii<=m; ii++ )
649    { A[ii] = A [ii]-y(ii);
650    }
651    A=std(A);
652  // ------------- check whether the x(i) are in the image -----------------
653    poly check;
654    for (ii=1; ii<=n; ii++ )
655    {  check=reduce(x(ii),A,1);
656  // --- checking whether all variables from old ring have disappeared -----
657  // if so, then the sum of the first n leading exponents is 0
658       if( sum(leadexp(check),1..n)!=0 )
659       { t=0;
660         break;
661       }
662    }
663   return(t);
664}
665example
666{ "EXAMPLE:"; echo = 2;
667   ring R = 0,(x,y,z),dp;
668   ideal i = x, y, x2-y3;
669   map phi = R,i;                    // a map from R to itself, z->x2-y3
670   is_surjective(phi);
671   qring Q = std(ideal(z-x37));
672   map psi = R, x,y,x2-y3;           // the same map to the quotient ring
673   is_surjective(psi);
674
675   ring S = 0,(a,b,c),dp;
676   map psi = R,ideal(a,a+b,c-a2+b3); // a map from R to S,
677   is_surjective(psi);               // x->a, y->a+b, z->c-a2+b3
678}
679
680///////////////////////////////////////////////////////////////////////////////
681
682proc is_bijective ( map phi, pr )
683"USAGE:   is_bijective(phi,pr); phi map to basering, pr preimage ring
684RETURN:  an integer,  1 if phi is bijective, 0 if not
685NOTE:    The algorithm checks first injectivity and then surjectivity.
686         To interprete this for local/mixed orderings, or for quotient rings
687         type help is_surjective; and help is_injective;
688DISPLAY: A comment if printlevel >= voice-1 (default)
689EXAMPLE: example is_bijective; shows an example
690"
691{
692  def br = basering;
693    int n = nvars(br);
694    ideal B = ideal(br);
695    int s = size(B);
696    ideal A = ideal(phi);
697    //folgendes Auffuellen oder Stutzen ist ev nicht mehr noetig
698    //falls map das richtig macht
699    int m = nvars(pr);
700    ideal j;
701    j[m]=0;
702    A=A,j;
703    A=A[1..m];
704    int ii,t = 1,1;
705    string mp=string(minpoly);
706  // ------------ create new ring with extra variables ---------------------
707    execute ("ring R=("+charstr(br)+"),(x(1..n),y(1..m)),(dp(n),dp(m));");
708    execute ("minpoly=number("+mp+");");
709    ideal vars = x(1..n);
710    map emb = br,vars;
711    if ( s != 0 )
712    {  ideal B = emb(B);
713       attrib(B,"isSB",1);
714       qring Q = B;
715       ideal vars = x(1..n);
716       map emb = br,vars;
717    }
718    ideal A = emb(A);
719    for ( ii=1; ii<=m; ii++ )
720    { A[ii] = A[ii]-y(ii);
721    }
722    A=std(A);
723    def bsr = basering;
724 // ------- checking whether phi is injective by computing the kernel -------
725    ideal ker = nselect(A,1..n);
726    t = size(ker);
727    setring pr;
728    if ( size(ideal(pr)) != 0 )
729    {
730      ideal proj;
731      proj[n+1..n+m] = maxideal(1);
732      map psi = bsr,proj;
733      t = size(NF(psi(ker),std(0)));
734    }
735    if ( t != 0 )
736    {  dbprint(printlevel-voice+3,"// map not injective" );
737      return(0);
738    }
739   else
740 // -------------- checking whether phi is surjective ----------------------
741   { t = 1;
742     setring bsr;
743     poly check;
744     for (ii=1; ii<=n; ii++ )
745     {  check=reduce(x(ii),A,1);
746  // --- checking whether all variables from old ring have disappeared -----
747  // if so, then the sum of the first n leading exponents is 0
748        if( sum(leadexp(check),1..n)!=0 )
749        { t=0;
750          break;
751        }
752     }
753     if ( t == 0 )
754     {  dbprint(printlevel-voice+3,"// map injective, but not surjective" );
755     }
756     return(t);
757   }
758}
759example
760{ "EXAMPLE:"; echo = 2;
761   int p = printlevel;  printlevel = 1;
762   ring R = 0,(x,y,z),dp;
763   ideal i = x, y, x2-y3;
764   map phi = R,i;                      // a map from R to itself, z->x2-y3
765   is_bijective(phi,R);
766   qring Q = std(z-x2+y3);
767   is_bijective(ideal(x,y,x2-y3),Q);
768
769   ring S = 0,(a,b,c,d),dp;
770   map psi = R,ideal(a,a+b,c-a2+b3,0); // a map from R to S,
771   is_bijective(psi,R);                // x->a, y->a+b, z->c-a2+b3
772   qring T = std(d,c-a2+b3);
773   map chi = Q,a,b,a2-b3;              // amap between two quotient rings
774   is_bijective(chi,Q);
775
776   printlevel = p;
777}
778///////////////////////////////////////////////////////////////////////////////
779
780proc noetherNormal(ideal i, list #)
781"USAGE:   noetherNormal(id[,p]);  id ideal, p integer
782RETURN:
783@format
784         a list l of two ideals, say I,J:
785         - I defines a map (coordinate change in the basering), such that:
786         - J is generated by a subset of the variables with size(J) = dim(id)
787           if we define  map phi=basering,I;
788           then k[var(1),...,var(n)]/phi(id) is finite over k[J].
789         If p is given, 0<=p<=100, a sparse coordinate change with p percent
790         of the matrix entries being 0 (default: p=0 i.e. dense)
791@end format
792NOTE:    Designed for characteristic 0.It works also in char k > 0 if it
793         terminates,but may result in an infinite loop in small characteristic.
794EXAMPLE: example noetherNormal; shows an example
795"
796{
797   i=simplify(i,2);
798   if ( i== 0)
799   {
800     list l = maxideal(1),maxideal(1);
801     return( l );
802   }
803   int p;
804   if( size(#) != 0 )
805   {
806     p = #[1];
807   }
808   def r = basering;
809   int n = nvars(r);
810   list good;
811   // ------------------------ change of ordering ---------------------------
812   //a procedure from ring.lib changing the order to dp creating a new
813   //basering @R in order to compute the dimension d of i
814   def @R=changeord(list(list("dp",1:nvars(basering))));
815   setring @R;
816   ideal i = imap(r,i);
817   list j = mstd(i);
818   i = j[2];
819   int d = dim(j[1]);
820   if ( d <= 0)
821   {
822     setring r;
823     list l = maxideal(1),ideal(0);
824     return( l );
825   }
826   // ------------------------ change of ordering ---------------------------
827   //Now change the order to (dp(n-d),lp) creating a new basering @S
828   def @S=changeord(list(list("dp",1:(n-d)),list("lp",1:d)));
829   setring @S;
830   ideal m;
831
832   // ----------------- sparse-random coordinate change  --------------------
833   //creating lower triangular random generators for the maximal ideal
834   //a procedure from random.lib, as sparse as possible
835   if(  char(@S) >  0 )
836   {
837      m=ideal(sparsetriag(n,n,p,char(@S)+1)*transpose(maxideal(1)));
838   }
839   if(  char(@S) == 0 )
840   {
841      if ( voice <= 6 )
842      {
843        m=ideal(sparsetriag(n,n,p,10)*transpose(maxideal(1)));
844      }
845     if( voice > 6 and voice <= 11)
846     {
847        m=ideal(sparsetriag(n,n,p,100)*transpose(maxideal(1)));
848      }
849      if ( voice > 11 )
850      {
851        m=ideal(sparsetriag(n,n,p,30000)*transpose(maxideal(1)));
852      }
853   }
854
855   map phi=r,m;
856   //map phi=@R,m;
857   ideal i=std(phi(i));
858
859   // ----------------------- test for finiteness ---------------------------
860   //We need a test whether the coordinate change was random enough, if yes
861   //we are ready, else call noetherNormal again
862   list l=finitenessTest(i);
863
864   setring r;
865   list l=imap(@S,l);
866
867   if(size(l[3]) == d)                    //the generic case
868   {
869      good = fetch(@S,m),l[3];
870      kill @S,@R;
871      return(good);
872   }
873   else                                   //the bad case
874   { kill @S,@R;
875      if ( voice >= 21 )
876      {
877       "// WARNING: In case of a finite ground field";
878       "// the characteristic may be too small.";
879       "// This could result in an infinte loop.";
880       "// Loop in noetherNormal, voice:";, voice;"";
881      }
882     if ( voice >= 16 )
883     {
884       "// Switch to dense coordinate change";"";
885       return(noetherNormal(i));
886     }
887     return(noetherNormal(i,p));
888   }
889}
890example
891{ "EXAMPLE:"; echo = 2;
892   ring r=0,(x,y,z),dp;
893   ideal i= xy,xz;
894   noetherNormal(i);
895}
896///////////////////////////////////////////////////////////////////////////////
897
898proc finitenessTest(ideal i, list #)
899"USAGE:   finitenessTest(J[,v]); J ideal, v intvec (say v1,...,vr with vi>0)
900RETURN:
901@format
902         a list l with l[1] integer, l[2], l[3], l[4] ideals
903         - l[1] = 1 if var(v1),...,var(vr) are in l[2] and 0 else
904         - l[2] (resp. l[3]) contains those variables which occur,
905           (resp. do not occur) as pure power in the leading term of one of the
906           generators of J,
907         - l[4] contains those J[i] for which the leading term is a pure power
908           of a variable (which is then in l[2])
909         (default: v = [1,2,..,nvars(basering)])
910@end format
911THEORY:  If J is a standard basis of an ideal generated by x_1 - f_1(y),...,
912         x_n - f_n with y_j ordered lexicographically and y_j >> x_i, then,
913         if y_i appears as pure power in the leading term of J[k], J[k] defines
914         an integral relation for y_i over the y_(i+1),... and the f's.
915         Moreover, in this situation, if l[2] = y_1,...,y_r, then K[y_1,...y_r]
916         is finite over K[f_1..f_n]. If J contains furthermore polynomials
917         h_j(y), then K[y_1,...y_z]/<h_j> is finite over K[f_1..f_n].
918         For a proof cf. Prop. 3.1.5, p. 214. in [G.-M. Greuel, G. Pfister:
919         A SINGULAR Introduction to Commutative Algebra, 2nd Edition,
920         Springer Verlag (2007)]
921EXAMPLE: example finitenessTest; shows an example
922"
923{  int n = nvars(basering);
924   intvec v,w;
925   int j,z,ii;
926   v[n]=0;                             //v should have size n
927   intvec V = 1..n;
928   list nze;                           //the non-zero entries of a leadexp
929   if (size(#) != 0 )
930   {
931     V = #[1];
932   }
933   intmat W[1][n];                     //create intmat with 1 row, having 1 at
934                                       //position V[j], i = 1..size(V), 0 else
935   for( j=1; j<=size(V); j++ )
936   {
937     W[1,V[j]] = 1;
938   }
939   ideal relation,zero,nonzero;
940   // ---------------------- check leading exponents -------------------------
941
942   for(j=1;j<=ncols(i);j++)
943   {
944      w = leadexp(i[j]);
945      nze = nonZeroEntry(w);
946      if( nze[1] == 1 )               //the leading term of i[j] is a
947      {                               //pure power of some variable
948        if( W*w != 0 )                //case: variable has index appearing in V
949        {
950          relation[size(relation)+1] = i[j];
951          v=v+w;
952        }
953      }
954   }
955   // ----------------- pick the corresponding variables ---------------------
956   //the nonzero entries of v correspond to variables which occur as
957   //pure power in the leading term of some polynomial in i
958
959   for(j=1; j<=size(v); j++)
960   {
961      if(v[j]==0)
962      {
963         zero[size(zero)+1]=var(j);
964      }
965      else
966      {
967        nonzero[size(nonzero)+1]=var(j);
968      }
969   }
970   // ---------------- do we have all pure powers we want? -------------------
971   // test this by dividing the product of corresponding variables
972   ideal max = maxideal(1);
973   max = max[V];
974   z = (product(nonzero)/product(max) != 0);
975   return(list(z,nonzero,zero,relation));
976}
977example
978{ "EXAMPLE:"; echo = 2;
979   ring s = 0,(x,y,z,a,b,c),(lp(3),dp);
980   ideal i= a -(xy)^3+x2-z, b -y2-1, c -z3;
981   ideal j = a -(xy)^3+x2-z, b -y2-1, c -z3, xy;
982   finitenessTest(std(i),1..3);
983   finitenessTest(std(j),1..3);
984}
985///////////////////////////////////////////////////////////////////////////////
986
987proc mapIsFinite(map phi, R, list #)
988"USAGE:   mapIsFinite(phi,R[,J]); R the preimage ring of the map
989         phi: R ---> basering
990         J an ideal in the basering, J = 0 if not given
991RETURN:  1 if R ---> basering/J is finite and 0 else
992NOTE:    R may be a quotient ring (this will be ignored since a map R/I-->S/J
993         is finite if and only if the induced map R-->S/J is finite).
994SEE ALSO: finitenessTest
995EXAMPLE: example mapIsFinite; shows an example
996"
997{
998  def bsr = basering;
999  ideal J;
1000  if( size(#) != 0 )
1001  {
1002    J = #[1];
1003  }
1004  string os = ordstr(bsr);
1005  int m = nvars(bsr);
1006  int n = nvars(R);
1007  ideal PHI = ideal(phi);
1008  if ( ncols(PHI) < n )
1009  { PHI[n]=0;
1010  }
1011  // --------------------- change of variable names -------------------------
1012  execute("ring @bsr = ("+charstr(bsr)+"),y(1..m),("+os+");");
1013  ideal J = fetch(bsr,J);
1014  ideal PHI = fetch(bsr,PHI);
1015
1016  // --------------------------- enlarging ring -----------------------------
1017  execute("ring @rr = ("+charstr(bsr)+"),(y(1..m),x(1..n)),(lp(m),dp);");
1018  ideal J = imap(@bsr,J);
1019  ideal PHI = imap(@bsr,PHI);
1020  ideal M;
1021  int i;
1022
1023  for(i=1;i<=n;i++)
1024  {
1025    M[i]=x(i)-PHI[i];
1026  }
1027  M = std(M+J);
1028  // ----------------------- test for finiteness ---------------------------
1029  list l = finitenessTest(M,1..m);
1030  return(l[1]);
1031}
1032example
1033{ "EXAMPLE:"; echo = 2;
1034   ring r = 0,(a,b,c),dp;
1035   ring s = 0,(x,y,z),dp;
1036   ideal i= xy;
1037   map phi= r,(xy)^3+x2+z,y2-1,z3;
1038   mapIsFinite(phi,r,i);
1039}
1040//////////////////////////////////////////////////////////////////////////////
1041
1042proc nonZeroEntry(id)
1043"USAGE:  nonZeroEntry(id); id=object for which the test 'id[i]!=0', i=1,..,N,
1044         N=size(id) (resp. ncols(id) for id of type ideal or module)
1045         is defined (e.g. ideal, vector, list of polynomials, intvec,...)
1046RETURN:  @format
1047         a list, say l, with l[1] an integer, l[2], l[3] integer vectors:
1048         - l[1] number of non-zero entries of id
1049         - l[2] intvec of size l[1] with l[2][i]=i if id[i] != 0
1050           in case l[1]!=0 (and l[2]=0 if l[1]=0)
1051         - l[3] intvec with l[3][i]=1 if id[i]!=0 and l[3][i]=0 else
1052@end format
1053NOTE:
1054EXAMPLE: example nonZeroEntry; shows an example
1055"
1056{
1057   int ii,jj,N,n;
1058   intvec v,V;
1059
1060   if ( typeof(id) == "ideal" || typeof(id) == "module" )
1061   {
1062      N = ncols(id);
1063   }
1064   else
1065   {
1066     N = size(id);
1067   }
1068   for ( ii=1; ii<=N; ii++ )
1069   {
1070      V[ii] = 0;
1071      if ( id[ii] != 0 )
1072      {
1073         n++;
1074         v=v,ii;      //the first entry of v is always 0
1075         V[ii] = 1;
1076      }
1077   }
1078   if ( size(v) > 1 ) //if id[ii] != 0 for at least one ii delete the first 0
1079   {
1080      v = v[2..size(v)];
1081   }
1082
1083   list l = n,v,V;
1084   return(l);
1085}
1086example
1087{ "EXAMPLE:"; echo = 2;
1088   ring r = 0,(a,b,c),dp;
1089   poly f = a3c+b3+c2+a;
1090   intvec v = leadexp(f);
1091   nonZeroEntry(v);
1092
1093   intvec w;
1094   list L = 37,0,f,v,w;
1095   nonZeroEntry(L);
1096}
1097//////////////////////////////////////////////////////////////////////////////
1098
Note: See TracBrowser for help on using the repository browser.