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