1 | //////////////////////////////////////////////////////////////////////////// |
---|
2 | version="version graal.lib 4.1.2.0 Feb_2019 "; // $Id$ |
---|
3 | category="Commutative Algebra"; |
---|
4 | info=" |
---|
5 | LIBRARY: graal.lib localization at prime ideals and their associated graded rings |
---|
6 | AUTHOR: Magdaleen Marais, magdaleen@aims.ac.za |
---|
7 | Yue Ren, ren@mathematik.uni-kl.de |
---|
8 | |
---|
9 | OVERVIEW: |
---|
10 | This library is on a computational treatment of localizations at prime ideals |
---|
11 | and their associated graded rings based on a work of Mora. |
---|
12 | Not only does it construct a ring isomorphic to the localization of an affine |
---|
13 | coordinate ring at a prime ideal, |
---|
14 | the algorithms in this library aim to exploit the topology in the localization |
---|
15 | by computing first and foremost in the associated graded ring and lifting |
---|
16 | the result to the localization afterwards. |
---|
17 | Features include a check for regularity and the resolution of ideals. |
---|
18 | |
---|
19 | REFERENCES: |
---|
20 | Mora, Teo: La queste del Saint Gr_a(A_L): A computational approach to local algebra |
---|
21 | Marais, Magdaleen and Ren, Yue: Mora's holy graal: Algorithms for computing in localizations at prime ideals |
---|
22 | |
---|
23 | PROCEDURES: |
---|
24 | graalMixed(ideal L[,int t]); contruct graalBearer |
---|
25 | dimensionOfLocalization(def L); dimension of the localization A_L of A at L |
---|
26 | systemOfParametersOfLocalization(def L); system of parameter of the localization A_L of A at L |
---|
27 | isLocalizationRegular(def L); test if localization A_L of A at L is regular |
---|
28 | warkedPreimageStd(warkedModule wM); std for warkedModule |
---|
29 | resolutionInLocalization(ideal I, def L); the resolution of I*A_L |
---|
30 | "; |
---|
31 | |
---|
32 | LIB "general.lib"; // for watchdog |
---|
33 | LIB "poly.lib"; // for hilbPoly |
---|
34 | LIB "standard.lib"; // for res |
---|
35 | |
---|
36 | proc mod_init() |
---|
37 | { |
---|
38 | /*** |
---|
39 | * graalBearer is a structure that contains those objects |
---|
40 | * of the intermediate steps to computing the associated graded algebra |
---|
41 | * that are worth saving for future computations. These are: |
---|
42 | * |
---|
43 | * ring A affine coordinate ring |
---|
44 | * ideal L ideal cutting out the subvariety |
---|
45 | * int s number of generators of L |
---|
46 | * ring Q polynomial ring of the ambient space |
---|
47 | * ideal H ideal such that A=Q/H |
---|
48 | * ideal J preimage of L |
---|
49 | * ring Q0y Q^0[Y1,...,Ys] |
---|
50 | * ideal scriptI <Y1-f1,...,Ys-fs>, where f1,...,fs are the generators of L |
---|
51 | * ring Al the ring A_L = Q0y/scriptI |
---|
52 | * ring Ky K[Y1,...,Ys], where K quotient field of A/L |
---|
53 | * ideal scriptIin I_in |
---|
54 | * ring Graal associated graded ring, isomorphic to Ky/scriptIin |
---|
55 | * map ina Al -> Graal, maps standard basis of ideals |
---|
56 | * to standard basis of their respective initial ideals |
---|
57 | **/ |
---|
58 | newstruct("graalBearer","int s, ring A, ideal L, ring Q, ideal H, ideal J, ring Q0, ideal J0, ring Q0y, ideal scriptI, ring Al, ring Ky, ideal scriptIin, map Q0yToKy, ring Graal, map ina"); |
---|
59 | system("install","graalBearer","print",graalBearer_print,1); |
---|
60 | |
---|
61 | /*** |
---|
62 | * warkedModule is a structure built to hold two corresponding modules in Ay and Ky respectively. |
---|
63 | * More precisely, it contains space for: |
---|
64 | * graalBearer Gr a graalBearer containing all relevant global structures |
---|
65 | * module modQ0y a module M over Q0y |
---|
66 | * module stdmodQ0y a standard basis of M with respect to the weight w |
---|
67 | * matrix qQ0y a transformation matrix over Q0y such that |
---|
68 | * stdmodAy = qQ0y*modQ0y |
---|
69 | * module modKy a module M_in over Ky |
---|
70 | * module stdmodKy a standard basis of M_in |
---|
71 | * matrix qKy a transformation Matrix over Ky such that |
---|
72 | * stdmodKy = qKy*modKy |
---|
73 | * intvec w an intvec containing the weights on M |
---|
74 | * Note: "wark" is a scots noun for building |
---|
75 | **/ |
---|
76 | newstruct("warkedModule","graalBearer Gr, module modQ0y, module stdmodQ0y, matrix qQ0y, module modKy, module stdmodKy, matrix qKy, intvec w"); |
---|
77 | system("install","warkedModule","print",warkedModule_print,1); |
---|
78 | |
---|
79 | /*** |
---|
80 | * markedResolution is a structure built to hold two corresponding resolutions in Al and Graal respectively. |
---|
81 | * More precisely, it contains space for: |
---|
82 | * graalBearer Gr a graalBearer containing all relevant global structures |
---|
83 | * ideal idealAl a standard basis of an ideal I in Al |
---|
84 | * resolution resAl a resolution of I over Al |
---|
85 | * resolution resGraal a resolution of inI, the initial ideal of I over Graal |
---|
86 | * list weight a list containing weights on the modules in resAl |
---|
87 | **/ |
---|
88 | newstruct("markedResolution","graalBearer Gr, ideal idealAl, resolution resAl, resolution resGraal, list weight"); |
---|
89 | system("install","markedResolution","print",markedResolution_print,1); |
---|
90 | } |
---|
91 | |
---|
92 | /////////////////////////////////////////////////////////////////////////////// |
---|
93 | |
---|
94 | |
---|
95 | /*** |
---|
96 | * returns the number of Y, each of them corresponding to a generator of J. |
---|
97 | * we assume that the Ys are written in the first non-"c" block of our ordering, |
---|
98 | * for example (Y(1..s),X(1..n)),(c,ds(s),dp(n)) |
---|
99 | * or (Y(1..s),X(1..n)),(ds(s),c,dp(n)) |
---|
100 | * but not (X(1..n),Y(1..s)),(c,dp(s),ds(n)). |
---|
101 | **/ |
---|
102 | static proc numberOfYs() |
---|
103 | { |
---|
104 | list L = ringlist(basering); |
---|
105 | if (L[3][1][1]!="c") |
---|
106 | { |
---|
107 | return(size(ringlist(basering)[3][1][2])); |
---|
108 | } |
---|
109 | else |
---|
110 | { |
---|
111 | return(size(ringlist(basering)[3][2][2])); |
---|
112 | } |
---|
113 | } |
---|
114 | |
---|
115 | |
---|
116 | static proc yinitial(def F, list #) |
---|
117 | { |
---|
118 | int s; |
---|
119 | if (size(#)>0 && typeof(#[1])=="int") |
---|
120 | { s = #[1]; } |
---|
121 | else |
---|
122 | { s = numberOfYs(); } |
---|
123 | if (typeof(F)=="poly") |
---|
124 | { |
---|
125 | int k = size(F); |
---|
126 | poly inF = F[1]; |
---|
127 | intvec expv = leadexp(F); |
---|
128 | int d = sum(intvec(expv[1..s])); |
---|
129 | for (int i=2; i<=k; i++) |
---|
130 | { |
---|
131 | expv = leadexp(F[i]); |
---|
132 | if (sum(intvec(expv[1..s])) == d) |
---|
133 | { inF = inF + F[i]; } |
---|
134 | else |
---|
135 | { break; } |
---|
136 | } |
---|
137 | return(inF); |
---|
138 | } |
---|
139 | if (typeof(F)=="ideal") |
---|
140 | { |
---|
141 | int k = size(F); |
---|
142 | ideal inF = yinitial(F[1]); |
---|
143 | for (int i=2; i<=k; i++) |
---|
144 | { inF[i] = yinitial(F[i],s); } |
---|
145 | return(inF); |
---|
146 | } |
---|
147 | } |
---|
148 | |
---|
149 | |
---|
150 | /*** |
---|
151 | * suppose X(1),...,X(n) are the variables in the ring containing g, |
---|
152 | * checks whether g contains the variables X(1),...,X(n-1). |
---|
153 | **/ |
---|
154 | static proc containsVariablesApartFromLast(poly g) |
---|
155 | { |
---|
156 | intvec expv; int d; int s = nvars(basering)-1; |
---|
157 | int i,j; |
---|
158 | for (j=1; j<=size(g); j++) |
---|
159 | { |
---|
160 | expv = leadexp(g[j]); |
---|
161 | for (i=1; i<=s; i++) |
---|
162 | { |
---|
163 | if (expv[i] > 0) |
---|
164 | { return(i); } |
---|
165 | } |
---|
166 | } |
---|
167 | return(0); |
---|
168 | } |
---|
169 | |
---|
170 | |
---|
171 | /*** |
---|
172 | * assuming that the ordering is lexicographical, |
---|
173 | * checks whether m is in general position with repect to it. |
---|
174 | **/ |
---|
175 | static proc isInGeneralPosition(ideal m) |
---|
176 | { |
---|
177 | int n = nvars(basering); |
---|
178 | if (n == 1) |
---|
179 | { return(1); } |
---|
180 | |
---|
181 | int k = size(m); |
---|
182 | if (k == n) |
---|
183 | { |
---|
184 | m = sort(m)[1]; poly g; |
---|
185 | for (int i=2; i<=k; i++) |
---|
186 | { |
---|
187 | g = m[i]; |
---|
188 | if (leadmonom(g)!=var(k-i+1) || containsVariablesApartFromLast(g-lead(g))) |
---|
189 | { return(0); } |
---|
190 | } |
---|
191 | g = m[1]; |
---|
192 | if (containsVariablesApartFromLast(g)) |
---|
193 | { return(0); } |
---|
194 | return(1); |
---|
195 | } |
---|
196 | return(0); |
---|
197 | } |
---|
198 | |
---|
199 | |
---|
200 | /*** |
---|
201 | * finds a transformation of the last variable |
---|
202 | * which maps m into general position with respect to the lexicographical ordering lp. |
---|
203 | * returns the image of the last variable under the transformation and the image of m. |
---|
204 | **/ |
---|
205 | static proc findGeneralPosition(ideal m) |
---|
206 | { |
---|
207 | list L = ringlist(basering); |
---|
208 | int newRing = 0; |
---|
209 | if (L[3][1][1]!="lp" || L[3][1][2]!=nvars(basering)) |
---|
210 | { |
---|
211 | def origin = basering; |
---|
212 | execute("ring ringForGeneralPosition = ("+charstr(basering)+"),("+varstr(basering)+"),lp;"); |
---|
213 | ideal m = fetch(origin,m); |
---|
214 | newRing = 1; |
---|
215 | } |
---|
216 | ideal mGeneralPosition = std(m); |
---|
217 | int n = nvars(basering); poly p = var(n); |
---|
218 | while (!isInGeneralPosition(mGeneralPosition)) |
---|
219 | { // apply generic coordinate change to the last variable, |
---|
220 | // m -> mGeneralPosition, X_n |-> p |
---|
221 | // until mGeneraliPosition is indeed in general position. |
---|
222 | p = randomLast(5)[n]; |
---|
223 | mGeneralPosition = subst(m,var(n),p); |
---|
224 | mGeneralPosition = std(mGeneralPosition); |
---|
225 | } |
---|
226 | if (newRing == 1) |
---|
227 | { |
---|
228 | setring origin; |
---|
229 | ideal mGeneralPosition = fetch(ringForGeneralPosition,mGeneralPosition); |
---|
230 | poly p = fetch(ringForGeneralPosition,p); |
---|
231 | } |
---|
232 | return(p,mGeneralPosition); |
---|
233 | } |
---|
234 | |
---|
235 | |
---|
236 | /*** |
---|
237 | * tries for t seconds to find a transformation of the last variable, |
---|
238 | * which maps m into general position with respect to the lexicographical ordering lp. |
---|
239 | * if successful, returns the image of the last variable as well as the image of m. |
---|
240 | * if unsuccessful, returns (0,0) instead. |
---|
241 | **/ |
---|
242 | static proc tryFindingGeneralPosition(ideal m, int t) |
---|
243 | { |
---|
244 | def p, mgp; |
---|
245 | p, mgp = watchdog(t,"findGeneralPosition(ideal("+string(m)+"))"); |
---|
246 | if (typeof(p)=="string") |
---|
247 | { return(0,0); } |
---|
248 | return(p,mgp); |
---|
249 | } |
---|
250 | |
---|
251 | |
---|
252 | /*** |
---|
253 | * if mgp is in general position with respect to the lexicographical ordering lp, |
---|
254 | * sorts the generators such that their order is |
---|
255 | * X(1) - g(1) |
---|
256 | * X(2) - g(2) |
---|
257 | * ... |
---|
258 | * X(n-1) - g(n-1) |
---|
259 | * g(n), |
---|
260 | * where g(1),...,g(n-1) are polynomials in X(n). |
---|
261 | **/ |
---|
262 | static proc sortIdealInGeneralPosition(ideal mgp) |
---|
263 | { |
---|
264 | int k = size(mgp); |
---|
265 | ideal sortedMgp; sortedMgp[k]=0; |
---|
266 | ASSUME(1,size(mgp)==nvars(basering)); |
---|
267 | for (int i=1; i<=k; i++) |
---|
268 | { |
---|
269 | poly g = mgp[i]; |
---|
270 | int j = containsVariablesApartFromLast(g); |
---|
271 | if (j>0) |
---|
272 | { sortedMgp[j] = g; } |
---|
273 | else |
---|
274 | { sortedMgp[k] = g; } |
---|
275 | kill g; |
---|
276 | kill j; |
---|
277 | } |
---|
278 | return(sortedMgp); |
---|
279 | } |
---|
280 | |
---|
281 | |
---|
282 | /*** |
---|
283 | * if mgp is in general position with respect to the lexicographical ordering lp, |
---|
284 | * and sorted (see above), returns g(1),...,g(n-1). |
---|
285 | **/ |
---|
286 | static proc getImagesOfPreviousX(ideal mgp) |
---|
287 | { |
---|
288 | def origin = basering; |
---|
289 | def getImagesRing = changeord(list(list("lp",nvars(basering)))); |
---|
290 | setring getImagesRing; |
---|
291 | |
---|
292 | ideal mgp = fetch(origin,mgp); |
---|
293 | int k = size(mgp); |
---|
294 | ideal imagesOfPreviousX; imagesOfPreviousX[k]=0; |
---|
295 | |
---|
296 | for (int i=1; i<=k; i++) |
---|
297 | { |
---|
298 | poly g = mgp[i]; |
---|
299 | ASSUME(1,leadexp(g)[i]==1); |
---|
300 | if (g!=0) |
---|
301 | { g = (lead(g)-g)/leadcoef(g); } |
---|
302 | imagesOfPreviousX[i] = g; |
---|
303 | kill g; |
---|
304 | } |
---|
305 | |
---|
306 | setring origin; |
---|
307 | ideal imagesOfPreviousX = fetch(getImagesRing,imagesOfPreviousX); |
---|
308 | return (imagesOfPreviousX); |
---|
309 | } |
---|
310 | |
---|
311 | |
---|
312 | proc graalMixed(ideal L, list #) |
---|
313 | " |
---|
314 | USAGE: graalMixed(L,t); L ideal, t int (optional) |
---|
315 | RETURN: graalBearer with all the necessary structures for our machinery |
---|
316 | if t specified and t>0, puts an upper time limit |
---|
317 | on finding a necessary transformation to map an intermediate ideal into general position. |
---|
318 | NOTE: assumes that the current basering is a domain and that L is a prime ideal. |
---|
319 | EXAMPLE: example graalMixed; shows an example |
---|
320 | " |
---|
321 | { |
---|
322 | graalBearer Gr; |
---|
323 | |
---|
324 | /*** |
---|
325 | * store ring A and ideal L |
---|
326 | **/ |
---|
327 | Gr.A = basering; Gr.L = L; |
---|
328 | int s = size(L); Gr.s = s; |
---|
329 | |
---|
330 | /*** |
---|
331 | * construct ring Q and ideals H,J |
---|
332 | **/ |
---|
333 | ideal H = ringlist(Gr.A)[4]; |
---|
334 | execute("ring Q = "+string(Gr.A)+";"); |
---|
335 | ideal H = fetch(Gr.A,H); H = sort(std(H))[1]; |
---|
336 | ideal J = fetch(Gr.A,L) + H; J = sort(std(J))[1]; |
---|
337 | Gr.Q = Q; Gr.H = H; Gr.J = J; |
---|
338 | |
---|
339 | /*** |
---|
340 | * construct ring Q0 and ideal J0 |
---|
341 | **/ |
---|
342 | intvec maxIndepSet = indepSet(std(J)); |
---|
343 | int trdeg = sum(maxIndepSet); |
---|
344 | int i; int n = nvars(Q); |
---|
345 | if (trdeg > 0) |
---|
346 | { |
---|
347 | string pars = ","; string vars; |
---|
348 | for (i=1; i<=n; i++) |
---|
349 | { |
---|
350 | if (maxIndepSet[i]>0) |
---|
351 | { pars = pars + string(var(i)) + ","; } |
---|
352 | else |
---|
353 | { vars = vars + string(var(i)) + ","; } |
---|
354 | } |
---|
355 | pars = pars[1..size(pars)-1]; |
---|
356 | vars = vars[1..size(vars)-1]; |
---|
357 | } |
---|
358 | else |
---|
359 | { string pars; string vars = varstr(basering); } |
---|
360 | execute("ring Q0 = ("+charstr(basering)+pars+"),("+vars+"),dp;"); |
---|
361 | ideal J0 = imap(Q,J); |
---|
362 | Gr.Q0 = Q0; |
---|
363 | Gr.J0 = J0; |
---|
364 | |
---|
365 | /*** |
---|
366 | * push J0 into general position |
---|
367 | **/ |
---|
368 | if (size(#)==0) |
---|
369 | { |
---|
370 | poly p; ideal mgp; |
---|
371 | p, mgp = findGeneralPosition(J0); |
---|
372 | } |
---|
373 | else |
---|
374 | { |
---|
375 | if ((#[1]==1) && (typeof(#[1])=="int")) |
---|
376 | { |
---|
377 | polg p; ideal mgp; |
---|
378 | p, mgp = tryFindingGeneralPosition(J0,#[1]); |
---|
379 | if (p == 0) |
---|
380 | { |
---|
381 | ERROR("timeout during computation of minimal polynomial"); |
---|
382 | return(Gr); |
---|
383 | } |
---|
384 | } |
---|
385 | else |
---|
386 | { |
---|
387 | ERROR("graal: unexpected optional paramemters"); |
---|
388 | return(Gr); |
---|
389 | } |
---|
390 | } |
---|
391 | n = nvars(Q0); |
---|
392 | mgp = sortIdealInGeneralPosition(mgp); |
---|
393 | ideal imageOfX = getImagesOfPreviousX(mgp); |
---|
394 | imageOfX[n] = p; |
---|
395 | for (i=1; i<n; i++) |
---|
396 | { |
---|
397 | imageOfX[n] = subst(imageOfX[n],var(i),imageOfX[i]); |
---|
398 | } |
---|
399 | poly g(n) = mgp[n]; |
---|
400 | |
---|
401 | /*** |
---|
402 | * construct Q0y, scriptI and Al |
---|
403 | **/ |
---|
404 | string ostring = ordstr(basering); |
---|
405 | ostring = ostring[1..size(ostring)-2]; |
---|
406 | execute("ring Q0y = ("+charstr(basering)+"),(Y(1..s),"+varstr(basering)+"),(ds(s),c,"+ostring+")"); |
---|
407 | setring Q0y; |
---|
408 | ideal H = imap(Gr.A,H); |
---|
409 | ideal J = imap(Gr.A,L); |
---|
410 | ideal scriptI = H; |
---|
411 | for (i=1; i<=s; i++) |
---|
412 | { scriptI = scriptI + poly(J[i]-Y(i)); } |
---|
413 | scriptI = std(scriptI); |
---|
414 | Gr.Q0y = Q0y; |
---|
415 | Gr.scriptI = scriptI; |
---|
416 | ideal inI = yinitial(scriptI,s); |
---|
417 | attrib(inI,"isSB",1); |
---|
418 | qring Al = scriptI; |
---|
419 | Gr.Al = Al; |
---|
420 | |
---|
421 | /*** |
---|
422 | * construct Ky and sigmainI |
---|
423 | **/ |
---|
424 | execute("ring KKy = ("+charstr(Q0)+"),(Y(1..s),"+varstr(Q0,nvars(Q0))+"),(c,dp(s),dp(1));"); |
---|
425 | poly minpolyOfK = imap(Q0,g(n)); |
---|
426 | qring Ky = std(minpolyOfK); |
---|
427 | |
---|
428 | ideal G = Y(1..s); ideal imageOfX = imap(Q0,imageOfX); |
---|
429 | int j1=1; |
---|
430 | for (i=1; i<=nvars(Q); i++) |
---|
431 | { |
---|
432 | if (maxIndepSet[i]==0) |
---|
433 | { G = G, imageOfX[j1]; j1++; } |
---|
434 | // if (maxIndepSet[i]>0) |
---|
435 | // { G = G, par(j2); j2++; } |
---|
436 | // else |
---|
437 | // { G = G, imageOfX[j1]; j1++; } |
---|
438 | } |
---|
439 | map Q0yToKy = Q0y,G; |
---|
440 | Gr.Q0yToKy = Q0yToKy; |
---|
441 | ideal scriptIin = Q0yToKy(inI); |
---|
442 | ASSUME(2,isStandardBasis(scriptIin)); |
---|
443 | scriptIin = std(scriptIin); |
---|
444 | Gr.Ky = Ky; |
---|
445 | Gr.scriptIin = scriptIin; |
---|
446 | |
---|
447 | /*** |
---|
448 | * construct Graal |
---|
449 | **/ |
---|
450 | qring Graal = scriptIin; |
---|
451 | Gr.Graal = Graal; |
---|
452 | map in_a = Al,imap(Ky,G); |
---|
453 | Gr.ina = in_a; |
---|
454 | |
---|
455 | return(Gr); |
---|
456 | } |
---|
457 | example |
---|
458 | { "EXAMPLE:"; echo = 2; |
---|
459 | // see [Mora] Example 6.5 |
---|
460 | ring Q = 0,(x,y,z),dp; |
---|
461 | ideal H = y2-xz; |
---|
462 | qring A = std(H); |
---|
463 | ideal L = x3-yz,x2y-z2; |
---|
464 | graalBearer Gr = graalMixed(L); Gr; |
---|
465 | } |
---|
466 | |
---|
467 | /*** |
---|
468 | * a print routine for graalBearers, |
---|
469 | * will overwrite the default print routine for newstructs |
---|
470 | **/ |
---|
471 | proc graalBearer_print(graalBearer Gr) |
---|
472 | { |
---|
473 | def A=Gr.A; setring A; |
---|
474 | "affine coordinate ring: "; |
---|
475 | " "+string(Gr.A); |
---|
476 | ideal quotientIdeal = ringlist(Gr.A)[4]; |
---|
477 | if (quotientIdeal != 0) |
---|
478 | { " mod <"+string(quotientIdeal)+">"; } |
---|
479 | ""; |
---|
480 | "ideal defining the subvariety: "; |
---|
481 | " <"+string(Gr.L)+">";""; |
---|
482 | def Al = Gr.Al; setring Al; |
---|
483 | "Al: "; |
---|
484 | " "+string(Gr.Al); |
---|
485 | ideal quotientIdeal = ringlist(basering)[4]; |
---|
486 | if (quotientIdeal != 0) |
---|
487 | { " mod <"+string(quotientIdeal)+">"; } |
---|
488 | kill quotientIdeal; |
---|
489 | def Graal = Gr.Graal; setring Graal; |
---|
490 | "graal: "; |
---|
491 | " "+string(Gr.Graal); |
---|
492 | ideal quotientIdeal = ringlist(basering)[4]; |
---|
493 | if (quotientIdeal != 0) |
---|
494 | { " mod <"+string(quotientIdeal)+">"; } |
---|
495 | kill quotientIdeal; |
---|
496 | " where "; |
---|
497 | setring Gr.A; |
---|
498 | for (int i=1; i<=Gr.s; i++) |
---|
499 | { " Y("+string(i)+") represents generator "+string(Gr.L[i]); } |
---|
500 | setring Al; |
---|
501 | list L = ringlist(basering); |
---|
502 | int yEnd = size(L[3][1][2]); |
---|
503 | ideal xAll; int n = nvars(basering); |
---|
504 | for (i=1; yEnd+i<=n; i++) |
---|
505 | { xAll[i] = var(yEnd+i); } |
---|
506 | string inaPrint = " and "+string(xAll)+" in Al are mapped to "; |
---|
507 | kill L; |
---|
508 | kill xAll; |
---|
509 | setring Graal; |
---|
510 | map ina = Gr.ina; |
---|
511 | ideal xAllImages; |
---|
512 | for (i=1; yEnd+i<=n; i++) |
---|
513 | { xAllImages[i] = ina[yEnd+i]; } |
---|
514 | inaPrint + string(xAllImages)+" in Graal"; |
---|
515 | kill ina; |
---|
516 | kill xAllImages; |
---|
517 | } |
---|
518 | |
---|
519 | /*** |
---|
520 | * a print routine for warkedModules, |
---|
521 | * will overwrite the default print routine for newstructs |
---|
522 | **/ |
---|
523 | proc warkedModule_print(warkedModule wM) |
---|
524 | { |
---|
525 | graalBearer Gr = wM.Gr; |
---|
526 | def Q0y = Gr.Q0y; setring Q0y; |
---|
527 | ideal quotientIdeal = ringlist(basering)[4]; |
---|
528 | "module over Q^0[Y] = "+string(basering)+" / <"+string(quotientIdeal)+">:"; |
---|
529 | print(matrix(wM.modQ0y)); |
---|
530 | "standard basis:"; |
---|
531 | print(matrix(wM.stdmodQ0y)); |
---|
532 | def Ky = Gr.Ky; setring Ky; |
---|
533 | ideal quotientIdeal = ringlist(basering)[4]; |
---|
534 | "module over K[Y] = "+string(basering)+" / <"+string(quotientIdeal)+">:"; |
---|
535 | print(matrix(wM.modKy)); |
---|
536 | "weights on the unit vectors: "+string(wM.w); |
---|
537 | } |
---|
538 | |
---|
539 | /*** |
---|
540 | * a print routine for markedModules, |
---|
541 | * will overwrite the default print routine for newstructs |
---|
542 | **/ |
---|
543 | proc markedModule_print(markedModule M) |
---|
544 | { |
---|
545 | graalBearer Gr = M.Gr; |
---|
546 | def Ay = Gr.Ky; setring Ay; |
---|
547 | module G = M.G; |
---|
548 | "module over Ay:"; |
---|
549 | print(G); |
---|
550 | def Ky = Gr.Graal; setring Ky; |
---|
551 | module H = M.H; |
---|
552 | "module over Ky:"; |
---|
553 | print(H); |
---|
554 | } |
---|
555 | |
---|
556 | |
---|
557 | proc dimensionOfLocalization(def L) |
---|
558 | " |
---|
559 | USAGE: dimensionOfLocalization(L); L ideal or graalBearer |
---|
560 | RETURN: int, the dimension of the localization A_L of A at L. |
---|
561 | EXAMPLE: example dimensionOfLocalization; shows an example |
---|
562 | " |
---|
563 | { |
---|
564 | if (typeof(L)=="ideal") |
---|
565 | { |
---|
566 | graalBearer Gr = graalMixed(L); |
---|
567 | return(dimensionOfLocalization(Gr)); |
---|
568 | } |
---|
569 | if (typeof(L)=="graalBearer") |
---|
570 | { |
---|
571 | graalBearer Gr = L; |
---|
572 | def Ky = Gr.Ky; setring Ky; |
---|
573 | ideal scriptIin = Gr.scriptIin; |
---|
574 | return(dim(scriptIin)); |
---|
575 | } |
---|
576 | ERROR("dimensionOfLocalization: unexpected parameters"); |
---|
577 | return(0); |
---|
578 | } |
---|
579 | example |
---|
580 | { |
---|
581 | "EXAMPLE:"; echo = 2; |
---|
582 | ring Q = 0,(X(1),X(2)),dp; |
---|
583 | ideal H = X(2)^2-(X(1)-1)*X(1)*(X(1)+1); |
---|
584 | ideal J = std(X(1),X(2)); |
---|
585 | qring A = std(H); |
---|
586 | ideal L = fetch(Q,J); |
---|
587 | graalBearer Gr = graalMixed(L); |
---|
588 | // def fA = Gr.fA; setring fA; |
---|
589 | dimensionOfLocalization(Gr); // = 1 |
---|
590 | } |
---|
591 | |
---|
592 | proc systemOfParametersOfLocalization(def L) |
---|
593 | " |
---|
594 | USAGE: systemOfParametersOfLocalization(def L); L ideal or graalBearer |
---|
595 | RETURN: ideal, a system of parameter of the localization A_L of A at L. |
---|
596 | EXAMPLE: example systemOfParameterOfLocalization; shows an example |
---|
597 | " |
---|
598 | { |
---|
599 | if (typeof(L)=="ideal") |
---|
600 | { |
---|
601 | graalBearer Gr = graalMixed(L); |
---|
602 | return(systemOfParametersOfIdealInLocalization(I, Gr)); |
---|
603 | } |
---|
604 | if (typeof(L)=="graalBearer") |
---|
605 | { |
---|
606 | graalBearer Gr = L; |
---|
607 | def Ky = Gr.Ky; setring Ky; |
---|
608 | int delta = dimensionOfLocalization(Gr); |
---|
609 | int s = Gr.s; |
---|
610 | int i,j; |
---|
611 | ideal H1 = Gr.scriptIin; |
---|
612 | for (i=1; i<=delta; i++) |
---|
613 | { |
---|
614 | poly lambda(i); |
---|
615 | for (j=1; j<=s; j++) |
---|
616 | { |
---|
617 | int c(i)(j) = random(0,10000); |
---|
618 | lambda(i) = lambda(i) + c(i)(j)*Y(j); |
---|
619 | } |
---|
620 | H1 = H1 + lambda(i); |
---|
621 | } |
---|
622 | H1 = std(H1); |
---|
623 | while (dim(H1) != 0) |
---|
624 | { |
---|
625 | H1 = Gr.scriptIin; |
---|
626 | for (i=1; i<=delta; i++) |
---|
627 | { |
---|
628 | for (j=1; j<=s; j++) |
---|
629 | { |
---|
630 | c(i)(j) = random(0,10000); |
---|
631 | lambda(i) = lambda(i) + c(i)(j)*Y(j); |
---|
632 | } |
---|
633 | H1 = H1 + lambda(i); |
---|
634 | } |
---|
635 | H1 = std(H1); |
---|
636 | } |
---|
637 | def Q = Gr.Q; setring Q; |
---|
638 | ideal J = Gr.J; ideal ret; |
---|
639 | for (i=1; i<=delta; i++) |
---|
640 | { |
---|
641 | poly a(i); |
---|
642 | for (j=1; j<=s; j++) |
---|
643 | { a(i) = a(i)+c(i)(j)*J[i]; } |
---|
644 | ret = ret + a(i); |
---|
645 | } |
---|
646 | def A = Gr.A; setring A; |
---|
647 | return(std(fetch(Q,ret))); |
---|
648 | } |
---|
649 | ERROR("systemOfParametersOfLocalization: unexpected parameters"); |
---|
650 | return(0); |
---|
651 | } |
---|
652 | example |
---|
653 | { |
---|
654 | "EXAMPLE:"; echo = 2; |
---|
655 | ring Q = 0,(X(1),X(2)),dp; |
---|
656 | ideal H = X(2)^2-(X(1)-1)*X(1)*(X(1)+1); |
---|
657 | ideal J = X(1),X(2); |
---|
658 | qring A = std(H); |
---|
659 | ideal L = fetch(Q,J); |
---|
660 | graalBearer Gr = graalMixed(L); |
---|
661 | systemOfParametersOfLocalization(Gr); // = 1 |
---|
662 | } |
---|
663 | |
---|
664 | |
---|
665 | /*** |
---|
666 | * returns true, if g only contains the last variuable. |
---|
667 | * returns false otherwise. |
---|
668 | **/ |
---|
669 | static proc isPolyInLastVariable(poly g) |
---|
670 | { |
---|
671 | int k = size(g); |
---|
672 | int n = nvars(basering); |
---|
673 | for (int i=1; i<=k; i++) |
---|
674 | { |
---|
675 | intvec v = leadexp(g[i]); |
---|
676 | v = v[1..n-1]; |
---|
677 | if (sum(v)>0) |
---|
678 | { |
---|
679 | return (0); |
---|
680 | } |
---|
681 | } |
---|
682 | return (1); |
---|
683 | } |
---|
684 | |
---|
685 | proc isLocalizationRegular(def L) |
---|
686 | " |
---|
687 | USAGE: isLocalizationRegular(def L); L ideal or graalBearer |
---|
688 | RETURN: int, 1 if the localization A_L of A at L is regular, |
---|
689 | 0 otherwise. |
---|
690 | EXAMPLE: example isLocalizationRegular; shows an example |
---|
691 | " |
---|
692 | { |
---|
693 | if (typeof(L)=="ideal") |
---|
694 | { |
---|
695 | graalBearer Gr = graalMixed(L); |
---|
696 | return(isLocalizationRegular(Gr)); |
---|
697 | } |
---|
698 | if (typeof(L)=="graalBearer") |
---|
699 | { |
---|
700 | graalBearer Gr = L; |
---|
701 | def Ky = Gr.Ky; setring Ky; |
---|
702 | ideal sscriptIin = Gr.scriptIin; |
---|
703 | option(redSB); |
---|
704 | sscriptIin = std(sscriptIin); |
---|
705 | option(noredSB); |
---|
706 | int i,j; poly gi; intvec expv; |
---|
707 | int s = Gr.s; |
---|
708 | for (i=1; i<=size(sscriptIin); i++) |
---|
709 | { |
---|
710 | gi = sscriptIin[i]; |
---|
711 | if (!isPolyInLastVariable(gi)) |
---|
712 | { |
---|
713 | for (j=1; j<=size(gi); j++) |
---|
714 | { |
---|
715 | expv = leadexp(gi[i]); |
---|
716 | if (sum(intvec(expv[1..s])) != 1) |
---|
717 | { return(0); } |
---|
718 | } |
---|
719 | } |
---|
720 | } |
---|
721 | return(1); |
---|
722 | } |
---|
723 | ERROR("isLocalizationRegular: unexpected parameters"); |
---|
724 | return(0); |
---|
725 | } |
---|
726 | example |
---|
727 | { |
---|
728 | "EXAMPLE:"; echo = 2; |
---|
729 | ring Q = 0,(X(1),X(2)),dp; |
---|
730 | ideal H = X(2)^2-(X(1)-1)*X(1)*(X(1)+1); |
---|
731 | ideal J = X(1),X(2); |
---|
732 | qring A = std(H); |
---|
733 | ideal L = fetch(Q,J); |
---|
734 | graalBearer Gr = graalMixed(L); |
---|
735 | isLocalizationRegular(Gr); // = 1 |
---|
736 | } |
---|
737 | |
---|
738 | |
---|
739 | /*** |
---|
740 | * returns the degree in Y |
---|
741 | **/ |
---|
742 | static proc yDeg(poly g, list #) |
---|
743 | { |
---|
744 | int s; |
---|
745 | if (size(#)>0 && typeof(#[1])=="int") |
---|
746 | { s = #[1]; } |
---|
747 | else |
---|
748 | { s = numberOfYs(); } |
---|
749 | |
---|
750 | intvec v = leadexp(g); |
---|
751 | int d = 0; |
---|
752 | for (int i=1; i<=s; i++) |
---|
753 | { d = d+v[i]; } |
---|
754 | return (d); |
---|
755 | } |
---|
756 | |
---|
757 | |
---|
758 | /*** |
---|
759 | * normalizes g such that LT_>(g)=Y^\alpha for some \alpha\in\NN^n. |
---|
760 | **/ |
---|
761 | static proc normalizeInY(vector g, graalBearer Gr, list #) |
---|
762 | { |
---|
763 | def origin = basering; |
---|
764 | int s; |
---|
765 | if (size(#)>0 && typeof(#[1])=="int") |
---|
766 | { s = #[1]; } |
---|
767 | else |
---|
768 | { s = numberOfYs(); } |
---|
769 | |
---|
770 | // get the coefficient before Y in the leading term |
---|
771 | // first isolate the first non-zero component and computes its degree in Y |
---|
772 | poly cg; |
---|
773 | for (int i = 1; i<=nrows(g); i++) |
---|
774 | { |
---|
775 | if (g[i]!=0) |
---|
776 | { |
---|
777 | cg = g[i]; |
---|
778 | break; |
---|
779 | } |
---|
780 | } |
---|
781 | int d = yDeg(cg,s); |
---|
782 | // next, sum all terms with the same degree in Y |
---|
783 | poly c = cg[1]; |
---|
784 | for (i = 2; i<=size(g); i++) |
---|
785 | { |
---|
786 | if (yDeg(cg[i],s)==d) |
---|
787 | { c = c+cg[i]; } |
---|
788 | } |
---|
789 | // and substitute all Y with 1 |
---|
790 | for (i=1; i<=s; i++) |
---|
791 | { c = subst(c,var(i),1); } |
---|
792 | |
---|
793 | def Q0 = Gr.Q0; |
---|
794 | setring Q0; |
---|
795 | ideal J0 = Gr.J0; |
---|
796 | ideal J0withC = imap(origin,c), J0; |
---|
797 | list L = division(1,J0withC); |
---|
798 | |
---|
799 | ASSUME(1,L[2]==0); |
---|
800 | poly a = L[1][1,1]; |
---|
801 | |
---|
802 | kill J0; |
---|
803 | kill J0withC; |
---|
804 | kill L; |
---|
805 | setring origin; |
---|
806 | poly a = imap(Q0,a); |
---|
807 | |
---|
808 | ideal scriptI = Gr.scriptI; |
---|
809 | g = reduce(a*g,scriptI); |
---|
810 | |
---|
811 | return (a,g); |
---|
812 | } |
---|
813 | |
---|
814 | |
---|
815 | /*** |
---|
816 | * removes all zero columns in matrix(G), |
---|
817 | * and removes the corresponding columns in Q, if they exist. |
---|
818 | **/ |
---|
819 | static proc removeZeroColumns(module G, matrix Q) |
---|
820 | { |
---|
821 | ASSUME(1,ncols(G)>ncols(Q)); |
---|
822 | module Gprime; |
---|
823 | matrix Qprime[nrows(Q)][ncols(Q)]; |
---|
824 | int newSizeG = 0; |
---|
825 | int newSizeQ = 0; |
---|
826 | |
---|
827 | for (int i=1; i<=ncols(G); i++) |
---|
828 | { |
---|
829 | if (G[i]!=0) |
---|
830 | { |
---|
831 | newSizeG++; |
---|
832 | Gprime[newSizeG] = G[i]; |
---|
833 | if (i<=ncols(Q)) |
---|
834 | { |
---|
835 | newSizeQ++; |
---|
836 | Qprime[1..nrows(Q),newSizeQ] = Q[1..nrows(Q),i]; |
---|
837 | } |
---|
838 | } |
---|
839 | } |
---|
840 | matrix QQprime[nrows(Q)][newSizeQ] = Qprime[1..nrows(Q),1..newSizeQ]; |
---|
841 | return (Gprime,QQprime); |
---|
842 | } |
---|
843 | |
---|
844 | |
---|
845 | proc warkedPreimageStd(warkedModule wM) |
---|
846 | " |
---|
847 | USAGE: warkedPreimageStd(wM); M warkedModule |
---|
848 | RETURN: given wM consisting of: |
---|
849 | - wM.Gr a graalBearer containing all relevant global structures |
---|
850 | - wM.modQ0y generating set G of a module M over Q0y |
---|
851 | - wM.stdmodQ0y empty |
---|
852 | - wM.qQ0y empty |
---|
853 | - wM.modKy corresponding generating set H of M_in over Ky |
---|
854 | - wM.stdmodKy empty |
---|
855 | - wM.qKy empty |
---|
856 | - wM.w weights on M |
---|
857 | returns the same warkedModule, except following differences: |
---|
858 | - wM.stdmodQ0y contains a subset G such that for any standard basis L of the kernel |
---|
859 | G + L is a standard basis of modQ0y + kernel |
---|
860 | - wM.qQ0y contains a transformation matrix such that |
---|
861 | stdmodAy = QAy*modQ0y |
---|
862 | - wM.stdmodKy contains a standardbasis of modKy |
---|
863 | - wM.qKy contains a transformation matrix such that |
---|
864 | stdmodKy = QKy*modKy |
---|
865 | NOTE: the standard basis of modAy is computed by lifting a corresponding |
---|
866 | Groebner basis of modKy |
---|
867 | EXAMPLE: example warkedPreimageStd; shows an example |
---|
868 | " |
---|
869 | { |
---|
870 | ASSUME(1,checkCorrespondence(wM)); |
---|
871 | |
---|
872 | graalBearer Gr = wM.Gr; |
---|
873 | // intvec w = wM.w; |
---|
874 | |
---|
875 | def Ky = Gr.Ky; setring Ky; |
---|
876 | module H = wM.modKy; |
---|
877 | |
---|
878 | /* add generators of the kernel to H */ |
---|
879 | int l = ncols(H); |
---|
880 | int k = nrows(H); |
---|
881 | int i,j; |
---|
882 | ideal scriptIin = Gr.scriptIin; |
---|
883 | H = H+freemodule(k)*scriptIin; |
---|
884 | |
---|
885 | /* compute a standard basis of H |
---|
886 | * and a corresponding transformation matrix */ |
---|
887 | matrix Qdash; |
---|
888 | module Hdash = liftstd(H,Qdash); |
---|
889 | |
---|
890 | /* drop factors before elements of scriptIin |
---|
891 | * and single out all elements of Hdash |
---|
892 | * whose leading monomial does not lie in scriptIin */ |
---|
893 | matrix QQ[l][size(Hdash)]; |
---|
894 | int ncolsQQ = 0; |
---|
895 | module redLHdash = reduce(lead(Hdash),lead(scriptIin)); |
---|
896 | for (i=1; i<=size(Hdash); i++) |
---|
897 | { |
---|
898 | if (redLHdash[i] != 0) |
---|
899 | { |
---|
900 | ncolsQQ++; |
---|
901 | QQ[1..l,ncolsQQ] = Qdash[1..l,i]; |
---|
902 | } |
---|
903 | } |
---|
904 | matrix Q[l][ncolsQQ] = QQ[1..l,1..ncolsQQ]; |
---|
905 | wM.qKy = Q; |
---|
906 | wM.stdmodKy = Hdash; |
---|
907 | |
---|
908 | def Q0y = Gr.Q0y; setring Q0y; |
---|
909 | module G = wM.modQ0y; |
---|
910 | matrix Q = imap(Ky,Q); |
---|
911 | ideal scriptI = Gr.scriptI; |
---|
912 | module Gdash = reduce(matrix(G)*Q,scriptI); |
---|
913 | poly a; |
---|
914 | for (i=1; i<=size(Gdash); i++) |
---|
915 | { |
---|
916 | a,Gdash[i] = normalizeInY(Gdash[i],Gr); |
---|
917 | Q[1..l,i] = a*Q[1..l,i]; |
---|
918 | } |
---|
919 | ASSUME(1,isStandardBases(Gdash)); |
---|
920 | Gdash = Gdash + freemodule(k)*scriptI; |
---|
921 | |
---|
922 | Gdash = simplify(Gdash,32); |
---|
923 | Gdash,Q = removeZeroColumns(Gdash,Q); |
---|
924 | |
---|
925 | |
---|
926 | wM.qQ0y = Q; |
---|
927 | wM.stdmodQ0y = Gdash; |
---|
928 | |
---|
929 | return(wM); |
---|
930 | } |
---|
931 | example |
---|
932 | { "EXAMPLE:"; echo = 2; |
---|
933 | ring Q = 0,(x,y,z),dp; |
---|
934 | ideal H = y2-xz; |
---|
935 | qring A = std(H); |
---|
936 | ideal L = x3-yz,x2y-z2; |
---|
937 | graalBearer Gr = graalMixed(L); |
---|
938 | def Q0y = Gr.Q0y; setring Q0y; |
---|
939 | |
---|
940 | module M = (Y(1)*y+y^2-1)*gen(1)+(Y(2)*z+z^2-1)*gen(2), Y(1)*y*gen(1)+Y(2)*z*gen(2); |
---|
941 | /* This is M: */ |
---|
942 | print(matrix(M)); |
---|
943 | intvec w = 1,1,1; |
---|
944 | warkedModule wM; |
---|
945 | wM.Gr = Gr; |
---|
946 | wM.modQ0y = M; |
---|
947 | wM.w = w; |
---|
948 | |
---|
949 | def Ky = Gr.Ky; setring Ky; |
---|
950 | module Min = (y^2-1)*gen(1)+(z^2-1)*gen(2),Y(1)*y*gen(1)+Y(2)*z*gen(2); |
---|
951 | /* This is M_in: */ |
---|
952 | print(matrix(Min)); |
---|
953 | wM.modKy = Min; |
---|
954 | |
---|
955 | /* warkedPreimageStd yields the same standard basis as std: */ |
---|
956 | warkedModule wN = warkedPreimageStd(wM); wN; |
---|
957 | setring Q0y; |
---|
958 | module stdM = std(M); |
---|
959 | print(matrix(stdM)); |
---|
960 | } |
---|
961 | |
---|
962 | proc markedResolution_print(markedResolution mr) |
---|
963 | { |
---|
964 | graalBearer Gr = mr.Gr; |
---|
965 | |
---|
966 | "resolution over Al:"; |
---|
967 | def Al = Gr.Al; setring Al; |
---|
968 | resolution resAl = mr.resAl; |
---|
969 | resAl; |
---|
970 | for (int i=1; i<=ressize(resAl); i++) |
---|
971 | { |
---|
972 | "k="+string(i); |
---|
973 | print(module(resAl[i])); |
---|
974 | ""; |
---|
975 | } |
---|
976 | |
---|
977 | "resolution over Graal:"; |
---|
978 | def Graal = Gr.Graal; setring Graal; |
---|
979 | resolution resGraal = mr.resGraal; |
---|
980 | resGraal; |
---|
981 | for (i=1; i<=ressize(resGraal); i++) |
---|
982 | { |
---|
983 | "k="+string(i); |
---|
984 | print(module(resGraal[i])); |
---|
985 | ""; |
---|
986 | } |
---|
987 | } |
---|
988 | |
---|
989 | |
---|
990 | /*** |
---|
991 | * returns the size of a resolution. |
---|
992 | **/ |
---|
993 | static proc ressize(resolution res) |
---|
994 | { |
---|
995 | for (int i=1; i<=size(res); i++) |
---|
996 | { |
---|
997 | if (res[i]==0) |
---|
998 | { |
---|
999 | return (i-1); |
---|
1000 | } |
---|
1001 | } |
---|
1002 | return (size(res)); |
---|
1003 | } |
---|
1004 | |
---|
1005 | |
---|
1006 | /*** |
---|
1007 | * given rh consisting of: |
---|
1008 | * - rh.Gr a graalBearer containing all relevant global structures |
---|
1009 | * - rh.idealAl a standard basis of an ideal I in Al |
---|
1010 | * - rh.resAl a resolution with only a single entry, |
---|
1011 | * generators of I corresponding to the generators of inI |
---|
1012 | * - rh.resGraal a resolution of inI, the initial ideal inI of I over Graal |
---|
1013 | * - rh.weights an empty list of weights for the modules in resAl |
---|
1014 | * liftRes lifts the given resolution of inI to a resolution of I |
---|
1015 | **/ |
---|
1016 | static proc liftRes(markedResolution rh) |
---|
1017 | { |
---|
1018 | graalBearer Gr = rh.Gr; |
---|
1019 | |
---|
1020 | /* before anything initiate a list with the generators of I |
---|
1021 | for the resolution over Al |
---|
1022 | and read out the resolution over Graal */ |
---|
1023 | def Al = Gr.Al; setring Al; |
---|
1024 | ideal I = rh.idealAl; |
---|
1025 | list resAl = I; |
---|
1026 | |
---|
1027 | def Graal = Gr.Graal; setring Graal; |
---|
1028 | resolution resGraal = rh.resGraal; |
---|
1029 | int k = ressize(resGraal); |
---|
1030 | ideal inI = resGraal[1]; |
---|
1031 | |
---|
1032 | /* before lifting the first segment of the resolution, |
---|
1033 | find suitable preimages of the generators of I and inI */ |
---|
1034 | int i = 1; |
---|
1035 | def Ky = Gr.Ky; setring Ky; |
---|
1036 | ideal scriptIin = Gr.scriptIin; |
---|
1037 | ASSUME(1,reduce(std(scriptIin),scriptIin)==0); // check whether it is standard basis |
---|
1038 | attrib(scriptIin,"isSB",1); // and set corresponding flag to 1 |
---|
1039 | ideal H(i) = imap(Graal,inI); |
---|
1040 | ASSUME(1,lead(H(i))==lead(reduce(H(i),scriptIin))); // H(i) should already be in reduced form, |
---|
1041 | // since inI was a standard basis |
---|
1042 | |
---|
1043 | def Q0y = Gr.Q0y; setring Q0y; |
---|
1044 | ideal scriptI = Gr.scriptI; |
---|
1045 | ASSUME(1,reduce(std(scriptI),scriptI)==0); // check whether it is standard basis |
---|
1046 | attrib(scriptI,"isSB",1); // and set corresponding flag to 1 |
---|
1047 | ideal G(i) = imap(Al,I); |
---|
1048 | ASSUME(1,lead(G(i))==lead(reduce(G(i),scriptI))); // G(i) should already be in reduced form, |
---|
1049 | // since I was a standard basis |
---|
1050 | |
---|
1051 | /* lifting the first segment of the resolution, |
---|
1052 | * i.e. syzygies of the generators Theta of inI to |
---|
1053 | * syzygies of the generators Delta of I */ |
---|
1054 | |
---|
1055 | /* note that I already is already in standard bases form, |
---|
1056 | * which is why G(i)+scriptI is a standard bases */ |
---|
1057 | /* next, we need a standard basis of the preimage of I */ |
---|
1058 | setring Q0y; |
---|
1059 | ideal Gdash(i) = G(i) + scriptI; |
---|
1060 | ASSUME(2,isStandardBasis(Gdash(i))); |
---|
1061 | attrib(Gdash(i),"isSB",1); |
---|
1062 | matrix Q(i)[size(G(i))][size(Gdash(i))]; |
---|
1063 | for (int j=1; j<=size(G(i)); j++) |
---|
1064 | { Q(i)[j,j]=1; } |
---|
1065 | |
---|
1066 | for (i=2; i<=k; i++) |
---|
1067 | { |
---|
1068 | setring Graal; |
---|
1069 | module syzTheta = resGraal[i]; |
---|
1070 | |
---|
1071 | // pick homogeneous representatives of hs eta in syzTheta |
---|
1072 | setring Ky; |
---|
1073 | module H(i) = imap(Graal,syzTheta); |
---|
1074 | H(i) = reduce(H(i),scriptIin); |
---|
1075 | |
---|
1076 | // lift them to gs in Q0y, substitute elements of G for the unit vectors |
---|
1077 | // and reduce the result |
---|
1078 | setring Q0y; |
---|
1079 | module G(i) = imap(Ky,H(i)); |
---|
1080 | module R = matrix(G(i-1))*matrix(G(i)); |
---|
1081 | R = reduce(R,scriptI); |
---|
1082 | |
---|
1083 | // compute a standard representation of the remainder |
---|
1084 | // with respect to G' |
---|
1085 | list L = division(R,Gdash(i-1)); |
---|
1086 | matrix D = L[1]; |
---|
1087 | ASSUME(1,L[2]==0); |
---|
1088 | ASSUME(1,isDiagonalMatrixOfOnes(L[3])); |
---|
1089 | |
---|
1090 | // correct the gs by our result |
---|
1091 | matrix QD = Q(i-1)*D; |
---|
1092 | G(i) = module(matrix(G(i))-QD); |
---|
1093 | setring Al; |
---|
1094 | resAl[i] = imap(Q0y,G(i)); |
---|
1095 | |
---|
1096 | // extend it to standard basis GDash(i) |
---|
1097 | // and transformation matrix for next step |
---|
1098 | warkedModule wM; |
---|
1099 | wM.Gr = Gr; |
---|
1100 | |
---|
1101 | setring Ky; |
---|
1102 | wM.modKy = H(i); |
---|
1103 | |
---|
1104 | setring Q0y; |
---|
1105 | wM.modQ0y = G(i); |
---|
1106 | |
---|
1107 | wM = warkedPreimageStd(wM); |
---|
1108 | matrix Q(i) = wM.qQ0y; |
---|
1109 | module Gdash(i) = wM.modQ0y; |
---|
1110 | |
---|
1111 | // cleanup |
---|
1112 | setring Graal; |
---|
1113 | kill syzTheta; |
---|
1114 | setring Q0y; |
---|
1115 | kill R; |
---|
1116 | kill L; |
---|
1117 | kill D; |
---|
1118 | kill QD; |
---|
1119 | } |
---|
1120 | |
---|
1121 | setring Al; |
---|
1122 | rh.resAl = resolution(resAl); |
---|
1123 | return(rh); |
---|
1124 | } |
---|
1125 | |
---|
1126 | |
---|
1127 | /*** |
---|
1128 | * Given two ideals with the same generators modulo ordering |
---|
1129 | * returns an intvec that respresents a permutation of the generators |
---|
1130 | **/ |
---|
1131 | static proc getPermutation(ideal I1, ideal I2) |
---|
1132 | { |
---|
1133 | ASSUME(1,size(I1)==size(I2)); |
---|
1134 | int i,j; |
---|
1135 | intvec perm; |
---|
1136 | for (i=1; i<=size(I1); i++) |
---|
1137 | { |
---|
1138 | for (j=1; j<=size(I2); j++) |
---|
1139 | { |
---|
1140 | if (I1[i]==I2[j]) |
---|
1141 | { |
---|
1142 | perm[i] = j; |
---|
1143 | } |
---|
1144 | } |
---|
1145 | } |
---|
1146 | for (i=1; i<=size(perm); i++) |
---|
1147 | { |
---|
1148 | ASSUME(1,perm[i]>0); |
---|
1149 | } |
---|
1150 | return(perm); |
---|
1151 | } |
---|
1152 | |
---|
1153 | |
---|
1154 | /*** |
---|
1155 | * Given an intvec representing a permutation, |
---|
1156 | * permutes the generators of the ideal. |
---|
1157 | **/ |
---|
1158 | static proc permuteGenerators(ideal I, intvec perm) |
---|
1159 | { |
---|
1160 | ASSUME(1,size(I)==size(perm)); |
---|
1161 | ideal J; |
---|
1162 | for (int i=1; i<=size(perm); i++) |
---|
1163 | { |
---|
1164 | J[i]=I[perm[i]]; |
---|
1165 | } |
---|
1166 | return (J); |
---|
1167 | } |
---|
1168 | |
---|
1169 | |
---|
1170 | proc resolutionInLocalization(ideal I, def L) |
---|
1171 | " |
---|
1172 | USAGE: resolutionInLocalization(I,L); I ideal, L ideal or graalBearer |
---|
1173 | RETURN: the resolution of I*A_L, where |
---|
1174 | A_L is the localization of the current basering (possibly a quotient ring) |
---|
1175 | at a prime ideal L. |
---|
1176 | EXAMPLE: example resolutionInLocalization; shows an example |
---|
1177 | " |
---|
1178 | { |
---|
1179 | if (typeof(L)=="ideal") |
---|
1180 | { |
---|
1181 | graalBearer Gr = graalMixed(L); |
---|
1182 | return(resolutionInLocalization(I,Gr)); |
---|
1183 | } |
---|
1184 | if (typeof(L)=="graalBearer") |
---|
1185 | { |
---|
1186 | graalBearer Gr = L; |
---|
1187 | def origin = basering; |
---|
1188 | def Al = Gr.Al; setring Al; |
---|
1189 | ideal I = imap(origin,I); |
---|
1190 | I = std(I); |
---|
1191 | int s = Gr.s; |
---|
1192 | markedResolution mr; |
---|
1193 | mr.idealAl = I; |
---|
1194 | ideal inI = yinitial(I,s); |
---|
1195 | def Graal = Gr.Graal; |
---|
1196 | setring Graal; |
---|
1197 | ideal inI = Gr.ina(inI); |
---|
1198 | ASSUME(1,isStandardBasis(inI)); |
---|
1199 | attrib(inI,"isSB",1); |
---|
1200 | resolution resInI = res(inI,0); |
---|
1201 | resInI = minres(resInI); |
---|
1202 | mr.Gr = Gr; |
---|
1203 | mr.resGraal = resInI; |
---|
1204 | ideal inJ = resInI[1]; |
---|
1205 | intvec perm = getPermutation(inI,inJ); |
---|
1206 | setring Al; |
---|
1207 | mr.idealAl = permuteGenerators(I,perm); |
---|
1208 | mr = liftRes(mr); |
---|
1209 | return(mr); |
---|
1210 | } |
---|
1211 | ERROR("resolutionInLocalization: unexpected parameters"); |
---|
1212 | return(0); |
---|
1213 | } |
---|
1214 | example |
---|
1215 | { "EXAMPLE:"; echo = 2; |
---|
1216 | ring Q = 0,(x,y,z,w),dp; |
---|
1217 | ideal circle = (x-1)^2+y^2-3,z; |
---|
1218 | ideal twistedCubic = xz-y2,yw-z2,xw-yz,z; |
---|
1219 | ideal I = std(intersect(circle,twistedCubic)); |
---|
1220 | |
---|
1221 | // the resolution is more complicated due to the twisted cubic |
---|
1222 | res(I,0); |
---|
1223 | |
---|
1224 | // however if we localize outside of the twisted cubic, |
---|
1225 | // it should become very easy again. |
---|
1226 | ideal L = std(I+ideal(x-1)); |
---|
1227 | graalBearer Gr = graalMixed(L); Gr; |
---|
1228 | markedResolution mr = resolutionInLocalization(I,Gr); |
---|
1229 | mr; |
---|
1230 | } |
---|
1231 | |
---|
1232 | |
---|
1233 | /*** |
---|
1234 | * debug code |
---|
1235 | **/ |
---|
1236 | static proc isConstantUnit(poly p) |
---|
1237 | { |
---|
1238 | return(cleardenom(p)==1); |
---|
1239 | } |
---|
1240 | static proc isConstantMultiple(vector v, vector w) |
---|
1241 | { |
---|
1242 | module M = v,w; |
---|
1243 | M = simplify(M,8); |
---|
1244 | if (M[2]!=0) |
---|
1245 | { return(0); } |
---|
1246 | return(1); |
---|
1247 | } |
---|
1248 | static proc checkColumnsUpToUnits(matrix M, matrix N) |
---|
1249 | { |
---|
1250 | if ((ncols(M)!=ncols(N)) && (nrows(M)!=nrows(N))) |
---|
1251 | { return(0); } |
---|
1252 | if (nrows(M)==0) |
---|
1253 | { return(1); } |
---|
1254 | int i,j; |
---|
1255 | vector v,w; |
---|
1256 | poly p,q; |
---|
1257 | for (i=ncols(M); i>0; i--) |
---|
1258 | { |
---|
1259 | v = M[i]; |
---|
1260 | w = N[i]; |
---|
1261 | if (!isConstantMultiple(v,w)) |
---|
1262 | { return(0); } |
---|
1263 | } |
---|
1264 | return(1); |
---|
1265 | } |
---|
1266 | /*** |
---|
1267 | * returns 1, if wM.modAy and wM.modKy correspond to each other |
---|
1268 | * and wm.stdmodAy and wm.stdmodKy correspond to each other. |
---|
1269 | * returns 0 otherwise. |
---|
1270 | **/ |
---|
1271 | static proc checkCorrespondence(warkedModule wM) |
---|
1272 | { |
---|
1273 | return (1); |
---|
1274 | graalBearer Gr = wM.Gr; |
---|
1275 | intvec w = wM.w; |
---|
1276 | def Ky = Gr.Ky; |
---|
1277 | setring Ky; |
---|
1278 | map Q0yToKy = Gr.Q0yToKy; |
---|
1279 | def Q0y = Gr.Q0y; |
---|
1280 | setring Q0y; |
---|
1281 | |
---|
1282 | module G1 = wM.modQ0y; |
---|
1283 | if (G1 != 0) |
---|
1284 | { |
---|
1285 | G1 = vectorInitial(G1,w); |
---|
1286 | setring Ky; |
---|
1287 | module H10 = wM.modKy; |
---|
1288 | if (H10 != 0) |
---|
1289 | { |
---|
1290 | module H11 = Q0yToKy(G1); |
---|
1291 | if (matrix(H10)!=matrix(H11)) |
---|
1292 | { return(0); } |
---|
1293 | } |
---|
1294 | setring Q0y; |
---|
1295 | } |
---|
1296 | |
---|
1297 | module G2 = wM.stdmodQ0y; |
---|
1298 | if (G2 != 0) |
---|
1299 | { |
---|
1300 | G2 = vectorInitial(G2,w); |
---|
1301 | setring Ky; |
---|
1302 | module H20 = wM.stdmodKy; |
---|
1303 | if (H20 != 0) |
---|
1304 | { |
---|
1305 | module H21 = Q0yToKy(G2); |
---|
1306 | if (matrix(H20)!=matrix(H21)) |
---|
1307 | { return(0); } |
---|
1308 | } |
---|
1309 | } |
---|
1310 | |
---|
1311 | return(1); |
---|
1312 | } |
---|
1313 | /*** |
---|
1314 | * checks whether U is a diagonal matrix consisting of 1's |
---|
1315 | **/ |
---|
1316 | static proc isDiagonalMatrixOfOnes(matrix U) |
---|
1317 | { |
---|
1318 | if (nrows(U)!=ncols(U)) |
---|
1319 | { return(0); } |
---|
1320 | int j,j; |
---|
1321 | for (i=1; i<=nrows(U); i++) |
---|
1322 | { |
---|
1323 | for (j=1; j<=ncols(U); j++) |
---|
1324 | { |
---|
1325 | if (i==j && U[i,j]!=number(1)) |
---|
1326 | { return(0); } |
---|
1327 | if (i!=j && U[i,j]!=number(0)) |
---|
1328 | { return(0); } |
---|
1329 | } |
---|
1330 | } |
---|
1331 | return(1); |
---|
1332 | } |
---|
1333 | /*** |
---|
1334 | * returns 1 if I is a standard basis, returns 0 otherwise, |
---|
1335 | **/ |
---|
1336 | static proc isStandardBasis(ideal I) |
---|
1337 | { |
---|
1338 | ideal LI = lead(std(I)); |
---|
1339 | attrib(LI,"isSB",1); |
---|
1340 | ideal LII = lead(I); |
---|
1341 | attrib(LII,"isSB",1); |
---|
1342 | /* checks whether lead(I) generates the leading ideal */ |
---|
1343 | if (simplify(reduce(LI,LII),2)!=0) |
---|
1344 | { |
---|
1345 | ERROR("isStandardBasis: input ideal no standard basis!"); |
---|
1346 | return(0); |
---|
1347 | } |
---|
1348 | /* the following case should never happen mathematically, |
---|
1349 | * left the check for sake of completeness */ |
---|
1350 | if (simplify(reduce(LII,LI),2)!=0) |
---|
1351 | { |
---|
1352 | ERROR("isStandardBasis: input ideal no standard basis!"); |
---|
1353 | return(0); |
---|
1354 | } |
---|
1355 | return(1); |
---|
1356 | } |
---|