source: git/Singular/LIB/algebra.lib @ 1e1ec4

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