1 | /////////////////////////////////////////////////////////////////////////////// |
---|
2 | version="$Id: algebra.lib,v 1.1 1999-07-19 14:54:07 obachman Exp $"; |
---|
3 | info=" |
---|
4 | LIBRARY: algebra.lib PROCEDURES FOR COMPUTING WITH ALGBRAS AND MAPS |
---|
5 | AUTHORS: 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 | |
---|
9 | PROCEDURES: |
---|
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 | |
---|
25 | proc 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 |
---|
28 | RETURN: - 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 |
---|
38 | DISPLAY: 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) |
---|
40 | NOTE: The proc inSubring uses a different algorithm which is sometimes faster |
---|
41 | THEORY: 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]. |
---|
46 | EXAMPLE: 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 | } |
---|
95 | example |
---|
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 | |
---|
113 | proc 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] |
---|
117 | ASSUME: ncols(P) = nvars(basering), the P[i] are algebraically independent |
---|
118 | RETURN: - 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 |
---|
129 | DISPLAY: 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) |
---|
132 | THEORY: 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. |
---|
139 | EXAMPLE: 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 | } |
---|
194 | example |
---|
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 | |
---|
210 | proc inSubring(poly p, ideal I) |
---|
211 | "USAGE: inSubring(p,i); p poly, i ideal |
---|
212 | RETURN: 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. |
---|
218 | NOTE: the proc algebra_containment tests the same with a different |
---|
219 | algorithm, which is often faster |
---|
220 | EXAMPLE: 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 | } |
---|
258 | example |
---|
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 | |
---|
267 | proc algDependence( ideal A, list # ) |
---|
268 | "USAGE: algDependence(f[,c]); f ideal (say, f = f1,...,fm), c integer |
---|
269 | RETURN: 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; |
---|
280 | DISPLAY: The above comment is displayed if printlevel >= 0 (default). |
---|
281 | EXAMPLE: 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 | } |
---|
372 | example |
---|
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 | ////////////////////////////////////////////////////////////////////////////// |
---|
385 | proc 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 |
---|
388 | RETURN: 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) |
---|
394 | NOTE: The basering may be a quotient ring. |
---|
395 | EXAMPLE: 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 | } |
---|
439 | example |
---|
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 | |
---|
459 | proc is_injective( map phi, pr,list #) |
---|
460 | "USAGE: is_injective(phi[,c,s]); phi map, pr reimage ring, c int, s string |
---|
461 | RETURN: - 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. |
---|
469 | NOTE: 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; |
---|
472 | DISPLAY: The above comment is displayed if printlevel >= 0 (default). |
---|
473 | EXAMPLE: 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 | } |
---|
531 | example |
---|
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 | |
---|
551 | proc is_surjective( map phi ) |
---|
552 | "USAGE: is_surjective(phi); phi map to basering, or ideal defining it |
---|
553 | RETURN: an integer, 1 if phi is surjective, 0 if not |
---|
554 | NOTE: 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. |
---|
558 | EXAMPLE: 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 | } |
---|
599 | example |
---|
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 | |
---|
616 | proc is_bijective ( map phi, pr ) |
---|
617 | "USAGE: is_bijective(phi); phi map to basering, pr preimage ring |
---|
618 | RETURN: an integer, 1 if phi is bijective, 0 if not |
---|
619 | NOTE: The algorithm checks first injectivity and then surjectivity |
---|
620 | To interprete this for local or mixed orderings, type |
---|
621 | help is_surjective; |
---|
622 | DISPLAY: Comment if printlevel >= voice-1 (default) |
---|
623 | EXAMPLE: 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 | } |
---|
694 | example |
---|
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 | /////////////////////////////////////////////////////////////////////////////// |
---|