source: git/Singular/LIB/algebra.lib @ 7bb71fa

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