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

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