1 | //////////////////////////////////////////////////////////////// |
---|
2 | version="version hodge.lib 4.2.0.0 Feb_2021 "; // $Id$ |
---|
3 | category="Noncommutative"; |
---|
4 | info=" |
---|
5 | LIBRARY: hodge.lib Algorithms for Hodge ideals |
---|
6 | |
---|
7 | AUTHORS: Guillem Blanco, email: guillem.blanco@kuleuven.be |
---|
8 | |
---|
9 | OVERVIEW: |
---|
10 | A library for computing the Hodge ideals [MP19] of Q-divisors associated to any reduced hypersurface @math{f \in R}. |
---|
11 | @* The implemented algorithm [Bla21] is based on the characterization of the Hodge ideals in terms of the @math{V}-filtration of Malgrange and Kashiwara on @math{R_f f^s}, see [MP20]. |
---|
12 | @* As a consequence, this library provides also an algorithm to compute the multiplier ideals and the jumping numbers of any hypersurface, see [BS05]. |
---|
13 | |
---|
14 | REFERENCES: |
---|
15 | @*[Bla21] G. Blanco, An algorithm for Hodge ideals, to appear. |
---|
16 | @*[BS05] N. Budur, M. Saito, Multiplier ideals, V-filtration, and spectrum, J. Algebraic Geom. 14 (2005), no. 2, 269-282. 2, 4 |
---|
17 | @*[MP19] M. Mustata, M. Popa: Hodge ideals, Mem. Amer. Math. Soc. 262 (2019), no. 1268 |
---|
18 | @*[MP20] M. Mustata, M. Popa: Hodge ideals for Q-divisors, V-filtration, and minimal exponent, Forum Math. Sigma 8 (2020), no. e19, 41 pp. |
---|
19 | |
---|
20 | KEYWORDS: Hodge ideals; V-filtration; Multiplier ideals; Jumping numbers |
---|
21 | |
---|
22 | PROCEDURES: |
---|
23 | Vfiltration(f, p [, eng]); compute @math{R}-generators for the @math{V}-filtration on @math{R_f f^s} truncated up to degree @math{p} in @math{\partial_t}. |
---|
24 | hodgeIdeals(f, p [, eng]); compute the Hodge ideals of @math{f^\alpha} up to level @math{p}, for a reduced hypersurface @math{f \in R}. |
---|
25 | multIdeals(f, p [, eng]); compute the multiplier ideals of a hypersurface @math{f \in R}. |
---|
26 | nextHodgeIdeal(f, I, p); given the @math{p}-th Hodge ideal @math{I} of @math{f^\alpha} compute the @math{p+1}-th Hodge ideal assuming that the Hodge filtration of the underlying mixed Hodge module is generated at level less than or equal to @math{p}. |
---|
27 | |
---|
28 | SEE ALSO: dmodapp_lib |
---|
29 | "; |
---|
30 | |
---|
31 | LIB "dmod.lib"; // SannfsBM, vec2poly, bFactor |
---|
32 | |
---|
33 | // Test whether the polynomial f is reduced or not. |
---|
34 | static proc isReduced(poly f) { |
---|
35 | // Compute square-free part. |
---|
36 | ideal j = jacob(f); poly g = f; |
---|
37 | for (int i = 1; i <= size(j); i++) { g = gcd(g, j[i]); } |
---|
38 | return(g == 1); |
---|
39 | } |
---|
40 | |
---|
41 | // The Q-polynomial as defined by Mustata & Popa. |
---|
42 | static proc Qpoly(int k, number a) { |
---|
43 | poly Q = 1; |
---|
44 | for (int i = 1; i <= k; i++) { Q = Q*(a+i-1); } |
---|
45 | return(Q); |
---|
46 | } |
---|
47 | |
---|
48 | // The procedure to compute the truncated V-filtration. |
---|
49 | proc Vfiltration(poly f, int p, list #) |
---|
50 | "USAGE: Vfiltration(f, p [, eng]); f a poly, p a non-negative integer, eng an optional integer. |
---|
51 | RETURN: ring |
---|
52 | PURPOSE: compute @math{R}-generators for the @math{V}-filtration on @math{R_f f^s} truncated up to degree @math{p} in @math{\partial_t}. |
---|
53 | NOTE: activate the output ring with the @code{setring} command. |
---|
54 | @*In the output ring, the list @code{Vfilt} contains the @math{V}-filtration. |
---|
55 | @*The value of @code{eng} controls the algorithm used for Groebner basis computations. |
---|
56 | @*See the @code{engine} procedure from @ref{dmodapp_lib} for the available algorithms. |
---|
57 | DISPLAY: If @code{printlevel}=1, progress debug messages will be printed. |
---|
58 | EXAMPLE: example Vfiltration; shows an example |
---|
59 | " |
---|
60 | { |
---|
61 | // The level 'p' must be a non-negative integer. |
---|
62 | if (p < 0) { ERROR("Level p must be non-negative."); } |
---|
63 | // The base ring must be non-commutative. |
---|
64 | if (size(ring_list(basering)) > 4) { ERROR("Base ring must be commutative."); } |
---|
65 | |
---|
66 | // Default engine & option. |
---|
67 | int slimgb_ = 0; int eng = slimgb_; |
---|
68 | // The first optional argument must be an integer. |
---|
69 | if (size(#) >= 1) { |
---|
70 | if (typeof(#[1]) == "int") { eng = int(#[1]); } |
---|
71 | else { ERROR("First argument must be an integer."); } |
---|
72 | // The check that the engine number is valid will be done by the engine. |
---|
73 | } |
---|
74 | |
---|
75 | // Save basering & set basic variables. |
---|
76 | def @R = basering; int N = nvars(@R); |
---|
77 | int ppl = printlevel - voice + 2; int i, j; string str; |
---|
78 | list Names = ringlist(@R)[2]; list Dnames; |
---|
79 | for (i = 1; i <= N; i++) { Dnames = Dnames + list("D" + Names[i]); } |
---|
80 | |
---|
81 | // No variable can be named 't' or 'Dt'. |
---|
82 | for (i = 1; i <= size(Names); i++) { |
---|
83 | if (Names[i] == "t" || Names[i] == "Dt" || Names[i] == "a") { |
---|
84 | ERROR("Variable names should not include 't', 'Dt' or 'a'"); |
---|
85 | } |
---|
86 | } |
---|
87 | |
---|
88 | // Compute s-parametric annhilator of f via BM algorithm & move to D[s]. |
---|
89 | dbprint(ppl, "// -1-1- Computing the annhilator of f^s..."); |
---|
90 | // SannfsBM returns a ring with elimination ordering for s. |
---|
91 | def @Ds = SannfsBM(f, slimgb_); setring(@Ds); |
---|
92 | dbprint(ppl, "// -1-2- Annhilator of f^s computed in @Ds"); |
---|
93 | |
---|
94 | list RL = ringlist(basering); list RL1; |
---|
95 | RL1[1] = RL[1]; //char. |
---|
96 | RL1[2] = list("s") + Dnames + Names; |
---|
97 | //RL1[3] = list(list("dp", 1:1), list("dp", 1:N), list("dp", 1:N), list("C", 0)); |
---|
98 | RL1[3] = list(list("c", 0), list("dp", 1:1), list("dp", 1:N), list("dp", 1:N)); |
---|
99 | RL1[4] = RL[4]; //min. poly. |
---|
100 | // Make new ring non-commutative. |
---|
101 | ring @Ds1 = ring(RL1); matrix @Dmat[2*N+1][2*N+1]; |
---|
102 | for (i = 1; i <= N; i++) { @Dmat[i+1, N+1+i] = -1; } |
---|
103 | def @Ds2 = nc_algebra(1, @Dmat); setring @Ds2; kill @Ds1; |
---|
104 | |
---|
105 | // Move annihilator & f to the new ring. |
---|
106 | ideal Annfs = imap(@Ds, LD); poly f = imap(@R, f); |
---|
107 | |
---|
108 | // Compute the B-S polynomial of f. |
---|
109 | dbprint(ppl, "// -2-1- Computing Groebner basis of Ann f^s + <f>..."); |
---|
110 | // The partial derivatives trick might make everything run a bit faster. |
---|
111 | ideal I = engine(Annfs+f+jacob(f), eng); |
---|
112 | dbprint(ppl, "// -2-2- Groebner basis of Ann f^s + <f> computed"); |
---|
113 | dbprint(ppl, "// -2-3- Intersecting Ann f^s + <f> with QQ[s]..."); |
---|
114 | // Add the missing s = -1 root. |
---|
115 | poly bfct = vec2poly(pIntersect(s, I))*(var(1)+1); |
---|
116 | list BS = bFactor(bfct); |
---|
117 | dbprint(ppl, "// -2-4- Intersection of Ann f^s + <f> with QQ[s] finished"); |
---|
118 | |
---|
119 | // Shifts feigen = delete(eigen, i); mul = delete(mul, i);or the annihilator of f^s. |
---|
120 | int m = -p; int k = 1; |
---|
121 | ideal J = subst(Annfs, s, s+m)+f^(k-m); |
---|
122 | |
---|
123 | // Shift roots of the BS to (0, 1], this avoids having to compute the BS of J. |
---|
124 | list eigen; list mul; |
---|
125 | for (i = 1; i <= size(BS[1]); i++) { |
---|
126 | for (j = 0; j <= p; j++) { |
---|
127 | if (BS[1][i]+j < 0) { |
---|
128 | eigen = eigen+list(number(-BS[1][i]-j)); |
---|
129 | mul = mul+list(BS[2][i]); |
---|
130 | } |
---|
131 | } // Sort shifted eigen. |
---|
132 | } list S = sort(eigen); eigen = S[1]; mul = mul[S[2]]; |
---|
133 | |
---|
134 | // Remove duplicates & keep max. multiplicity. |
---|
135 | for (i = 1; i <= size(eigen) - 1; i++) { |
---|
136 | j = 1; while (eigen[i] == eigen[i+j]) { mul[i] = max(mul[i], mul[i+j]); j++; } |
---|
137 | while (j != 1) { eigen = delete(eigen, i+j-1); mul = delete(mul, i+j-1); j--; } |
---|
138 | } |
---|
139 | |
---|
140 | // Compute the kernels of the eigenvalues in 'eigen' in J. |
---|
141 | str = sprintf("// -3-1- Computing the kernels of the eigenvalues of Dt*t... (p = %p)", |
---|
142 | p); dbprint(ppl, str); |
---|
143 | list Ker; ideal K; |
---|
144 | for (i = 1; i <= size(eigen); i++) { |
---|
145 | str = sprintf("// -3-1-%p- Kernel for eigenvalue %p, multiplicity %p... (%p/%p)", |
---|
146 | i, eigen[i], mul[i], i, size(eigen)); dbprint(ppl, str); |
---|
147 | // *NO* need to add f^(k-m) as Ker[i] contains J = Annf^(s+m) + f^(k-m). |
---|
148 | Ker[i] = ideal(modulo(s + eigen[i], J)); |
---|
149 | // If there are multiplicities, iterate the generalized eigenspaces. |
---|
150 | for (j = 1; j < mul[i]; j++) { |
---|
151 | // Reduce the number of generators before calling modulo. |
---|
152 | K = engine(Ker[i], eng); |
---|
153 | Ker[i] = ideal(modulo(s + eigen[i], K)); |
---|
154 | } |
---|
155 | } |
---|
156 | |
---|
157 | // Compress the kernels of the eigenvalues greater than 1. |
---|
158 | for (i = size(eigen)-1; i > 0 && eigen[i] > 1; i--) { |
---|
159 | Ker[i] = Ker[i] + Ker[i+1]; Ker = delete(Ker, i+1); |
---|
160 | eigen = delete(eigen, i+1); mul = delete(mul, i+1); |
---|
161 | } |
---|
162 | // Heuristically, it is better to compute a Groebner basis here before |
---|
163 | // doing the elimination of the variables. |
---|
164 | dbprint(ppl, "// -3-3- Computing Groebner basis of kernels..."); |
---|
165 | for (i = 1; i <= size(Ker); i++) { Ker[i] = engine(Ker[i], eng); } |
---|
166 | |
---|
167 | // Create new ring with elimination order for _Dx. |
---|
168 | list RL = ringlist(basering); list RL1; |
---|
169 | RL1[1] = RL[1]; //char. |
---|
170 | RL1[2] = Dnames + list("s") + Names; |
---|
171 | RL1[3] = list(list("dp", 1:N), list("dp", 1:(N+1)), list("C", 0)); //orders. |
---|
172 | RL1[4] = RL[4]; //min. poly. |
---|
173 | // Make new ring non-commutative. |
---|
174 | ring @Ds3 = ring(RL1); |
---|
175 | matrix @Dmat[2*N+1][2*N+1]; |
---|
176 | for (i = 1; i <= N; i++) { @Dmat[i, N+i+1] = -1; } |
---|
177 | def @Ds4 = nc_algebra(1, @Dmat); setring @Ds4; kill @Ds3; |
---|
178 | dbprint(ppl, "// -4-1- The elimination ring @Ds4(_Dx,s,_x) is ready..."); |
---|
179 | |
---|
180 | // Map things to the new ring and eliminate |
---|
181 | dbprint(ppl, "// -4-2- Moving kernels to the new elimination ring..."); |
---|
182 | list Ker = imap(@Ds2, Ker); poly f = imap(@Ds2, f); list eigen = imap(@Ds2, eigen); |
---|
183 | |
---|
184 | dbprint(ppl, "// -4-3- Starting the elimination of _Dx in the V-filtration..."); |
---|
185 | int n = size(Ker); list S; S[n] = engine(Ker[n], eng); list H; |
---|
186 | for (i = n - 1; i > 0; i--) { |
---|
187 | str = sprintf("// -4-3-%p- Elimination for eigenvalue %p... (%p/%p)", n-i, |
---|
188 | eigen[i], n-i, n); dbprint(ppl, str); |
---|
189 | S[i] = engine(Ker[i] + S[i+1], eng); |
---|
190 | H[i] = nselect(S[i], 1..N); |
---|
191 | } |
---|
192 | dbprint(ppl, "// -4-4- The variables _Dx are eliminated"); |
---|
193 | |
---|
194 | // Create new commutative ring with block order (s)(x_). |
---|
195 | list RL = ringlist(basering); list RL1; |
---|
196 | RL1[1] = RL[1]; //char. |
---|
197 | RL1[2] = list("s") + Names; //vars. |
---|
198 | RL1[3] = list(list("dp", 1), list("dp", 1:N), list("C", 0)); //orders. |
---|
199 | RL1[4] = RL[4]; //min. poly. |
---|
200 | // Make new ring non-commutative. |
---|
201 | ring @R1 = ring(RL1); setring(@R1); |
---|
202 | dbprint(ppl, "// -4-5- The commutative ring s,_x is ready"); |
---|
203 | |
---|
204 | // Compute Groebner bases for H in the new ring. |
---|
205 | list H = imap(@Ds4, H); |
---|
206 | dbprint(ppl, "// -4-6- Computing Groebner basis of the H ideals in the new ring..."); |
---|
207 | for (i = 1; i <= size(H); i++) { H[i] = slimgb(H[i]); } |
---|
208 | dbprint(ppl, "// -4-7- Groebner basis of the H ideals computed"); |
---|
209 | |
---|
210 | // Create new ring (Dt,t,x_) where s -> -Dt*t. |
---|
211 | list RL = ringlist(basering); list RL1; |
---|
212 | RL1[1] = RL[1]; //char. |
---|
213 | RL1[2] = list("Dt", "t") + Names; //vars. |
---|
214 | RL1[3] = list(list("dp", 1:2), list("dp", 1:N), list("C", 0)); //orders. |
---|
215 | RL1[4] = RL[4]; //min. poly. |
---|
216 | // Make new ring non-commutative. |
---|
217 | ring @Ds5 = ring(RL1); |
---|
218 | matrix @Dmat[N+2][N+2]; @Dmat[1, 2] = -1; |
---|
219 | def @Ds6 = nc_algebra(1, @Dmat); setring @Ds6; kill @Ds5; |
---|
220 | dbprint(ppl, "// -5-1- The ring @Ds6(t,Dt,_x) is ready"); |
---|
221 | |
---|
222 | // Move things to the new (Dt,t,x_) ring. |
---|
223 | def Max = maxideal(1); ideal J = -Dt*t; |
---|
224 | for (i = 3; i <= N + 2; i++) { J = J + Max[i]; } |
---|
225 | dbprint(ppl, "// -5-2- Moving H ideals to the new (Dt,t,_x) ring..."); |
---|
226 | map Map = @R1, J; list H = Map(H); |
---|
227 | poly f = imap(@Ds4, f); list eigen = imap(@Ds4, eigen); |
---|
228 | |
---|
229 | // Subtitute t = f and *exactly* divide H ideals by f^p. |
---|
230 | dbprint(ppl, "// -5-3- Substituting t = f and dividing by f^p..."); |
---|
231 | list Vfilt; |
---|
232 | for (i = 1; i <= size(H); i++) { |
---|
233 | // Append the corresponding eigenvalue and its multiplicity to the output. |
---|
234 | Vfilt[i] = list(list(), poly(eigen[i]), mul[i]); |
---|
235 | for (j = 1; j <= size(H[i]); j++) { |
---|
236 | if (leadexp(H[i][j])[1] <= p) { |
---|
237 | Vfilt[i][1] = Vfilt[i][1] + list(subst(H[i][j], var(2), f)/f^p); |
---|
238 | } |
---|
239 | } |
---|
240 | } export(Vfilt); return(@Ds6); |
---|
241 | } |
---|
242 | example |
---|
243 | { |
---|
244 | "EXAMPLE:"; echo = 2; |
---|
245 | ring R = 0,(x,y),dp; |
---|
246 | poly f = y^2-x^3; |
---|
247 | def D = Vfiltration(f, 1); |
---|
248 | setring D; Vfilt; |
---|
249 | } |
---|
250 | |
---|
251 | proc hodgeIdeals(poly f, int p, list #) |
---|
252 | "USAGE: hodgeIdeals(f, p [, eng]); f a reduced poly, p a non-negative integer, eng an optional integer. |
---|
253 | RETURN: ring |
---|
254 | PURPOSE: compute the Hodge ideals of @math{f^\alpha} up to level @math{p}, for a reduced hypersurface @math{f}. |
---|
255 | NOTE: activate the output ring with the @code{setring} command. |
---|
256 | @*In the output ring, the list of ideals @code{hodge} contains the Hodge ideals of @math{f}. |
---|
257 | @*The value of @code{eng} controls the algorithm used for Groebner basis computations. |
---|
258 | @*See the @code{engine} procedure from @ref{dmodapp_lib} for the available algorithms. |
---|
259 | DISPLAY: If @code{printlevel}=1, progress debug messages will be printed. |
---|
260 | EXAMPLE: example hodgeIdeals; shows an example |
---|
261 | " |
---|
262 | { |
---|
263 | // Equation 'f' must be reduced. |
---|
264 | if (!isReduced(f)) { ERROR("Polynomial f must be reduced."); } |
---|
265 | |
---|
266 | def @R = basering; int N = nvars(@R); |
---|
267 | list Trans = ringlist(@R)[1]; |
---|
268 | list Names = ringlist(@R)[2]; |
---|
269 | // Check for name collisions within Transcendental parameters. |
---|
270 | int i, j; |
---|
271 | if (size(Trans) != 1) { |
---|
272 | for (i = 1; i <= size(Trans[2]); i++) { |
---|
273 | if (Trans[2][i] == "t" || Trans[2][i] == "Dt" || Trans[2][i] == "a") { |
---|
274 | ERROR("Transcendental parameters should not include 't', 'Dt' or 'a'"); |
---|
275 | } |
---|
276 | } |
---|
277 | } |
---|
278 | |
---|
279 | int ppl = printlevel - voice + 2; |
---|
280 | printlevel = printlevel + 1; |
---|
281 | // Start by computing the Vfiltration of f truncated at level p. |
---|
282 | def @Ddt = Vfiltration(f, p, #); setring(@Ddt); |
---|
283 | printlevel = printlevel - 1; |
---|
284 | |
---|
285 | // Commutative (x_) ring with trascendental parameter 'a'. |
---|
286 | list RL = ringlist(basering); list RL1; |
---|
287 | if (size(RL[1]) == 0) { // no transcendental parameters in basering. |
---|
288 | RL1[1] = list(RL[1], list("a"), list(list("lp", 1)), ideal(0)); |
---|
289 | } else { // trascendental parameters already in basering. |
---|
290 | RL1[1] = RL[1]; RL1[1][2] = RL1[1][2] + list("a"); |
---|
291 | RL1[1][3][1][2] = RL1[1][3][1][2],1; |
---|
292 | } |
---|
293 | RL1[2] = list("Dt") + Names; //vars. |
---|
294 | RL1[3] = list(list("dp", 1), list("dp", 1:N), list("C", 0)); //orders. |
---|
295 | RL1[4] = RL[4]; //min. poly. |
---|
296 | // Make new ring non-commutative. |
---|
297 | ring @R2 = ring(RL1); setring(@R2); |
---|
298 | dbprint(ppl, "// -6-1- The commutative ring (a),_x is ready"); |
---|
299 | list Vfilt = imap(@Ddt, Vfilt); poly f = imap(@R, f); |
---|
300 | |
---|
301 | option(redSB); |
---|
302 | // Finally step, compute Hodge ideals using Theorem A' of Mustata & Popa. |
---|
303 | dbprint(ppl, "// -6-2- Computing Hodge ideals..."); |
---|
304 | list hodge; ideal Iq; poly g, mon; int q, l, dg; |
---|
305 | // For each eigenvalue... |
---|
306 | for (i = 1; i <= size(Vfilt); i++) { |
---|
307 | hodge[i] = list(list(), Vfilt[i][2], Vfilt[i][3]); |
---|
308 | // For each level q = 0,1,..,p we have a the q-th Hodge ideal 'Iq'. |
---|
309 | for (q = 0; q <= p; q++) { Iq = 0; |
---|
310 | // For each generator of H[i], compute a generator g of the Hodge ideal. |
---|
311 | for (j = 1; j <= size(Vfilt[i][1]); j++) { g = 0; |
---|
312 | // Select only the generators of H[i] with degree <= q in Dt. |
---|
313 | if (leadexp(Vfilt[i][1][j])[1] <= q) { |
---|
314 | // For each monomial term of the j-th generator of H[i]... |
---|
315 | for (l = 1; l <= size(Vfilt[i][1][j]); l++) { |
---|
316 | mon = Vfilt[i][1][j][l]; dg = leadexp(mon)[1]; |
---|
317 | // Apply Theorem A' of Mustata & Popa. |
---|
318 | g = g + Qpoly(dg, a)*f^(q-dg)*(mon/Dt^dg); |
---|
319 | } // Add a new element of the q-th Hodge ideal. |
---|
320 | } Iq = Iq + g; |
---|
321 | // Save a reduced GB of the q-th Hodge ideal of the i-th eigenvalue. |
---|
322 | } hodge[i][1] = hodge[i][1] + list(slimgb(Iq)); |
---|
323 | } |
---|
324 | } option(noredSB); |
---|
325 | |
---|
326 | export(hodge); return(@R2); |
---|
327 | } |
---|
328 | example |
---|
329 | { |
---|
330 | "EXAMPLE:"; echo = 2; |
---|
331 | ring R = 0,(x,y),dp; |
---|
332 | poly f = y^2-x^3; |
---|
333 | def Ra = hodgeIdeals(f, 2); |
---|
334 | setring Ra; hodge; |
---|
335 | } |
---|
336 | |
---|
337 | proc multIdeals(poly f, list #) |
---|
338 | "USAGE: multIdeals(f, [, eng]); f a reduced poly, eng an optional integer. |
---|
339 | RETURN: list |
---|
340 | PURPOSE: compute the multiplier ideals of a hypersurface @math{f \in R}. |
---|
341 | NOTE: The value of @code{eng} controls the algorithm used for Groebner basis computations. |
---|
342 | @* See the @code{engine} procedure from @ref{dmodapp_lib} for the available algorithms. |
---|
343 | DISPLAY: If @code{printlevel}=1, progress debug messages will be printed. |
---|
344 | EXAMPLE: example multIdeals; shows an example |
---|
345 | " |
---|
346 | { |
---|
347 | // Compute the Vfiltration of f truncated at level 0. |
---|
348 | printlevel = printlevel + 1; |
---|
349 | def @Ddt = Vfiltration(f, 0, #); |
---|
350 | printlevel = printlevel - 1; |
---|
351 | |
---|
352 | // Compute Hodge ideals using Theorem 0.1 of Budur & Saito. |
---|
353 | list Vfilt = imap(@Ddt, Vfilt); |
---|
354 | list multIdeals; int i, j; |
---|
355 | option(redSB); |
---|
356 | for (i = 1; i <= size(Vfilt); i++) { |
---|
357 | multIdeals[i] = list(ideal(), Vfilt[i][2], Vfilt[i][3]); |
---|
358 | for (j = 1; j <= size(Vfilt[i][1]); j++) { |
---|
359 | multIdeals[i][1] = multIdeals[i][1] + Vfilt[i][1][j]; |
---|
360 | } // Cosmetic Groebner basis. |
---|
361 | multIdeals[i][1] = slimgb(ideal(multIdeals[i][1])); |
---|
362 | } option(noredSB); |
---|
363 | |
---|
364 | return(multIdeals); |
---|
365 | } |
---|
366 | example |
---|
367 | { |
---|
368 | "EXAMPLE:"; echo = 2; |
---|
369 | ring R = 0,(x,y),dp; |
---|
370 | poly f = y^2-x^3; |
---|
371 | multIdeals(f); |
---|
372 | } |
---|
373 | |
---|
374 | // If I is the p-th Hodge ideal and the Hodge filtration is generated at |
---|
375 | // level p, return the (p+1)-th Hodge ideal. |
---|
376 | proc nextHodgeIdeal(poly f, ideal I, int p) |
---|
377 | "USAGE: nextHodgeIdeal(f, I, p); f a poly, I an ideal, p a non-negative integer |
---|
378 | RETURN: ideal |
---|
379 | PURPOSE: given the @math{p}-th Hodge ideal @math{I} of @math{f^\alpha} compute the @math{p+1}-th Hodge ideal assuming that |
---|
380 | @*the Hodge filtration of the underlying mixed Hodge module is generated at level less than or equal to @math{p}. |
---|
381 | EXAMPLE: example nextHodgeIdeal; shows an example |
---|
382 | " |
---|
383 | { |
---|
384 | int N = nvars(basering); ideal J = f*I; int i, j; |
---|
385 | for (i = 1; i <= size(I); i++) { |
---|
386 | for (j = 1; j <= N; j++) { |
---|
387 | J = J + (f*diff(I[i], var(j)) - (a + p)*I[i]*diff(f, var(j))); |
---|
388 | } |
---|
389 | } return(slimgb(J)); |
---|
390 | } |
---|
391 | example |
---|
392 | { |
---|
393 | "EXAMPLE:"; echo = 2; |
---|
394 | ring R = 0,(x,y),dp; |
---|
395 | poly f = y^2-x^3; |
---|
396 | def Ra = hodgeIdeals(f, 2); |
---|
397 | setring(Ra); |
---|
398 | int p = 1; |
---|
399 | nextHodgeIdeal(y^2-x^3, hodge[3][1][p+1], p); |
---|
400 | } |
---|