1 | // $Id: elim.lib,v 1.23 2008-10-06 17:04:26 Singular Exp $ |
---|
2 | // (GMG, last modified 22.06.96) |
---|
3 | /////////////////////////////////////////////////////////////////////////////// |
---|
4 | version="$Id: elim.lib,v 1.23 2008-10-06 17:04:26 Singular Exp $"; |
---|
5 | category="Commutative Algebra"; |
---|
6 | info=" |
---|
7 | LIBRARY: elim.lib Elimination, Saturation and Blowing up |
---|
8 | |
---|
9 | PROCEDURES: |
---|
10 | blowup0(j[,s1,s2]); create presentation of blownup ring of ideal j |
---|
11 | elim(id,v); eliminate variables in v from id (ideal/module) |
---|
12 | elim1(id,p); p=product of vars to be eliminated from id |
---|
13 | nselect(id,v); select generators not containing variables given by v |
---|
14 | sat(id,j); saturated quotient of ideal/module id by ideal j |
---|
15 | select(id,v); select generators containing all variables given by v |
---|
16 | select1(id,v); select generators containing one variable given by v |
---|
17 | |
---|
18 | (parameters in square brackets [] are optional) |
---|
19 | "; |
---|
20 | |
---|
21 | LIB "inout.lib"; |
---|
22 | LIB "general.lib"; |
---|
23 | LIB "poly.lib"; |
---|
24 | |
---|
25 | /////////////////////////////////////////////////////////////////////////////// |
---|
26 | |
---|
27 | proc blowup0 (ideal J,ideal C, list #) |
---|
28 | "USAGE: blowup0(J,C [,W]); J,C,W ideals |
---|
29 | @* C = ideal of center of blowup, J = ideal to be blown up, |
---|
30 | W = ideal of ambient space |
---|
31 | ASSUME: inclusion of ideals : W in J, J in C. |
---|
32 | If not, the procedure replaces J by J+W and C by C+J+W |
---|
33 | RETURN: a ring, say B, containing the ideals C,J,W and the ideals |
---|
34 | @* - bR (ideal defining the blown up basering) |
---|
35 | @* - aS (ideal of blown up ambient space) |
---|
36 | @* - eD (ideal of exceptional divisor) |
---|
37 | @* - tT (ideal of total transform) |
---|
38 | @* - sT (ideal of strict transform) |
---|
39 | @* - bM (ideal of the blowup map from basering to B) |
---|
40 | @* such that B/bR is isomorphic to the blowup ring BC. |
---|
41 | PURPOSE: compute the projective blowup of the basering in the center C, the |
---|
42 | exceptional locus, the total and strict tranform of J, |
---|
43 | and the blowup map. |
---|
44 | The projective blowup is a presentation of the blowup ring |
---|
45 | BC = R[C] = R + t*C + t^2*C^2 + ... (also called Rees ring) of the |
---|
46 | ideal C in the ring basering R. |
---|
47 | THEORY: If basering = K[x1,...,xn] and C = <f1,...,fk> then let |
---|
48 | B = K[x1,...,xn,y1,...,yk] and aS the preimage in B of W |
---|
49 | under the map B -> K[x1,...,xn,t], xi -> xi, yi -> t*fi. |
---|
50 | aS is homogeneous in the variables yi and defines a variety |
---|
51 | Z=V(aS) in A^n x P^(k-1), the ambient space of the blowup of V(W). |
---|
52 | The projection Z -> A^n is an isomorphism outside the preimage |
---|
53 | of the center V(C) in A^n and is called the blowup of the center. |
---|
54 | The preimage of V(C) is called the exceptional set, the preimage of |
---|
55 | V(J) is called the total transform of V(J). The strict transform |
---|
56 | is the closure of (total transform - exceptional set). |
---|
57 | @* If C = <x1,...,xn> then aS = <yi*xj - yj*xi | i,j=1,...,n> |
---|
58 | and Z is the blowup of A^n in 0, the exceptional set is P^(k-1). |
---|
59 | NOTE: The procedure creates a new ring with variables y(1..k) and x(1..n) |
---|
60 | where n=nvars(basering) and k=ncols(C). The ordering is a block |
---|
61 | ordering where the x-block has the ordering of the basering and |
---|
62 | the y-block has ordering dp if C is not homogeneous |
---|
63 | resp. the weighted ordering wp(b1,...bk) if C is homogeneous |
---|
64 | with deg(C[i])=bi. |
---|
65 | SEE ALSO:blowUp |
---|
66 | EXAMPLE: example blowup0; shows examples |
---|
67 | "{ |
---|
68 | def br = basering; |
---|
69 | list l = ringlist(br); |
---|
70 | int n,k,i = nvars(br),ncols(C),0; |
---|
71 | ideal W; |
---|
72 | if (size(#) !=0) |
---|
73 | { W = #[1];} |
---|
74 | J = J,W; |
---|
75 | //J = interred(J+W); |
---|
76 | //------------------------- create rings for blowup ------------------------ |
---|
77 | //Create rings tr = K[x(1),...,x(n),t] and nr = K[x(1),...,x(n),y(1),...,y(k)] |
---|
78 | //and map Bl: nr --> tr, x(i)->x(i), y(i)->t*fi. |
---|
79 | //Let ord be the ordering of the basering. |
---|
80 | //We change the ringlist l by changing l[2] and l[3] |
---|
81 | //For K[t,x(1),...,x(n),t] |
---|
82 | // - l[2]: the variables to x(1),...,x(n),t |
---|
83 | // - l[3]: the ordering to a block ordering (ord,dp(1)) |
---|
84 | //For K[x(1),...,x(n),y(1),...,y(k)] |
---|
85 | // - l[2]: the variables to x(1),...,x(n),y(1),...,y(k), |
---|
86 | // - l[3]: the ordering to a block ordering (ord,dp) if C is |
---|
87 | // not homogeneous or to (ord,wp(b1,...bk),ord) if C is |
---|
88 | // homogeneous with deg(C[i])=bi; |
---|
89 | |
---|
90 | //--------------- create tr = K[x(1),...,x(n),t] --------------------------- |
---|
91 | int s = size(l[3]); |
---|
92 | for ( i=1; i<=n; i++) |
---|
93 | { |
---|
94 | l[2][i]="x("+string(i)+")"; |
---|
95 | } |
---|
96 | l[2]=insert(l[2],"t",n); |
---|
97 | l[3]=insert(l[3],list("dp",1),s-1); |
---|
98 | def tr = ring(l); |
---|
99 | |
---|
100 | //--------------- create nr = K[x(1),...,x(n),y(1),...,y(k)] --------------- |
---|
101 | l[2]=delete(l[2],n+1); |
---|
102 | l[3]=delete(l[3],s); |
---|
103 | for ( i=1; i<=k; i++) |
---|
104 | { |
---|
105 | l[2][n+i]="y("+string(i)+")"; |
---|
106 | } |
---|
107 | |
---|
108 | //---- change l[3]: |
---|
109 | l[3][s+1] = l[3][s]; // save the module ordering of the basering |
---|
110 | intvec w; |
---|
111 | w[k]=0; w=w+1; |
---|
112 | intvec v; // containing the weights for the varibale |
---|
113 | if( homog(C) ) |
---|
114 | { |
---|
115 | for( i=1; i<=k; i++) |
---|
116 | { |
---|
117 | v[i]=deg(C[i]); |
---|
118 | } |
---|
119 | if (v != w) |
---|
120 | { |
---|
121 | l[3][s]=list("wp",v); |
---|
122 | } |
---|
123 | else |
---|
124 | { |
---|
125 | l[3][s]=list("dp",v); |
---|
126 | } |
---|
127 | } |
---|
128 | else |
---|
129 | { |
---|
130 | for( i=1; i<=k; i++) |
---|
131 | { |
---|
132 | v[i]=1; |
---|
133 | } |
---|
134 | l[3][s]=list("dp",v); |
---|
135 | } |
---|
136 | def nr = ring(l); |
---|
137 | |
---|
138 | //-------- create blowup map Bl: nr --> tr, x(i)->x(i), y(i)->t*fi --------- |
---|
139 | setring tr; |
---|
140 | ideal C = fetch(br,C); |
---|
141 | ideal bl = x(1..n); |
---|
142 | for( i=1; i<=k; i++) { bl = bl,t*C[i]; } |
---|
143 | map Bl = nr,bl; |
---|
144 | ideal Z; |
---|
145 | //------------------ compute blown up objects and return ------------------- |
---|
146 | setring nr; |
---|
147 | ideal bR = preimage(tr,Bl,Z); //ideal of blown up affine space A^n |
---|
148 | ideal C = fetch(br,C); |
---|
149 | ideal J = fetch(br,J); |
---|
150 | ideal W = fetch(br,W); |
---|
151 | ideal aS = interred(bR+W); //ideal of ambient space |
---|
152 | ideal tT = interred(J+bR+W); //ideal of total transform |
---|
153 | ideal eD = interred(C+J+bR+W); //ideal of exceptional divisor |
---|
154 | ideal sT = sat(tT,C)[1]; //ideal of strict transform |
---|
155 | ideal bM = x(1..n); //ideal of blowup map br --> nr |
---|
156 | |
---|
157 | export(bR,C,J,W,aS,tT,eD,sT,bM); |
---|
158 | return(nr); |
---|
159 | } |
---|
160 | example |
---|
161 | { "EXAMPLE:"; echo = 2; |
---|
162 | ring r = 0,(x,y),dp; |
---|
163 | poly f = x2+y3; |
---|
164 | ideal C = x,y; //center of blowup |
---|
165 | def B1 = blowup0(f,C); |
---|
166 | setring B1; |
---|
167 | aS; //ideal of blown up ambient space |
---|
168 | tT; //ideal of total transform of f |
---|
169 | sT; //ideal of strict transform of f |
---|
170 | eD; //ideal of exceptional divisor |
---|
171 | bM; //ideal of blowup map r --> B1 |
---|
172 | |
---|
173 | ring R = 0,(x,y,z),ds; |
---|
174 | poly f = y2+x3+z5; |
---|
175 | ideal C = y2,x,z; |
---|
176 | ideal W = z-x; |
---|
177 | def B2 = blowup0(f,C,W); |
---|
178 | setring B2; |
---|
179 | B2; //weighted ordering |
---|
180 | bR; //ideal of blown up R |
---|
181 | aS; //ideal of blown up R/W |
---|
182 | sT; //strict transform of f |
---|
183 | eD; //ideal of exceptional divisor |
---|
184 | //Note that the different affine charts are {y(i)=1} |
---|
185 | } |
---|
186 | /////////////////////////////////////////////////////////////////////////////// |
---|
187 | |
---|
188 | |
---|
189 | /////////////////////////////////////////////////////////////////////////////// |
---|
190 | |
---|
191 | proc elim (id, intvec va) |
---|
192 | "USAGE: elim(id,v); id ideal/module, v intvec |
---|
193 | RETURNS: ideal/module obtained from id by eliminating variables in v |
---|
194 | NOTE: no special monomial ordering is required, result is a SB with |
---|
195 | respect to ordering dp (resp. ls) if the first var not to be |
---|
196 | eliminated belongs to a -p (resp. -s) blockordering |
---|
197 | This proc uses 'execute' or calls a procedure using 'execute'. |
---|
198 | SEE ALSO: elim1, eliminate |
---|
199 | EXAMPLE: example elim; shows examples |
---|
200 | " |
---|
201 | { |
---|
202 | //---- get variables to be eliminated and create string for new ordering ------ |
---|
203 | int ii; poly vars=1; |
---|
204 | for( ii=1; ii<=size(va); ii++ ) { vars=vars*var(va[ii]); } |
---|
205 | if( attrib(basering,"global")) { string ordering = "),dp;"; } |
---|
206 | else { string ordering = "),ls;"; } |
---|
207 | string mpoly=string(minpoly); |
---|
208 | //-------------- create new ring and map objects to new ring ------------------ |
---|
209 | def br = basering; |
---|
210 | string str = "ring @newr = ("+charstr(br)+"),("+varstr(br)+ordering; |
---|
211 | execute(str); |
---|
212 | if (mpoly!="0") { execute("minpoly="+mpoly+";"); } |
---|
213 | def i = imap(br,id); |
---|
214 | poly vars = imap(br,vars); |
---|
215 | //---------- now eliminate in new ring and map back to old ring --------------- |
---|
216 | i = eliminate(i,vars); |
---|
217 | setring br; |
---|
218 | return(imap(@newr,i)); |
---|
219 | } |
---|
220 | example |
---|
221 | { "EXAMPLE:"; echo = 2; |
---|
222 | ring r=0,(x,y,u,v,w),dp; |
---|
223 | ideal i=x-u,y-u2,w-u3,v-x+y3; |
---|
224 | elim(i,3..4); |
---|
225 | module m=i*gen(1)+i*gen(2); |
---|
226 | m=elim(m,3..4);show(m); |
---|
227 | } |
---|
228 | /////////////////////////////////////////////////////////////////////////////// |
---|
229 | |
---|
230 | proc elim1 (id, poly vars) |
---|
231 | "USAGE: elim1(id,p); id ideal/module, p product of vars to be eliminated |
---|
232 | RETURN: ideal/module obtained from id by eliminating vars occuring in poly |
---|
233 | NOTE: no special monomial ordering is required, result is a SB with |
---|
234 | respect to ordering dp (resp. ls) if the first var not to be |
---|
235 | eliminated belongs to a -p (resp. -s) blockordering |
---|
236 | This proc uses 'execute' or calls a procedure using 'execute'. |
---|
237 | SEE ALSO: elim, eliminate |
---|
238 | EXAMPLE: example elim1; shows examples |
---|
239 | " |
---|
240 | { |
---|
241 | //---- get variables to be eliminated and create string for new ordering ------ |
---|
242 | int ii; |
---|
243 | for( ii=1; ii<=nvars(basering); ii++ ) |
---|
244 | { |
---|
245 | if( vars/var(ii)==0 ) { poly p = 1+var(ii); break;} |
---|
246 | } |
---|
247 | if( ord(p)==0 ) { string ordering = "),ls;"; } |
---|
248 | if( ord(p)>0 ) { string ordering = "),dp;"; } |
---|
249 | //-------------- create new ring and map objects to new ring ------------------ |
---|
250 | def br = basering; |
---|
251 | string str = "ring @newr = ("+charstr(br)+"),("+varstr(br)+ordering; |
---|
252 | execute(str); |
---|
253 | def id = fetch(br,id); |
---|
254 | poly vars = fetch(br,vars); |
---|
255 | //---------- now eliminate in new ring and map back to old ring --------------- |
---|
256 | id = eliminate(id,vars); |
---|
257 | setring br; |
---|
258 | return(imap(@newr,id)); |
---|
259 | } |
---|
260 | example |
---|
261 | { "EXAMPLE:"; echo = 2; |
---|
262 | ring r=0,(x,y,t,s,z),dp; |
---|
263 | ideal i=x-t,y-t2,z-t3,s-x+y3; |
---|
264 | elim1(i,ts); |
---|
265 | module m=i*gen(1)+i*gen(2); |
---|
266 | m=elim1(m,st); show(m); |
---|
267 | } |
---|
268 | /////////////////////////////////////////////////////////////////////////////// |
---|
269 | |
---|
270 | proc nselect (id_inp, intvec v) |
---|
271 | "USAGE: nselect(id,v); id = module or ideal, v = intvec |
---|
272 | RETURN: generators of id not containing the variables with index an entry of v |
---|
273 | SEE ALSO: select, select1 |
---|
274 | EXAMPLE: example nselect; shows examples |
---|
275 | " |
---|
276 | { |
---|
277 | if (typeof(id_inp)!="ideal") { module id=module(id_inp); } |
---|
278 | else { ideal id=id_inp; } |
---|
279 | int j,k; |
---|
280 | int n,m = size(v), ncols(id); |
---|
281 | //listvar(id); |
---|
282 | for( k=1; k<=m; k++ ) |
---|
283 | { |
---|
284 | for( j=1; j<=n; j++ ) |
---|
285 | { |
---|
286 | if( size(id[k]/var(v[j]))!=0 ) |
---|
287 | { |
---|
288 | id[k]=0; break; |
---|
289 | } |
---|
290 | } |
---|
291 | } |
---|
292 | //if(typeof(id)=="ideal") { return(simplify(id,2)); } |
---|
293 | //return(simplify(module(id),2)); |
---|
294 | id=(simplify(module(id),2)); |
---|
295 | //listvar(id); |
---|
296 | return(id); |
---|
297 | //return(simplify(id,2)); |
---|
298 | } |
---|
299 | example |
---|
300 | { "EXAMPLE:"; echo = 2; |
---|
301 | ring r=0,(x,y,t,s,z),(c,dp); |
---|
302 | ideal i=x-y,y-z2,z-t3,s-x+y3; |
---|
303 | nselect(i,3); |
---|
304 | module m=i*(gen(1)+gen(2)); |
---|
305 | show(m); |
---|
306 | show(nselect(m,3..4)); |
---|
307 | } |
---|
308 | /////////////////////////////////////////////////////////////////////////////// |
---|
309 | |
---|
310 | proc sat (id, ideal j) |
---|
311 | "USAGE: sat(id,j); id=ideal/module, j=ideal |
---|
312 | RETURN: list of an ideal/module [1] and an integer [2]: |
---|
313 | [1] = saturation of id with respect to j (= union_(k=1...) of id:j^k) |
---|
314 | [2] = saturation exponent (= min( k | id:j^k = id:j^(k+1) )) |
---|
315 | NOTE: [1] is a standard basis in the basering |
---|
316 | DISPLAY: saturation exponent during computation if printlevel >=1 |
---|
317 | EXAMPLE: example sat; shows an example |
---|
318 | "{ |
---|
319 | int ii,kk; |
---|
320 | def i=id; |
---|
321 | id=std(id); |
---|
322 | int p = printlevel-voice+3; // p=printlevel+1 (default: p=1) |
---|
323 | while( ii<=size(i) ) |
---|
324 | { |
---|
325 | dbprint(p-1,"// compute quotient "+string(kk+1)); |
---|
326 | i=quotient(id,j); |
---|
327 | for( ii=1; ii<=size(i); ii++ ) |
---|
328 | { |
---|
329 | if( reduce(i[ii],id,1)!=0 ) break; |
---|
330 | } |
---|
331 | id=std(i); kk++; |
---|
332 | } |
---|
333 | dbprint(p-1,"// saturation becomes stable after "+string(kk-1)+" iteration(s)",""); |
---|
334 | list L = id,kk-1; |
---|
335 | return (L); |
---|
336 | } |
---|
337 | example |
---|
338 | { "EXAMPLE:"; echo = 2; |
---|
339 | int p = printlevel; |
---|
340 | ring r = 2,(x,y,z),dp; |
---|
341 | poly F = x5+y5+(x-y)^2*xyz; |
---|
342 | ideal j = jacob(F); |
---|
343 | sat(j,maxideal(1)); |
---|
344 | printlevel = 2; |
---|
345 | sat(j,maxideal(2)); |
---|
346 | printlevel = p; |
---|
347 | } |
---|
348 | /////////////////////////////////////////////////////////////////////////////// |
---|
349 | |
---|
350 | proc select (id, intvec v) |
---|
351 | "USAGE: select(id,n[,m]); id = ideal/module, v= intvec |
---|
352 | RETURN: generators of id containing all variables with index an entry of v |
---|
353 | NOTE: use 'select1' for selecting generators containing at least one of the |
---|
354 | variables with index an entry of v |
---|
355 | SEE ALSO: select1, nselect |
---|
356 | EXAMPLE: example select; shows examples |
---|
357 | "{ |
---|
358 | int j,k; |
---|
359 | int n,m = size(v), ncols(id); |
---|
360 | for( k=1; k<=m; k++ ) |
---|
361 | { |
---|
362 | for( j=1; j<=n; j++ ) |
---|
363 | { |
---|
364 | if( size(id[k]/var(v[j]))==0) |
---|
365 | { |
---|
366 | id[k]=0; break; |
---|
367 | } |
---|
368 | } |
---|
369 | } |
---|
370 | return(simplify(id,2)); |
---|
371 | } |
---|
372 | example |
---|
373 | { "EXAMPLE:"; echo = 2; |
---|
374 | ring r=0,(x,y,t,s,z),(c,dp); |
---|
375 | ideal i=x-y,y-z2,z-t3,s-x+y3; |
---|
376 | ideal j=select(i,1); |
---|
377 | j; |
---|
378 | module m=i*(gen(1)+gen(2)); |
---|
379 | m; |
---|
380 | select(m,1..2); |
---|
381 | } |
---|
382 | /////////////////////////////////////////////////////////////////////////////// |
---|
383 | |
---|
384 | proc select1 (id, intvec v) |
---|
385 | "USAGE: select1(id,v); id = ideal/module, v = intvec |
---|
386 | RETURN: generators of id containing at least one of the variables with |
---|
387 | index an entry of v |
---|
388 | NOTE: use 'select' for selecting generators containing all the |
---|
389 | variables with index an entry of v |
---|
390 | SEE ALSO: select, nselect |
---|
391 | EXAMPLE: example select1; shows examples |
---|
392 | "{ |
---|
393 | int j,k; |
---|
394 | int n,m = size(v), ncols(id); |
---|
395 | execute (typeof(id)+" I;"); |
---|
396 | for( k=1; k<=m; k++ ) |
---|
397 | { for( j=1; j<=n; j++ ) |
---|
398 | { |
---|
399 | if( size(subst(id[k],var(v[j]),0)) != size(id[k]) ) |
---|
400 | { |
---|
401 | I = I,id[k]; break; |
---|
402 | } |
---|
403 | } |
---|
404 | } |
---|
405 | return(simplify(I,2)); |
---|
406 | } |
---|
407 | example |
---|
408 | { "EXAMPLE:"; echo = 2; |
---|
409 | ring r=0,(x,y,t,s,z),(c,dp); |
---|
410 | ideal i=x-y,y-z2,z-t3,s-x+y3; |
---|
411 | ideal j=select1(i,1); |
---|
412 | j; |
---|
413 | module m=i*(gen(1)+gen(2)); |
---|
414 | m; |
---|
415 | select1(m,1..2); |
---|
416 | } |
---|
417 | /////////////////////////////////////////////////////////////////////////////// |
---|