source: git/Singular/LIB/algebra.lib @ 9660f5

spielwiese
Last change on this file since 9660f5 was 9660f5, checked in by Motsak Oleksandr <motsak@…>, 15 years ago
*motsak: fixes due to O.Iena git-svn-id: file:///usr/local/Singular/svn/trunk@11621 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 35.9 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.20 2009-04-03 20:58:53 motsak 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
256         if l[1] == 0 then l[2] may contain more than one relation h(y(0),y(1),...,y(k)),
257         separated by comma
258EXAMPLE: example inSubring; shows an example
259"
260{int z=ncols(I);
261  int i;
262  def gnir=basering;
263  int n = nvars(gnir);
264  string mp=string(minpoly);
265  list l;
266  // neu CL 10/05:
267  int is_qring;
268  if (size(ideal(gnir))>0) {
269    is_qring=1;
270    ideal IdQ = ideal(gnir);
271  }
272  // ---------- create new ring with extra variables --------------------
273  //the intersection of ideal nett=(p-y(0),I[1]-y(1),...)
274  //with the ring k[y(0),...,y(n)] is computed, the result is ker
275   execute ("ring r1= ("+charstr(basering)+"),(x(1..n),y(0..z)),lp;");
276 //  execute ("ring r1= ("+charstr(basering)+"),(y(0..z),x(1..n)),dp;");
277  execute ("minpoly=number("+mp+");");
278  ideal va = x(1..n);
279  map emb = gnir,va;
280  ideal nett = emb(I);
281  for (i=1;i<=z;i++)
282  { nett[i]=nett[i]-y(i);
283  }
284  nett=emb(p)-y(0),nett;
285  // neu CL 10/05:
286  if (is_qring) { nett = nett,emb(IdQ); }
287  //-----------------
288  ideal ker=eliminate(nett,product(va));
289  ker=std(ker);
290  //---------- test wether y(0)-h(y(1),...,y(z)) is in ker --------------
291  l[1]=0;
292  l[2]="";
293  for (i=1;i<=size(ker);i++)
294  { if (deg(ker[i]/y(0))==0)
295     { string str=string(ker[i]);
296        setring gnir;
297        l[1]=1;
298        l[2]=str;
299        return(l);
300     }
301     if (deg(ker[i]/y(0))>0)
302     { if( l[2] != "" ){ l[2] = l[2] + ","; }
303       l[2] = l[2] + string(ker[i]);
304     }
305  }
306  return(l);
307}
308example
309{ "EXAMPLE:"; echo = 2;
310   ring q=0,(x,y,z,u,v,w),dp;
311   poly p=xyzu2w-1yzu2w2+u4w2-1xu2vw+u2vw2+xyz-1yzw+2u2w-1xv+vw+2;
312   ideal I =x-w,u2w+1,yz-v;
313   inSubring(p,I);
314}
315//////////////////////////////////////////////////////////////////////////////
316
317proc algDependent( ideal A, list # )
318"USAGE:   algDependent(f[,c]); f ideal (say, f = f1,...,fm), c integer
319RETURN:
320@format
321         a list l  of size 2, l[1] integer, l[2] ring:
322         - l[1] = 1 if f1,...,fm are algebraic dependent, 0 if not
323         - l[2] is a ring with variables x(1),...,x(n),y(1),...,y(m) if the
324           basering has n variables. It contains the ideal 'ker', depending
325           only on the y(i) and generating the algebraic relations between the
326           f[i], i.e. substituting y(i) by fi yields 0. Of course, ker is
327           nothing but the kernel of the ring map
328              K[y(1),...,y(m)] ---> basering,  y(i) --> fi.
329@end format
330NOTE:    Three different algorithms are used depending on c = 1,2,3.
331         If c is not given or c=0, a heuristically best method is choosen.
332         The basering may be a quotient ring.
333         To access to the ring l[2] and see ker you must give the ring a name,
334         e.g. def S=l[2]; setring S; ker;
335DISPLAY: The above comment is displayed if printlevel >= 0 (default).
336EXAMPLE: example algDependent; shows an example
337"
338{
339    int bestoption = 3;
340    // bestoption is the default algorithm, it may be set to 1,2 or 3;
341    // it should be changed, if another algorithm turns out to be faster
342    // in general. Is perhaps dependent on the input (# vars, size ...)
343    int tt;
344    if( size(#) > 0 )
345    { if( typeof(#[1]) == "int" )
346      { tt = #[1];
347      }
348    }
349    if( size(#) == 0 or tt == 0 )
350    { tt = bestoption;
351    }
352    def br=basering;
353    int n = nvars(br);
354    ideal B = ideal(br);
355    int m = ncols(A);
356    int s = size(B);
357    int i;
358    string mp = string(minpoly);
359 // --------------------- 1st variant of algorithm ----------------------
360 // use internal preimage command (should be equivalent to 2nd variant)
361    if ( tt == 1 )
362    {
363      execute ("ring R1=("+charstr(br)+"),y(1..m),dp;");
364      execute ("minpoly=number("+mp+");");
365      setring br;
366      map phi = R1,A;
367      setring R1;
368      ideal ker = preimage(br,phi,B);
369    }
370 // ---------- create new ring with extra variables --------------------
371    execute ("ring R2=("+charstr(br)+"),(x(1..n),y(1..m)),(dp);");
372    execute ("minpoly=number("+mp+");");
373    if( tt == 1 )
374    {
375      ideal ker = imap(R1,ker);
376    }
377    else
378    {
379      ideal vars = x(1..n);
380      map emb = br,vars;
381      ideal A = emb(A);
382      for (i=1; i<=m; i=i+1)
383      { A[i] = A[i]-y(i);
384      }
385 // --------------------- 2nd variant of algorithm ----------------------
386 // use internal eliminate for eliminating m variables x(i) from
387 // ideal A[i] - y(i) (uses extra eliminating 'first row', a-order)
388      if ( s == 0 and  tt == 2  )
389      { ideal ker = eliminate(A,product(vars));
390      }
391      else
392 // eliminate does not work in qrings
393 // --------------------- 3rd variant of algorithm ----------------------
394 // eliminate m variables x(i) from ideal A[i] - y(i) by choosing product
395 // order
396       {execute ("ring R3=("+charstr(br)+"),(x(1..n),y(1..m)),(dp(n),dp(m));");
397        execute ("minpoly=number("+mp+");");
398        if ( s != 0 )
399        { ideal vars = x(1..n);
400          map emb = br,vars;
401          ideal B = emb(B);
402          attrib(B,"isSB",1);
403          qring Q = B;
404        }
405        ideal A = imap(R2,A);
406        A = std(A);
407        ideal ker = nselect(A,1..n);
408        setring R2;
409        if ( defined(Q)==voice )
410        { ideal ker = imap(Q,ker);
411        }
412        else
413        { ideal ker = imap(R3,ker);
414        }
415        kill A,emb,vars;
416      }
417    }
418 // --------------------------- return ----------------------------------
419    s = size(ker);
420    list L = (s!=0), R2;
421    export(ker);
422    dbprint(printlevel-voice+3,"
423// The 2nd element of the list l is a ring with variables x(1),...,x(n),
424// and y(1),...,y(m) if the basering has n variables and if the ideal
425// is f[1],...,f[m]. The ring contains the ideal ker which depends only
426// on the y(i) and generates the relations between the f[i].
427// I.e. substituting y(i) by f[i] yields 0.
428// To access to the ring and see ker you must give the ring a name,
429// e.g.:
430             def S = l[2]; setring S; ker;
431        ");
432    return (L);
433}
434example
435{ "EXAMPLE:"; echo = 2;
436   int p = printlevel; printlevel = 1;
437   ring R = 0,(x,y,z,u,v,w),dp;
438   ideal I = xyzu2w-1yzu2w2+u4w2-1xu2vw+u2vw2+xyz-1yzw+2u2w-1xv+vw+2,
439             x-w, u2w+1, yz-v;
440   list l = algDependent(I);
441   l[1];
442   def S = l[2]; setring S;
443   ker;
444   printlevel = p;
445}
446//////////////////////////////////////////////////////////////////////////////
447proc alg_kernel( map phi, pr, list #)
448"USAGE:   alg_kernel(phi,pr[,s,c]); phi map to basering, pr preimage ring,
449         s string (name of kernel in pr), c integer.
450RETURN:  a string, the kernel of phi as string.
451         If, moreover, a string s is given, the algorithm creates, in the
452         preimage ring pr the kernel of phi with name s.
453         Three different algorithms are used depending on c = 1,2,3.
454         If c is not given or c=0, a heuristically best method is chosen.
455         (algorithm 1 uses the preimage command)
456NOTE:    Since the kernel of phi lives in pr, it cannot be returned to the
457         basering. If s is given, the user has access to it in pr via s.
458         The basering may be a quotient ring.
459EXAMPLE: example alg_kernel; shows an example
460"
461{   int tt;
462   if( size(#) >0 )
463   { if( typeof(#[1]) == "int")
464     { tt = #[1];
465     }
466     if( typeof(#[1]) == "string")
467     { string nker=#[1];
468     }
469     if( size(#)>1 )
470     {  if( typeof(#[2]) == "string")
471        { string nker=#[2];
472        }
473        if( typeof(#[2]) == "int")
474       {  tt = #[2];
475       }
476     }
477   }
478    int n = nvars(basering);
479    string mp = string(minpoly);
480    ideal A = ideal(phi);
481    //def pr = preimage(phi);
482    //folgendes Auffuellen oder Stutzen ist ev nicht mehr noetig
483    //falls map das richtig macht
484    int m = nvars(pr);
485    ideal j;
486    j[m]=0;
487    A=A,j;
488    A=A[1..m];
489    list L = algDependent(A,tt);
490    // algDependent is called with "bestoption" if tt = 0
491    def S = L[2];
492    execute ("ring R=("+charstr(basering)+"),(@(1..n),"+varstr(pr)+"),(dp);");
493    execute ("minpoly=number("+mp+");");
494    ideal ker = fetch(S,ker);       //in order to have variable names correct
495    string sker = string(ker);
496    if (defined(nker) == voice)
497    { setring pr;
498      execute("ideal "+nker+"="+sker+";");
499      execute("export("+nker+");");
500     }
501    return(sker);
502}
503example
504{ "EXAMPLE:"; echo = 2;
505   ring r = 0,(a,b,c),ds;
506   ring s = 0,(x,y,z,u,v,w),dp;
507   ideal I = x-w,u2w+1,yz-v;
508   map phi = r,I;                // a map from r to s:
509   alg_kernel(phi,r);            // a,b,c ---> x-w,u2w+1,yz-v
510
511   ring S = 0,(a,b,c),ds;
512   ring R = 0,(x,y,z),dp;
513   qring Q = std(x-y);
514   ideal i = x, y, x2-y3;
515   map phi = S,i;                 // a map to a quotient ring
516   alg_kernel(phi,S,"ker",3);     // uses algorithm 3
517   setring S;                     // you have access to kernel in preimage
518   ker;
519}
520//////////////////////////////////////////////////////////////////////////////
521
522proc is_injective( map phi, pr,list #)
523"USAGE:   is_injective(phi,pr[,c,s]); phi map, pr preimage ring, c int, s string
524RETURN:
525@format
526         - 1 (type int) if phi is injective, 0 if not (if s is not given).
527         - If s is given, return a list l of size 2, l[1] int, l[2] ring:
528           l[1] is 1 if phi is injective, 0 if not
529           l[2] is a ring with variables x(1),...,x(n),y(1),...,y(m) if the
530           basering has n variables and the map m components, it contains the
531           ideal 'ker', depending only on the y(i), the kernel of the given map
532@end format
533NOTE:    Three differnt algorithms are used depending on c = 1,2,3.
534         If c is not given or c=0, a heuristically best method is choosen.
535         The basering may be a quotient ring. However, if the preimage ring is
536         a quotient ring, say pr = P/I, consider phi as a map from P and then
537         the algorithm returns 1 if the kernel of phi is 0 mod I.
538         To access to the ring l[2] and see ker you must give the ring a name,
539         e.g. def S=l[2]; setring S; ker;
540DISPLAY: The above comment is displayed if printlevel >= 0 (default).
541EXAMPLE: example is_injective; shows an example
542"
543{  def bsr = basering;
544   int tt;
545   if( size(#) >0 )
546   { if( typeof(#[1]) == "int")
547     { tt = #[1];
548     }
549     if( typeof(#[1]) == "string")
550     { string pau=#[1];
551     }
552     if( size(#)>1 )
553     {  if( typeof(#[2]) == "string")
554        { string pau=#[2];
555        }
556        if( typeof(#[2]) == "int")
557       {  tt = #[2];
558       }
559     }
560   }
561    int n = nvars(basering);
562    string mp = string(minpoly);
563    ideal A = ideal(phi);
564    //def pr = preimage(phi);
565    //folgendes Auffuellen oder Stutzen ist ev nicht mehr noetig
566    //falls map das richtig macht
567    int m = nvars(pr);
568    ideal j;
569    j[m]=0;
570    A=A,j;
571    A=A[1..m];
572    list L = algDependent(A,tt);
573    L[1] = L[1]==0;
574// the preimage ring may be a quotient ring, we still have to check whether
575// the kernel is 0 mod ideal of the quotient ring
576    setring pr;
577    if ( size(ideal(pr)) != 0 )
578    { def S = L[2];
579      ideal proj;
580      proj [n+1..n+m] = maxideal(1);
581      map psi = S,proj;
582      L[1] = size(NF(psi(ker),std(0))) == 0;
583    }
584    if ( defined(pau) != voice )
585    {  return (L[1]);
586    }
587    else
588    {
589      dbprint(printlevel-voice+3,"
590// The 2nd element of the list is a ring with variables x(1),...,x(n),
591// y(1),...,y(m) if the basering has n variables and the map is
592// F[1],...,F[m].
593// It contains the ideal ker, the kernel of the given map y(i) --> F[i].
594// To access to the ring and see ker you must give the ring a name,
595// e.g.:
596     def S = l[2]; setring S; ker;
597        ");
598      return(L);
599    }
600 }
601example
602{ "EXAMPLE:"; echo = 2;
603   int p = printlevel;
604   ring r = 0,(a,b,c),ds;
605   ring s = 0,(x,y,z,u,v,w),dp;
606   ideal I = x-w,u2w+1,yz-v;
607   map phi = r,I;                    // a map from r to s:
608   is_injective(phi,r);              // a,b,c ---> x-w,u2w+1,yz-v
609   ring R = 0,(x,y,z),dp;
610   ideal i = x, y, x2-y3;
611   map phi = R,i;                    // a map from R to itself, z --> x2-y3
612   list l = is_injective(phi,R,"");
613   l[1];
614   def S = l[2]; setring S;
615   ker;
616}
617///////////////////////////////////////////////////////////////////////////////
618
619proc is_surjective( map phi )
620"USAGE:   is_surjective(phi); phi map to basering, or ideal defining it
621RETURN:  an integer,  1 if phi is surjective, 0 if not
622NOTE:    The algorithm returns 1 iff all the variables of the basering are
623         contained in the polynomial subalgebra generated by the polynomials
624         defining phi. Hence, if the basering has local or mixed ordering
625         or if the preimage ring is a quotient ring (in which case the map
626         may not be well defined) then the return value 1 means \"surjectivity\"
627         in this sense.
628EXAMPLE: example is_surjective; shows an example
629"
630{
631  def br=basering;
632    ideal B = ideal(br);
633    int s = size(B);
634    int n = nvars(br);
635    ideal A = ideal(phi);
636    int m = ncols(A);
637    int ii,t=1,1;
638    string mp=string(minpoly);
639  // ------------ create new ring with extra variables ---------------------
640    execute ("ring R=("+charstr(br)+"),(x(1..n),y(1..m)),(dp(n),dp(m));");
641    execute ("minpoly=number("+mp+");");
642    ideal vars = x(1..n);
643    map emb = br,vars;
644    if ( s != 0 )
645    {  ideal B = emb(B);
646       attrib(B,"isSB",1);
647       qring Q = B;
648       ideal vars = x(1..n);
649       map emb = br,vars;
650    }
651    ideal A = emb(A);
652    for ( ii=1; ii<=m; ii++ )
653    { A[ii] = A [ii]-y(ii);
654    }
655    A=std(A);
656  // ------------- check whether the x(i) are in the image -----------------
657    poly check;
658    for (ii=1; ii<=n; ii++ )
659    {  check=reduce(x(ii),A,1);
660  // --- checking whether all variables from old ring have disappeared -----
661  // if so, then the sum of the first n leading exponents is 0
662       if( sum(leadexp(check),1..n)!=0 )
663       { t=0;
664         break;
665       }
666    }
667   return(t);
668}
669example
670{ "EXAMPLE:"; echo = 2;
671   ring R = 0,(x,y,z),dp;
672   ideal i = x, y, x2-y3;
673   map phi = R,i;                    // a map from R to itself, z->x2-y3
674   is_surjective(phi);
675   qring Q = std(ideal(z-x37));
676   map psi = R, x,y,x2-y3;           // the same map to the quotient ring
677   is_surjective(psi);
678
679   ring S = 0,(a,b,c),dp;
680   map psi = R,ideal(a,a+b,c-a2+b3); // a map from R to S,
681   is_surjective(psi);               // x->a, y->a+b, z->c-a2+b3
682}
683
684///////////////////////////////////////////////////////////////////////////////
685
686proc is_bijective ( map phi, pr )
687"USAGE:   is_bijective(phi,pr); phi map to basering, pr preimage ring
688RETURN:  an integer,  1 if phi is bijective, 0 if not
689NOTE:    The algorithm checks first injectivity and then surjectivity
690         To interprete this for local/mixed orderings, or for quotient rings
691         type help is_surjective; and help is_injective;
692DISPLAY: A comment if printlevel >= voice-1 (default)
693EXAMPLE: example is_bijective; shows an example
694"
695{
696  def br = basering;
697    int n = nvars(br);
698    ideal B = ideal(br);
699    int s = size(B);
700    ideal A = ideal(phi);
701    //folgendes Auffuellen oder Stutzen ist ev nicht mehr noetig
702    //falls map das richtig macht
703    int m = nvars(pr);
704    ideal j;
705    j[m]=0;
706    A=A,j;
707    A=A[1..m];
708    int ii,t = 1,1;
709    string mp=string(minpoly);
710  // ------------ create new ring with extra variables ---------------------
711    execute ("ring R=("+charstr(br)+"),(x(1..n),y(1..m)),(dp(n),dp(m));");
712    execute ("minpoly=number("+mp+");");
713    ideal vars = x(1..n);
714    map emb = br,vars;
715    if ( s != 0 )
716    {  ideal B = emb(B);
717       attrib(B,"isSB",1);
718       qring Q = B;
719       ideal vars = x(1..n);
720       map emb = br,vars;
721    }
722    ideal A = emb(A);
723    for ( ii=1; ii<=m; ii++ )
724    { A[ii] = A[ii]-y(ii);
725    }
726    A=std(A);
727    def bsr = basering;
728 // ------- checking whether phi is injective by computing the kernel -------
729    ideal ker = nselect(A,1..n);
730    t = size(ker);
731    setring pr;
732    if ( size(ideal(pr)) != 0 )
733    {
734      ideal proj;
735      proj[n+1..n+m] = maxideal(1);
736      map psi = bsr,proj;
737      t = size(NF(psi(ker),std(0)));
738    }
739    if ( t != 0 )
740    {  dbprint(printlevel-voice+3,"// map not injective" );
741      return(0);
742    }
743   else
744 // -------------- checking whether phi is surjective ----------------------
745   { t = 1;
746     setring bsr;
747     poly check;
748     for (ii=1; ii<=n; ii++ )
749     {  check=reduce(x(ii),A,1);
750  // --- checking whether all variables from old ring have disappeared -----
751  // if so, then the sum of the first n leading exponents is 0
752        if( sum(leadexp(check),1..n)!=0 )
753        { t=0;
754          break;
755        }
756     }
757     if ( t == 0 )
758     {  dbprint(printlevel-voice+3,"// map injective, but not surjective" );
759     }
760     return(t);
761   }
762}
763example
764{ "EXAMPLE:"; echo = 2;
765   int p = printlevel;  printlevel = 1;
766   ring R = 0,(x,y,z),dp;
767   ideal i = x, y, x2-y3;
768   map phi = R,i;                      // a map from R to itself, z->x2-y3
769   is_bijective(phi,R);
770   qring Q = std(z-x2+y3);
771   is_bijective(ideal(x,y,x2-y3),Q);
772
773   ring S = 0,(a,b,c,d),dp;
774   map psi = R,ideal(a,a+b,c-a2+b3,0); // a map from R to S,
775   is_bijective(psi,R);                // x->a, y->a+b, z->c-a2+b3
776   qring T = std(d,c-a2+b3);
777   map chi = Q,a,b,a2-b3;              // amap between two quotient rings
778   is_bijective(chi,Q);
779
780   printlevel = p;
781}
782///////////////////////////////////////////////////////////////////////////////
783
784proc noetherNormal(ideal i, list #)
785"USAGE:   noetherNormal(id[,p]);  id ideal, p integer
786RETURN:
787@format
788         a list l of two ideals, say I,J:
789         - I is generated by a subset of the variables with size(I) = dim(id)
790         - J defines a map (coordinate change in the basering), such that:
791           if we define  map phi=basering,J;
792           then k[var(1),...,var(n)]/phi(id) is finite over k[I].
793         If p is given, 0<=p<=100, a sparse coordinate change with p percent
794         of the matrix entries being 0 (default: p=0 i.e. dense)
795@end format
796NOTE:    Designed for characteristic 0.It works also in char k > 0 if it
797         terminates,but may result in an infinite loop in small characteristic
798EXAMPLE: example noetherNormal; shows an example
799"
800{
801   if ( deg(i[1]) <= 0)
802   {
803     list l = ideal(0),i;
804     return( l );
805   }
806   int p;
807   if( size(#) != 0 )
808   {
809     p = #[1];
810   }
811   def r = basering;
812   int n = nvars(r);
813   list good;
814   // ------------------------ change of ordering ---------------------------
815   //a procedure from ring.lib changing the order to dp creating a new
816   //basering @R in order to compute the dimension d of i
817   def @R=changeord("dp");
818   setring @R;
819   ideal i = imap(r,i);
820   list j = mstd(i);
821   i = j[2];
822   int d = dim(j[1]);
823   if ( d == 0)
824   {
825     setring r;
826     list l = ideal(0),maxideal(1);
827     return( l );
828   }
829   // ------------------------ change of ordering ---------------------------
830   //Now change the order to (dp(n-d),lp) creating a new basering @S
831    string s ="dp("+string(n-d)+"),lp";
832   def @S=changeord(s);
833   setring @S;
834   ideal m;
835
836   // ----------------- sparse-random coordinate change  --------------------
837   //creating lower triangular random generators for the maximal ideal
838   //a procedure from random.lib, as sparse as possible
839   if(  char(@S) >  0 )
840   {
841      m=ideal(sparsetriag(n,n,p,char(@S)+1)*transpose(maxideal(1)));
842   }
843   if(  char(@S) == 0 )
844   {
845      if ( voice <= 6 )
846      {
847        m=ideal(sparsetriag(n,n,p,10)*transpose(maxideal(1)));
848      }
849     if( voice > 6 and voice <= 11)
850     {
851        m=ideal(sparsetriag(n,n,p,100)*transpose(maxideal(1)));
852      }
853      if ( voice > 11 )
854      {
855        m=ideal(sparsetriag(n,n,p,30000)*transpose(maxideal(1)));
856      }
857   }
858
859   map phi=r,m;
860   //map phi=@R,m;
861   ideal i=std(phi(i));
862
863   // ----------------------- test for finiteness ---------------------------
864   //We need a test whether the coordinate change was random enough, if yes
865   //we are ready, else call noetherNormal again
866   list l=finitenessTest(i);
867
868   setring r;
869   list l=imap(@S,l);
870
871   if(size(l[3]) == d)                    //the generic case
872   {
873      good = fetch(@S,m),l[3];
874      kill @S,@R;
875      return(good);
876   }
877   else                                   //the bad case
878   { kill @S,@R;
879      if ( voice >= 21 )
880      {
881       "// WARNING: In case of a finite ground field";
882       "// the characteristic may be too small.";
883       "// This could result in an infinte loop.";
884       "// Loop in noetherNormal, voice:";, voice;"";
885      }
886     if ( voice >= 16 )
887     {
888       "// Switch to dense coordinate change";"";
889       return(noetherNormal(i));
890     }
891     return(noetherNormal(i,p));
892   }
893}
894example
895{ "EXAMPLE:"; echo = 2;
896   ring r=0,(x,y,z),dp;
897   ideal i= xy,xz;
898   noetherNormal(i);
899}
900///////////////////////////////////////////////////////////////////////////////
901
902proc finitenessTest(ideal i, list #)
903"USAGE:   finitenessTest(J[,v]); J ideal, v intvec (say v1,...,vr with vi>0)
904RETURN:
905@format
906         a list l with l[1] integer, l[2], l[3], l[4] ideals
907         - l[1] = 1 if var(v1),...,var(vr) are in l[2] and 0 else
908         - l[2] (resp. l[3]) contains those variables which occur,
909           (resp. do not occur) as pure power in the leading term of one of the
910           generators of J,
911         - l[4] contains those J[i] for which the leading term is a pure power
912           of a variable (which is then in l[2])
913         (default: v = [1,2,..,nvars(basering)])
914@end format
915THEORY:  If J is a standard basis of an ideal generated by x_1 - f_1(y),...,
916         x_n - f_n with y_j ordered lexicographically and y_j >> x_i, then,
917         if y_i appears as pure power in the leading term of J[k], J[k] defines
918         an integral relation for y_i over the y_(i+1),... and the f's.
919         Moreover, in this situation, if l[2] = y_1,...,y_r, then K[y_1,...y_r]
920         is finite over K[f_1..f_n]. If J contains furthermore polynomials
921         h_j(y), then K[y_1,...y_z]/<h_j> is finite over K[f_1..f_n].
922         For a proof cf. Prop. 3.1.5, p. 214. in [G.-M. Greuel, G. Pfister:
923         A SINGULAR Introduction to Commutative Algebra, 2nd Edition,
924         Springer Verlag (2007)]
925EXAMPLE: example finitenessTest; shows an example
926"
927{  int n = nvars(basering);
928   intvec v,w;
929   int j,z,ii;
930   v[n]=0;                             //v should have size n
931   intvec V = 1..n;
932   list nze;                           //the non-zero entries of a leadexp
933   if (size(#) != 0 )
934   {
935     V = #[1];
936   }
937   intmat W[1][n];                     //create intmat with 1 row, having 1 at
938                                       //position V[j], i = 1..size(V), 0 else
939   for( j=1; j<=size(V); j++ )
940   {
941     W[1,V[j]] = 1;
942   }
943   ideal relation,zero,nonzero;
944   // ---------------------- check leading exponents -------------------------
945
946   for(j=1;j<=ncols(i);j++)
947   {
948      w = leadexp(i[j]);
949      nze = nonZeroEntry(w);
950      if( nze[1] == 1 )               //the leading term of i[j] is a
951      {                               //pure power of some variable
952        if( W*w != 0 )                //case: variable has index appearing in V
953        {
954          relation[size(relation)+1] = i[j];
955          v=v+w;
956        }
957      }
958   }
959   // ----------------- pick the corresponding variables ---------------------
960   //the nonzero entries of v correspond to variables which occur as
961   //pure power in the leading term of some polynomial in i
962
963   for(j=1; j<=size(v); j++)
964   {
965      if(v[j]==0)
966      {
967         zero[size(zero)+1]=var(j);
968      }
969      else
970      {
971        nonzero[size(nonzero)+1]=var(j);
972      }
973   }
974   // ---------------- do we have all pure powers we want? -------------------
975   // test this by dividing the product of corresponding variables
976   ideal max = maxideal(1);
977   max = max[V];
978   z = (product(nonzero)/product(max) != 0);
979   return(list(z,nonzero,zero,relation));
980}
981example
982{ "EXAMPLE:"; echo = 2;
983   ring s = 0,(x,y,z,a,b,c),(lp(3),dp);
984   ideal i= a -(xy)^3+x2-z, b -y2-1, c -z3;
985   ideal j = a -(xy)^3+x2-z, b -y2-1, c -z3, xy;
986   finitenessTest(std(i),1..3);
987   finitenessTest(std(j),1..3);
988}
989///////////////////////////////////////////////////////////////////////////////
990
991proc mapIsFinite(map phi, R, list #)
992"USAGE:   mapIsFinite(phi,R[,J]); R the preimage ring of the map
993         phi: R ---> basering
994         J an ideal in the basering, J = 0 if not given
995RETURN:  1 if R ---> basering/J is finite and 0 else
996NOTE:    R may be a quotient ring (this will be ignored since a map R/I-->S/J
997         is finite iff the induced map R-->S/J is finite).
998SEE ALSO: finitenessTest
999EXAMPLE: example mapIsFinite; shows an example
1000"
1001{
1002  def bsr = basering;
1003  ideal J;
1004  if( size(#) != 0 )
1005  {
1006    J = #[1];
1007  }
1008  string os = ordstr(bsr);
1009  int m = nvars(bsr);
1010  int n = nvars(R);
1011  ideal PHI = ideal(phi);
1012  if ( ncols(PHI) < n )
1013  { PHI[n]=0;
1014  }
1015  // --------------------- change of variable names -------------------------
1016  execute("ring @bsr = ("+charstr(bsr)+"),y(1..m),("+os+");");
1017  ideal J = fetch(bsr,J);
1018  ideal PHI = fetch(bsr,PHI);
1019
1020  // --------------------------- enlarging ring -----------------------------
1021  execute("ring @rr = ("+charstr(bsr)+"),(y(1..m),x(1..n)),(lp(m),dp);");
1022  ideal J = imap(@bsr,J);
1023  ideal PHI = imap(@bsr,PHI);
1024  ideal M;
1025  int i;
1026
1027  for(i=1;i<=n;i++)
1028  {
1029    M[i]=x(i)-PHI[i];
1030  }
1031  M = std(M+J);
1032  // ----------------------- test for finiteness ---------------------------
1033  list l = finitenessTest(M,1..m);
1034  return(l[1]);
1035}
1036example
1037{ "EXAMPLE:"; echo = 2;
1038   ring r = 0,(a,b,c),dp;
1039   ring s = 0,(x,y,z),dp;
1040   ideal i= xy;
1041   map phi= r,(xy)^3+x2+z,y2-1,z3;
1042   mapIsFinite(phi,r,i);
1043}
1044//////////////////////////////////////////////////////////////////////////////
1045
1046proc nonZeroEntry(id)
1047"USAGE:  nonZeroEntry(id); id=object for which the test 'id[i]!=0', i=1,..,N,
1048         N=size(id) (resp. ncols(id) for id of type ideal or module)
1049         is defined (e.g. ideal, vector, list of polynomials, intvec,...)
1050RETURN:  @format
1051         a list, say l, with l[1] an integer, l[2], l[3] integer vectors:
1052         - l[1] number of non-zero entries of id
1053         - l[2] intvec of size l[1] with l[2][i]=i if id[i] != 0
1054           in case l[1]!=0 (and l[2]=0 if l[1]=0)
1055         - l[3] intvec with l[3][i]=1 if id[i]!=0 and l[3][i]=0 else
1056@end format
1057NOTE:
1058EXAMPLE: example nonZeroEntry; shows an example
1059"
1060{
1061   int ii,jj,N,n;
1062   intvec v,V;
1063
1064   if ( typeof(id) == "ideal" || typeof(id) == "module" )
1065   {
1066      N = ncols(id);
1067   }
1068   else
1069   {
1070     N = size(id);
1071   }
1072   for ( ii=1; ii<=N; ii++ )
1073   {
1074      V[ii] = 0;
1075      if ( id[ii] != 0 )
1076      {
1077         n++;
1078         v=v,ii;      //the first entry of v is always 0
1079         V[ii] = 1;
1080      }
1081   }
1082   if ( size(v) > 1 ) //if id[ii] != 0 for at least one ii delete the first 0
1083   {
1084      v = v[2..size(v)];
1085   }
1086
1087   list l = n,v,V;
1088   return(l);
1089}
1090example
1091{ "EXAMPLE:"; echo = 2;
1092   ring r = 0,(a,b,c),dp;
1093   poly f = a3c+b3+c2+a;
1094   intvec v = leadexp(f);
1095   nonZeroEntry(v);
1096
1097   intvec w;
1098   list L = 37,0,f,v,w;
1099   nonZeroEntry(L);
1100}
1101//////////////////////////////////////////////////////////////////////////////
1102
Note: See TracBrowser for help on using the repository browser.