source: git/Singular/LIB/algebra.lib @ 238c959

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