source: git/Singular/LIB/algebra.lib @ 92b2f3

spielwiese
Last change on this file since 92b2f3 was 92b2f3, checked in by Olaf Bachmann <obachman@…>, 25 years ago
* added git-svn-id: file:///usr/local/Singular/svn/trunk@3295 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 24.4 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2version="$Id: algebra.lib,v 1.1 1999-07-19 14:54:07 obachman 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 algDependence(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";
19
20 LIB "inout.lib";
21 LIB "elim.lib";
22
23///////////////////////////////////////////////////////////////////////////////
24
25proc algebra_containment (poly p, ideal A,list #)
26"USAGE:   algebra_containment(p,A[,k]); p poly, A ideal, k integer
27         A = A[1],...,A[m] generators of subalgebra of the basering
28RETURN:  - k=0 (or if k is not given) an integer:
29           1    : if p is contained in the subalgebra K[A[1],...,A[m]]
30           0    : if p is not contained in K[A[1],...,A[m]]
31         - k=1: a list, say l, of size 2, l[1] integer, l[2] ring, satisfying
32           l[1]=1 if p is in the subalgebra K[A[1],...,A[m]] and then the ring
33           l[2] contains the poly check = h(y(1),...,y(m)) if p=h(A[1],...,A[m])
34           l[1]=0 if p is in not the subalgebra K[A[1],...,A[m]] and then
35           l[2] contains the poly check = h(x,y(1),...,y(m)) if p satisfies
36           the nonlinear relation p = h(x,A[1],...,A[m]) where
37           x = x(1),...,x(n) denote the variables of the basering
38DISPLAY: if k=0, polynomial h(y(1),...,y(m)) if p=h(A[1],...,A[m]) is contained
39         in the subalgebra, provided printlevel >= voice+1 (default)
40NOTE:    The proc inSubring uses a different algorithm which is sometimes faster
41THEORY:  The ideal of algebraic relations of the algebra generators A[1],...,
42         A[m] is computed introducing new variables y(i) and the product
43         order with x(i) >> y(i).
44         p reduces to a polynomial only in the y(i) <=> p is contained in the
45         subring generated by the polynomials A[1],...,A[m].
46EXAMPLE: example algebra_containment; shows an example
47"
48{ int DEGB = degBound;
49  degBound = 0;
50    if (size(#)==0)
51    { #[1] = 0;
52    }     
53    def br=basering;
54    int n = nvars(br);
55    int m = ncols(A);
56    int i;
57    string mp=string(minpoly);
58  // ---------- create new ring with extra variables --------------------
59    execute ("ring R=("+charstr(br)+"),(x(1..n),y(1..m)),(dp(n),dp(m));");
60    execute ("minpoly=number("+mp+");");
61    ideal vars=x(1..n);
62    map emb=br,vars;
63    ideal A=ideal(emb(A));
64    poly check=emb(p);
65    for (i=1;i<=m;i=i+1)
66    { A[i]=A[i]-y(i);
67    }
68    A=std(A);
69    check=reduce(check,A);
70    /*alternatively we could use reduce(check,A,1) which is a little faster
71      but result is bigger since it is not tail-reduced
72    */
73  //--- checking whether all variables from old ring have disappeared ------
74  // if so, then the sum of the first n leading exponents is 0, hence i=1
75  // use i also to control the display
76    i = (sum(leadexp(check),1..n)==0);   
77  degBound = DEGB;
78    if( #[1] == 0 )
79    { dbprint(i*(printlevel-voice+3),"// "+string(check));
80      return(i);
81    }
82    else
83    { list l = i,R;
84      kill A,vars,emb;
85      export check;       
86      dbprint(printlevel-voice+3,"
87// 'algebra_containment' created a ring as 2nd element of the list.
88// This ring contains the poly check which defines the algebraic relation.
89// To access to the ring and see check you must give the ring a name, e.g.:
90     def S = l[2]; setring S; check;
91        ");
92     return(l);
93    }
94}
95example
96{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:"; echo=2;
97   int p = printlevel; printlevel = 1;
98   ring R = 0,(x,y,z),dp;
99   ideal A=x2+y2,z2,x4+y4,1,x2z-1y2z,xyz,x3y-1xy3;
100   poly p1=z;
101   poly p2=x10z3-x8y2z3+2x6y4z3-2x4y6z3+x2y8z3-y10z3+x6z4+3x4y2z4+3x2y4z4+y6z4;
102   
103   algebra_containment(p1,A);
104   algebra_containment(p2,A);
105   list L = algebra_containment(p2,A,1);
106   L[1];
107   def S = L[2]; setring S;   
108   check;
109   printlevel = p;
110}
111///////////////////////////////////////////////////////////////////////////////
112
113proc module_containment(poly p, ideal P, ideal S, list #)
114"USAGE:   module_containment(p,P,M[,k]); p poly, P ideal, M ideal, k int
115         P = P[1],...,P[n] generators of a subalgebra of the basering,
116         M = M[1],...,M[m] generators of a module over the subalgebra K[P]
117ASSUME:  ncols(P) = nvars(basering), the P[i] are algebraically independent
118RETURN:  - k=0 (or if k is not given), an integer:
119           1    : if p is contained in the module <M[1],...,M[m]> over K[P]
120           0    : if p is not contained in <M[1],...,M[m]>
121         - k=1, a list, say l, of size 2, l[1] integer, l[2] ring:
122           l[1]=1 : if p is in <M[1],...,M[m]> and then the ring l[2] contains
123             the polynomial check = h(y(1),...,y(m),z(1),...,z(n)) if
124             p = h(M[1],...,M[m],P[1],...,P[n])
125           l[1]=0 : if p is in not in <M[1],...,M[m]> and then l[2] contains the
126             polynomial check = h(x,y(1),...,y(m),z(1),...,z(n)) if p satisfies
127             the nonlinear relation p = h(x,M[1],...,M[m],P[1],...,P[n]) where
128             x = x(1),...,x(n) denote the variables of the basering
129DISPLAY: the polynomial h(y(1),...,y(m),z(1),...,z(n)) if k=0, resp.
130         a comment how to access the relation check if k=1,
131         provided printlevel >= voice+1 (default)
132THEORY:  The ideal of algebraic relations of all the generators p1,...,pn,
133         s1,...,st given by P and S is computed introducing new variables y(j),
134         z(i) and the product order: x^a*y^b*z^c > x^d*y^e*z^f if x^a > x^d
135         with respect to the lp ordering or else if z^c > z^f with respect to
136         the dp ordering or else if y^b > y^e with respect to the lp ordering
137         again. p reduces to a polynomial only in the y(j) and z(i), linear in
138         the z(i) <=> p is contained in the module.
139EXAMPLE: example module_containment; shows an example
140"
141{ def br=basering;
142  int DEGB = degBound;
143  degBound=0;
144  if (size(#)==0)
145  { #[1] = 0;
146  }
147  int n=nvars(br);
148  if ( ncols(P)==n )
149  { int m=ncols(S);
150    string mp=string(minpoly);
151  // ---------- create new ring with extra variables --------------------
152    execute
153   ("ring R=("+charstr(br)+"),(x(1..n),y(1..m),z(1..n)),(lp(n),dp(m),lp(n));");
154    execute ("minpoly=number("+mp+");");
155    ideal vars = x(1..n);
156    map emb = br,vars;
157    ideal P = emb(P);
158    ideal S  = emb(S);
159    poly check = emb(p);
160    ideal I;
161    for (int i=1;i<=m;i=i+1)
162    { I[i]=S[i]-y(i);
163    }
164    for (i=1;i<=n;i=i+1)
165    { I[m+i]=P[i]-z(i);
166    }
167    I=std(I);
168    check = reduce(check,I);
169  //--- checking whether all variables from old ring have disappeared ------
170  // if so, then the sum of the first n leading exponents is 0
171    i = (sum(leadexp(check),1..n)==0);   
172    if( #[1] == 0 )
173    { dbprint(i*(printlevel-voice+3),"// "+string(check));
174      return(i);
175    }
176    else
177    { list l = i,R;
178      kill I,vars,emb,P,S;
179      export check;       
180      dbprint(printlevel-voice+3,"
181// 'module_containment' created a ring as 2nd element of the list.
182// This ring contains the poly check which defines the algebraic relation for p.
183// To access to the ring and see check you must give the ring a name, e.g.:
184     def S = l[2]; setring S; check;
185      ");
186      return(l);
187    }
188  }
189  else
190  { "ERROR: the first ideal must have nvars(basering) entries";
191    return();
192  }
193}
194example
195{ "EXAMPLE: Sturmfels: Algorithms in Invariant Theory 2.3.7:"; echo=2;
196   int p = printlevel; printlevel = 1;
197   ring R=0,(x,y,z),dp;
198   ideal P = x2+y2,z2,x4+y4;           //algebra generators
199   ideal M = 1,x2z-1y2z,xyz,x3y-1xy3;  //module generators
200   poly p1=x10z3-x8y2z3+2x6y4z3-2x4y6z3+x2y8z3-y10z3+x6z4+3x4y2z4+3x2y4z4+y6z4;
201   module_containment(p1,P,M);
202   poly p2=z;
203   list l = module_containment(p2,P,M,1);
204   l[1];
205   def S = l[2]; setring S; check;
206   printlevel=p;
207}
208///////////////////////////////////////////////////////////////////////////////
209
210proc inSubring(poly p, ideal I)
211"USAGE:   inSubring(p,i); p poly, i ideal
212RETURN:  a list, say l,of size 2, l[1] integer, l[2] string
213         l[1]=1 iff p is in the subring generated by i=i[1],...,i[k],
214                and then l[2] = y(0)-h(y(1),...,y(k)) if p = h(i[1],...,i[k])
215         l[1]=0 iff p is in not the subring generated by i,
216                and then l[2] = h(y(0),y(1),...,y(k) where p satisfies the
217                nonlinear relation h(p,i[1],...,i[k])=0.
218NOTE:    the proc algebra_containment tests the same with a different
219         algorithm, which is often faster
220EXAMPLE: example inSubring; shows an example
221"
222{int z=ncols(I);
223  int i;
224  def gnir=basering;
225  int n = nvars(gnir);
226  string mp=string(minpoly);
227  list l;
228  // ---------- create new ring with extra variables --------------------
229  //the intersection of ideal nett=(p-y(0),I[1]-y(1),...)
230  //with the ring k[y(0),...,y(n)] is computed, the result is ker
231  execute ("ring r1= ("+charstr(basering)+"),(x(1..n),y(0..z)),dp;");
232  execute ("minpoly=number("+mp+");");
233  ideal va = x(1..n);
234  map emb = gnir,va;
235  ideal nett = emb(I);
236  for (i=1;i<=z;i++)
237  { nett[i]=nett[i]-y(i);
238  }
239  nett=emb(p)-y(0),nett;
240  ideal ker=eliminate(nett,product(va));
241  //---------- test wether y(0)-h(y(1),...,y(z)) is in ker --------------
242  l[1]=0;
243  l[2]="";
244  for (i=1;i<=size(ker);i++)
245  { if (deg(ker[i]/y(0))==0)
246     { string str=string(ker[i]);
247        setring gnir;
248        l[1]=1;
249        l[2]=str;
250        return(l);
251     }
252     if (deg(ker[i]/y(0))>0)
253     { l[2]=l[2]+string(ker[i]);
254     }
255  }
256  return(l);
257}
258example
259{ "EXAMPLE:"; echo = 2;
260   ring q=0,(x,y,z,u,v,w),dp;
261   poly p=xyzu2w-1yzu2w2+u4w2-1xu2vw+u2vw2+xyz-1yzw+2u2w-1xv+vw+2;
262   ideal I =x-w,u2w+1,yz-v;
263   inSubring(p,I);
264}
265//////////////////////////////////////////////////////////////////////////////
266
267proc algDependence( ideal A, list # )
268"USAGE:   algDependence(f[,c]); f ideal (say, f = f1,...,fm), c integer
269RETURN:  a list, say l, of size 2, l[1] integer, l[2] ring:
270         l[1] = 1 if f1,...,fm are algebraic dependent, 0 if not
271         l[2] is a ring with variables x(1),...,x(n),y(1),...,y(m) if the
272         basering has n variables. It contains the ideal 'ker', depending
273         onIy on the y(i) and generating the algebraic relations between the
274         f[i], i.e. substituting y(i) by f[i] yields 0.
275         Three differnt algorithms are used depending on c = 1,2,3.
276         If c is not given or c=0, a heuristically best method is choosen.
277         The basering may be a quotient ring.
278         To access to the ring l[2] and see ker you must give the ring a name,
279         e.g. def S=l[2]; setring S; ker;
280DISPLAY: The above comment is displayed if printlevel >= 0 (default).
281EXAMPLE: example algDependence; shows an example
282"
283{   
284    int bestoption = 3;
285    // bestoption is the default algorithm, it may be set to 1,2 or 3;
286    // it should be changed, if another algorithm turns out to be faster
287    // in general. Is perhaps dependent on the input (# vars, size ...)
288    int tt;
289    if( size(#) > 0 )
290    { if( typeof(#[1]) == "int" )
291      { tt = #[1];
292      }
293    }
294    if( size(#) == 0 or tt == 0 )
295    { tt = bestoption;
296    }   
297    def br=basering;
298    int n = nvars(br);
299    ideal B = ideal(br);
300    int m = ncols(A);
301    int s = size(B);
302    int i;
303    string mp = string(minpoly);
304 // --------------------- 1st variant of algorithm ----------------------
305    if ( tt == 1 )
306    { 
307      execute ("ring R1=("+charstr(br)+"),y(1..m),dp;");
308      execute ("minpoly=number("+mp+");");
309      setring br;
310      map phi = R1,A;
311      setring R1;
312      ideal ker = preimage(br,phi,B);             
313    }
314 // ---------- create new ring with extra variables --------------------
315    execute ("ring R2=("+charstr(br)+"),(x(1..n),y(1..m)),(dp);");
316    execute ("minpoly=number("+mp+");");
317    if( tt == 1 )
318    {
319      ideal ker = imap(R1,ker);
320    }
321    else
322    {
323      ideal vars = x(1..n);
324      map emb = br,vars;
325      ideal A = emb(A);
326      for (i=1; i<=m; i=i+1)
327      { A[i] = A[i]-y(i);
328      }
329 // --------------------- 2nd variant of algorithm ----------------------
330 // eliminate does not work in qrings
331      if ( s == 0 and  tt == 2  )
332      { ideal ker = eliminate(A,product(vars));
333      }
334      else
335 // --------------------- 3rd variant of algorithm ----------------------
336      { execute ("ring R3=("+charstr(br)+"),(x(1..n),y(1..m)),(dp(n),dp(m));");
337        execute ("minpoly=number("+mp+");");
338        if ( s != 0 )
339        { ideal vars = x(1..n);
340          map emb = br,vars;
341          ideal B = emb(B);
342          attrib(B,"isSB",1);
343          qring Q = B;
344        }
345        ideal A = imap(R2,A);
346        A=std(A);
347        ideal ker = nselect(A,1,n);
348        setring R2;
349        if ( defined(Q)==voice )
350        { ideal ker = imap(Q,ker);
351        }
352        else
353        { ideal ker = imap(R3,ker);
354        }
355        kill A,emb,vars;
356      }
357    }
358 // --------------------------- return ----------------------------------
359    s = size(ker);
360    list L = (s!=0), R2;
361    export(ker);
362    dbprint(printlevel-voice+3,"
363// The 2nd element of the list, say l, is a ring with variables x(1),...,x(n),
364// y(1),...,y(m) if the basering has n variables and the ideal is f[1],...,f[m]
365// It contains the ideal ker only depending on the y(i) and generating the
366// relations between the f[i], i.e. substituting y(i) by f[i] yields 0.
367// To access to the ring and see ker you must give the ring a name, e.g.:
368     def S = l[2]; setring S; ker;
369        ");
370    return (L);
371}
372example
373{ "EXAMPLE:"; echo = 2;
374   int p = printlevel; printlevel = 1;
375   ring R = 0,(x,y,z,u,v,w),dp;
376   ideal I = xyzu2w-1yzu2w2+u4w2-1xu2vw+u2vw2+xyz-1yzw+2u2w-1xv+vw+2,
377             x-w, u2w+1, yz-v;
378   list l = algDependence(I);
379   l[1];
380   def S = l[2]; setring S;
381   ker;
382   printlevel = p;
383}
384//////////////////////////////////////////////////////////////////////////////
385proc alg_kernel( map phi, pr, list #)
386"USAGE:   alg_kernel(phi,pr[,s,c]); phi map to basering, pr preimage ring,
387         s string (name of kernel in pr), c integer
388RETURN:  a string, the kernel of phi as string
389         If, moreover, a string s is given, the algorithm creates, in pr,
390         the kernel of phi with name equal to s.
391         Three differnt algorithms are used depending on c = 1,2,3.
392         If c is not given or c=0, a heuristically best method is choosen.
393         (alogrithm 1 uses the preimage command)
394NOTE:    The basering may be a quotient ring.
395EXAMPLE: example kernel; shows an example
396"
397{   int tt;
398   if( size(#) >0 )
399   { if( typeof(#[1]) == "int")
400     { tt = #[1];
401     }
402     if( typeof(#[1]) == "string")
403     { string nker=#[1];
404     }
405     if( size(#)>1 )
406     {  if( typeof(#[2]) == "string")
407        { string nker=#[2];
408        }
409        if( typeof(#[2]) == "int")
410       {  tt = #[2];
411       }
412     }
413   }
414    int n = nvars(basering);
415    string mp = string(minpoly);
416    ideal A = ideal(phi);
417    //def pr = preimage(phi);
418    //folgendes Auffuellen oder Stutzen ist ev nicht mehr noetig
419    //falls map das richtig macht
420    int m = nvars(pr);
421    ideal j;
422    j[m]=0;
423    A=A,j;
424    A=A[1..m];
425    list L = algDependence(A,tt);
426    // algDependence is called with "bestoption" if tt = 0
427    def S = L[2];
428    execute ("ring R=("+charstr(basering)+"),(@(1..n),"+varstr(pr)+"),(dp);");
429    execute ("minpoly=number("+mp+");");
430    ideal ker = fetch(S,ker);       //in order to have variable names correct
431    string sker = string(ker);
432    if (defined(nker) == voice)
433    { setring pr;
434      execute("ideal "+nker+"="+sker+";");
435      execute("export("+nker+");");
436     }
437    return(sker);
438}
439example
440{ "EXAMPLE:"; echo = 2;
441   ring r = 0,(a,b,c),ds;
442   ring s = 0,(x,y,z,u,v,w),dp;
443   ideal I = x-w,u2w+1,yz-v;
444   map phi = r,I;                   // a map from r to s:
445   alg_kernel(phi,r);                   // a,b,c ---> x-w,u2w+1,yz-v
446 
447   ring S = 0,(a,b,c),ds;
448   ring R = 0,(x,y,z),dp;
449   qring Q = std(x-y);
450   ideal i = x, y, x2-y3;
451   map phi = S,i;                    // a map to a quotient ring
452   alg_kernel(phi,S,"ker",3);            // uses algorithm 3
453   setring S;                        // you have access to kernel in preimage
454   // setring preimage(phi);      ## wenn realisiert ##
455   ker;
456}
457//////////////////////////////////////////////////////////////////////////////
458
459proc is_injective( map phi, pr,list #)
460"USAGE:   is_injective(phi[,c,s]); phi map, pr reimage ring, c int, s string
461RETURN:  - 1 (type int) if phi is injective, 0 if not (if s is not given).
462         - If s is given, return a list, say l, of size 2, l[1] int, l[2] ring:
463           l[1] = 1 if phi is injective, 0 if not
464           l[2] is a ring with variables x(1),...,x(n),y(1),...,y(m) if the
465           basering has n variables and the map m components, it contains the
466           ideal 'ker', depending only on the y(i), the kernel of the given map
467         Three differnt algorithms are used depending on c = 1,2,3.
468         If c is not given or c=0, a heuristically best method is choosen.
469NOTE:    The basering may be a quotient ring.
470         To access to the ring l[2] and see ker you must give the ring a name,
471         e.g. def S=l[2]; setring S; ker;
472DISPLAY: The above comment is displayed if printlevel >= 0 (default).
473EXAMPLE: example is_injective; shows an example
474"
475{  def bsr = basering;
476   int tt;
477   if( size(#) >0 )
478   { if( typeof(#[1]) == "int")
479     { tt = #[1];
480     }
481     if( typeof(#[1]) == "string")
482     { string pau=#[1];
483     }
484     if( size(#)>1 )
485     {  if( typeof(#[2]) == "string")
486        { string pau=#[2];
487        }
488        if( typeof(#[2]) == "int")
489       {  tt = #[2];
490       }
491     }
492   }
493    int n = nvars(basering);
494    string mp = string(minpoly);
495    ideal A = ideal(phi);
496    //def pr = preimage(phi);
497    //folgendes Auffuellen oder Stutzen ist ev nicht mehr noetig
498    //falls map das richtig macht
499    int m = nvars(pr);
500    ideal j;
501    j[m]=0;
502    A=A,j;
503    A=A[1..m];
504    list L = algDependence(A,tt);
505    L[1] = L[1]==0;
506// the preimage ring may be a quotient ring, we still have to check whether
507// the kernel is 0 mod ideal of the quotient ring
508    setring pr;
509    if ( size(ideal(pr)) != 0 )
510    { def S = L[2];
511      ideal proj;
512      proj [n+1..m] = maxideal(1);
513      map psi = S,proj;
514      L[1] = size(NF(psi(ker),std(0))) == 0;
515    }
516    if ( defined(pau) != voice )
517    {  return (L[1]);
518    }
519    else
520    {
521      dbprint(printlevel-voice+3,"
522// The 2nd element of the list is a ring with variables x(1),...,x(n),y(1),
523// ...,y(m) if the basering has n variables and the map is, say, F[1],...,F[m].
524// It contains the ideal ker, the kernel of the given map y(i) --> F[i].
525// To access to the ring and see ker you must give the ring a name, e.g.:
526     def S = l[2]; setring S; ker;
527        ");
528      return(L);
529    }
530 }
531example
532{ "EXAMPLE:"; echo = 2;
533   int p = printlevel; printlevel = 1;
534   ring r = 0,(a,b,c),ds;
535   ring s = 0,(x,y,z,u,v,w),dp;
536   ideal I = x-w,u2w+1,yz-v;
537   map phi = r,I;                    // a map from r to s:
538   is_injective(phi,r);              // a,b,c ---> x-w,u2w+1,yz-v
539   ring R = 0,(x,y,z),dp;
540   ideal i = x, y, x2-y3;
541   map phi = R,i;                    // a map from R to itself, z --> x2-y3
542   list l = is_injective(phi,R,"");
543   l[1];
544   def S = l[2]; setring S;
545   ker;
546   
547   printlevel = p;
548 }
549///////////////////////////////////////////////////////////////////////////////
550
551proc is_surjective( map phi )
552"USAGE:   is_surjective(phi); phi map to basering, or ideal defining it
553RETURN:  an integer,  1 if phi is surjective, 0 if not
554NOTE:    The algorithm returns 1 iff all the variables of the basering are
555         contained in the polynomial subalgebra generated by the polynomials
556         defining phi. Hence, if the basering has local or mixed ordering then
557         the return value 1 means surjectivity in this sense.
558EXAMPLE: example is_surjective; shows an example
559"
560{
561  def br=basering;
562    ideal B = ideal(br);
563    int s = size(B);
564    int n = nvars(br);
565    ideal A = ideal(phi);
566    int m = ncols(A);
567    int ii,t=1,1;
568    string mp=string(minpoly);
569  // ------------ create new ring with extra variables ---------------------
570  execute ("ring R=("+charstr(br)+"),(x(1..n),y(1..m)),(dp(n),dp(m));");
571    execute ("minpoly=number("+mp+");");
572    ideal vars = x(1..n);
573    map emb = br,vars;
574    if ( s != 0 )
575    {  ideal B = emb(B);
576       attrib(B,"isSB",1);
577       qring Q = B;
578       ideal vars = x(1..n);
579       map emb = br,vars;
580    }
581    ideal A = emb(A);
582    for ( ii=1; ii<=m; ii++ )
583    { A[ii] = A [ii]-y(ii);
584    }
585    A=std(A);
586  // ------------- check whether the x(i) are in the image -----------------   
587    poly check;
588    for (ii=1; ii<=n; ii++ )
589    {  check=reduce(x(ii),A,1);
590  // --- checking whether all variables from old ring have disappeared -----
591  // if so, then the sum of the first n leading exponents is 0
592       if( sum(leadexp(check),1..n)!=0 )
593       { t=0;
594         break;
595       }
596    }
597   return(t);
598}
599example
600{ "EXAMPLE:"; echo = 2;
601   ring R = 0,(x,y,z),dp;
602   ideal i = x, y, x2-y3;
603   map phi = R,i;                    // a map from R to itself, z->x2-y3
604   is_surjective(phi);
605   qring Q = std(ideal(z-x37));
606   map psi = R, x,y,x2-y3;           // the same map to the quotient ring
607   is_surjective(psi);
608
609   ring S = 0,(a,b,c),dp;
610   map psi = R,ideal(a,a+b,c-a2+b3); // a map from R to S,
611   is_surjective(psi);               // x->a, y->a+b, z->c-a2+b3
612}
613
614///////////////////////////////////////////////////////////////////////////////
615
616proc is_bijective ( map phi, pr )
617"USAGE:   is_bijective(phi); phi map to basering, pr preimage ring
618RETURN:  an integer,  1 if phi is bijective, 0 if not
619NOTE:    The algorithm checks first injectivity and then surjectivity
620         To interprete this for local or mixed orderings, type
621         help is_surjective;
622DISPLAY: Comment if printlevel >= voice-1 (default)
623EXAMPLE: example is_bijective; shows an example
624"
625{
626  def br = basering;
627    int n = nvars(br);
628    ideal B = ideal(br);
629    int s = size(B);
630    ideal A = ideal(phi);
631    //folgendes Auffuellen oder Stutzen ist ev nicht mehr noetig
632    //falls map das richtig macht
633    int m = nvars(pr);
634    ideal j;
635    j[m]=0;
636    A=A,j;
637    A=A[1..m];
638    int ii,t = 1,1;
639    string mp=string(minpoly);
640  // ------------ create new ring with extra variables ---------------------
641  execute ("ring R=("+charstr(br)+"),(x(1..n),y(1..m)),(dp(n),dp(m));");
642    execute ("minpoly=number("+mp+");");
643    ideal vars = x(1..n);
644    map emb = br,vars;
645    if ( s != 0 )
646    {  ideal B = emb(B);
647       attrib(B,"isSB",1);
648       qring Q = B;
649       ideal vars = x(1..n);
650       map emb = br,vars;
651    }
652    ideal A = emb(A);
653    for ( ii=1; ii<=m; ii++ )
654    { A[ii] = A[ii]-y(ii);
655    }
656    A=std(A);
657    def bsr = basering;
658   
659 // ------- checking whether phi is injective by computing the kernel -------
660    ideal ker = nselect(A,1,n);
661    t = size(ker);
662    setring pr;
663    if ( size(ideal(pr)) != 0 )
664    {
665      ideal proj;
666      proj [n+1..m] = maxideal(1);
667      map psi = bsr,proj;
668      t = size(NF(psi(ker),std(0))) == 0;
669    }
670    if ( t != 0 )
671    {  dbprint(printlevel-voice+3,"// map not injective" );
672      return(0);
673    }
674   else
675 // -------------- checking whether phi is surjective ----------------------
676   { t = 1;
677     setring bsr;
678     poly check;
679     for (ii=1; ii<=n; ii++ )
680     {  check=reduce(x(ii),A,1);
681  // --- checking whether all variables from old ring have disappeared -----
682  // if so, then the sum of the first n leading exponents is 0
683        if( sum(leadexp(check),1..n)!=0 )
684        { t=0;
685          break;
686        }
687     }
688     if ( t == 0 )
689     {  dbprint(printlevel-voice+3,"// map injective, but not surjective" );
690     }   
691     return(t);
692   }
693}
694example
695{ "EXAMPLE:"; echo = 2;
696   int p = printlevel;  printlevel = 1;
697   ring R = 0,(x,y,z),dp;
698   ideal i = x, y, x2-y3;
699   map phi = R,i;                      // a map from R to itself, z->x2-y3
700   is_bijective(phi,R);
701   qring Q = std(z-x2+y3);
702   is_bijective(ideal(x,y,x2-y3),Q);
703   
704   ring S = 0,(a,b,c,d),dp;
705   map psi = R,ideal(a,a+b,c-a2+b3,0); // a map from R to S,
706   is_bijective(psi,R);                // x->a, y->a+b, z->c-a2+b3
707   qring T = std(d,c-a2+b3);
708   map chi = Q,a,b,a2-b3;              // amap between two quotient rings
709   is_bijective(chi,Q);
710   
711   printlevel = p;
712}
713
714///////////////////////////////////////////////////////////////////////////////
Note: See TracBrowser for help on using the repository browser.