source: git/Singular/LIB/algebra.lib @ 3963c1

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