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

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