1 | /////////////////////////////////////////////////////////////////////////////// |
---|
2 | version="Id: rinvar.lib,v 1.0 2000/12/10 17:32:15 Singular Exp $"; |
---|
3 | info=" |
---|
4 | LIBRARY: rinvar.lib PROCEDURES FOR INVARIANT RINGS OF REDUCTIVE GROUPS |
---|
5 | |
---|
6 | AUTHOR: Thomas Bayer, email: tbayer@in.tum.de |
---|
7 | |
---|
8 | PROCEDURES: |
---|
9 | HilbertSeries(I, w) Hilbert series of the ideal I w.r.t. weight w |
---|
10 | HilbertWeights(I, w) weighted degrees of the generators of I |
---|
11 | ImageVariety(I, F) ideal of the image variety F(variety(I)) |
---|
12 | ImageGroup(G, F) ideal of G w.r.t. the induced representation |
---|
13 | InvariantRing(G, Gaction) generators of the invariant ring of G |
---|
14 | InvariantQ(f, G, Gaction) decide if f is invariant w.r.t. G |
---|
15 | LinearizeAction(G, Gaction) linearization of the action 'Gaction' of G |
---|
16 | LinearActionQ(action,s,t) decide if action is linear in var(s..nvars) |
---|
17 | LinearCombinationQ(base, f) decide if f is in the linear hull of 'base' |
---|
18 | MinimalDecomposition(f,s,t) minimal decomposition of f (like coef) |
---|
19 | NullCone(G, act) ideal of the nullcone of the action 'act' of G |
---|
20 | ReynoldsImage(RO,f) image of f under the Reynolds operator 'RO' |
---|
21 | ReynoldsOperator(G, Gaction) Reynolds operator of the group G |
---|
22 | SimplifyIdeal(I[,m,s]) simplify the ideal I (try to reduce variables) |
---|
23 | TransferIdeal(R,name,nA) transfer the ideal 'name' from R to basering |
---|
24 | "; |
---|
25 | |
---|
26 | // NOTE: This library has been written in the frame of the diploma thesis |
---|
27 | // 'Computing moduli spaces of semiquasihomogeneous singularites and an |
---|
28 | // implementation in Singular', Arbeitsgruppe Algebraische Geometrie, |
---|
29 | // Fachbereich Mathematik, University Kaiserslautern, |
---|
30 | // Advisor: Prof. Gert-Martin Greuel |
---|
31 | |
---|
32 | |
---|
33 | LIB "presolve.lib"; |
---|
34 | LIB "elim.lib"; |
---|
35 | LIB "zeroset.lib"; |
---|
36 | |
---|
37 | /////////////////////////////////////////////////////////////////////////////// |
---|
38 | |
---|
39 | proc EquationsOfEmbedding(ideal embedding, int nrs) |
---|
40 | "USAGE: EquationsOfEmbedding(embedding, s); ideal embedding; int s; |
---|
41 | PURPOSE: compute the ideal of the variety parameterized by 'embedding' by |
---|
42 | implicitation and change the variables to the old ones. |
---|
43 | RETURN: ideal |
---|
44 | ASSUME: nvars(basering) = n, size(embedding) = r and s = n - r. |
---|
45 | The polynomials of embedding contain only var(s + 1 .. n). |
---|
46 | NOTE: the result is the Zariski closure of the parameterized variety |
---|
47 | EXAMPLE: example EquationsOfEmbedding; shows an example |
---|
48 | " |
---|
49 | { |
---|
50 | ideal tvars; |
---|
51 | |
---|
52 | for(int i = nrs + 1; i <= nvars(basering); i++) { tvars[i - nrs] = var(i); } |
---|
53 | |
---|
54 | def RE1 = ImageVariety(ideal(0), embedding); // implicitation of the parameterization |
---|
55 | // map F = RE1, tvars; |
---|
56 | map F = RE1, maxideal(1); |
---|
57 | return(F(imageid)); |
---|
58 | } |
---|
59 | example |
---|
60 | {"EXAMPLE:"; echo = 2; |
---|
61 | ring R = 0,(s(1..5), t(1..4)),dp; |
---|
62 | ideal emb = t(1), t(2), t(3), t(3)^2; |
---|
63 | ideal I = EquationsOfEmbedding(emb, 5); |
---|
64 | I; |
---|
65 | } |
---|
66 | |
---|
67 | /////////////////////////////////////////////////////////////////////////////// |
---|
68 | |
---|
69 | proc ImageGroup(ideal Grp, ideal Gaction) |
---|
70 | "USAGE: ImageGroup(G, action); ideal G, action; |
---|
71 | PURPOSE: compute the ideal of the image of G in GL(m,K) induced by the linear |
---|
72 | action 'action', where G is an algebraic group and 'action' defines |
---|
73 | an action of G on K^m (size(action) = m). |
---|
74 | RETURN: ring, a polynomial ring over the same ground field as the basering, |
---|
75 | containing the ideals 'groupid' and 'actionid'. |
---|
76 | - 'groupid' is the ideal of the image of G (order <= order of G) |
---|
77 | - 'actionid' defines the linear action of 'groupid' on K^m. |
---|
78 | NOTE: 'action' and 'actionid' have the same orbits |
---|
79 | all variables which give only rise to 0's in the m x m matrices of G |
---|
80 | have been omitted. |
---|
81 | ASSUME: basering K[s(1..r),t(1..m)] has r + m variables, G is the ideal of an |
---|
82 | algebraic group and F is an action of G on K^m. G contains only the |
---|
83 | variables s(1)...s(r). The action 'action' is given by polynomials |
---|
84 | f_1,...,f_m in basering, s.t. on the ring level we have |
---|
85 | K[t_1,...,t_m] --> K[s_1,...,s_r,t_1,...,t_m]/G |
---|
86 | t_i --> f_i(s_1,...,s_r,t_1,...,t_m) |
---|
87 | |
---|
88 | EXAMPLE: example ImageGroup; shows an example |
---|
89 | " |
---|
90 | { |
---|
91 | int i, j, k, newVars, nrt, imageSize, dbPrt; |
---|
92 | ideal matrixEntries; |
---|
93 | matrix coMx; |
---|
94 | poly tVars, mPoly; |
---|
95 | string ringSTR1, ringSTR2, order; |
---|
96 | |
---|
97 | dbPrt = printlevel-voice+2; |
---|
98 | dbprint(dbPrt, "Image Group of " + string(Grp) + ", action = " + string(Gaction)); |
---|
99 | def RIGB = basering; |
---|
100 | mPoly = minpoly; |
---|
101 | tVars = 1; |
---|
102 | k = 0; |
---|
103 | |
---|
104 | // compute the representation of G induced by Gaction, i.e., a matrix |
---|
105 | // of size(Gaction) x size(Gaction) and polynomials in s(1),...,s(r) as entries |
---|
106 | // the matrix is represented as the list 'matrixEntries' where |
---|
107 | // the entries which are always 0 are omittet. |
---|
108 | |
---|
109 | for(i = 1; i <= ncols(Gaction); i++) { |
---|
110 | tVars = tVars * var(i + nvars(basering) - ncols(Gaction)); |
---|
111 | } |
---|
112 | for(i = 1; i <= ncols(Gaction); i++){ |
---|
113 | coMx = coef(Gaction[i], tVars); |
---|
114 | for(j = 1; j <= ncols(coMx); j++){ |
---|
115 | k++; |
---|
116 | matrixEntries[k] = coMx[2, j]; |
---|
117 | } |
---|
118 | } |
---|
119 | newVars = size(matrixEntries); |
---|
120 | nrt = ncols(Gaction); |
---|
121 | |
---|
122 | // this matrix defines an embedding of G into GL(m, K). |
---|
123 | // in the next step the ideal of this image is computed |
---|
124 | // note that we have omitted all variables which give give rise |
---|
125 | // only to 0's. Note that z(1..newVars) are slack variables |
---|
126 | |
---|
127 | order = "(dp(" + string(nvars(basering)) + "), dp);"; |
---|
128 | ringSTR1 = "ring RIGR = (" + charstr(basering) + "), (" + varstr(basering) + ", z(1.." + string(newVars) + "))," + order; |
---|
129 | execute(ringSTR1); |
---|
130 | minpoly = number(imap(RIGB, mPoly)); |
---|
131 | ideal I1, I2, Gn, G, F, mEntries, newGaction; |
---|
132 | G = imap(RIGB, Grp); |
---|
133 | F = imap(RIGB, Gaction); |
---|
134 | mEntries = imap(RIGB, matrixEntries); |
---|
135 | |
---|
136 | // prepare the ideals needed to compute the image |
---|
137 | // and compute the new action of the image on K^m |
---|
138 | |
---|
139 | for(i = 1; i <= size(mEntries); i++) { I1[i] = var(i + nvars(RIGB)) - mEntries[i]; } |
---|
140 | I1 = std(I1); |
---|
141 | |
---|
142 | for(i = 1; i <= ncols(F); i++) { newGaction[i] = reduce(F[i], I1); } |
---|
143 | I2 = G, I1; |
---|
144 | I2 = std(I2); |
---|
145 | Gn = nselect(I2, 1, nvars(RIGB)); |
---|
146 | imageSize = ncols(Gn); |
---|
147 | |
---|
148 | // create a new basering which might contain more variables |
---|
149 | // s(1..newVars) as the original basering and map the ideal |
---|
150 | // Gn (contians only z(1..newVars)) to this ring |
---|
151 | |
---|
152 | ringSTR2 = "ring RIGS = (" + charstr(basering) + "), (s(1.." + string(newVars) + "), t(1.." + string(nrt) + ")), lp;"; |
---|
153 | execute(ringSTR2); |
---|
154 | minpoly = number(imap(RIGB, mPoly)); |
---|
155 | ideal mapIdeal, groupid, actionid; |
---|
156 | int offset; |
---|
157 | |
---|
158 | // construct the map F : RIGB -> RIGS |
---|
159 | |
---|
160 | for(i = 1; i <= nvars(RIGB) - nrt; i++) { mapIdeal[i] = 0;} // s(i) -> 0 |
---|
161 | offset = nvars(RIGB) - nrt; |
---|
162 | for(i = 1; i <= nrt; i++) { mapIdeal[i + offset] = var(newVars + i);} // t(i) -> t(i) |
---|
163 | offset = offset + nrt; |
---|
164 | for(i = 1; i <= newVars; i++) { mapIdeal[i + offset] = var(i);} // z(i) -> s(i) |
---|
165 | |
---|
166 | // map Gn and newGaction to RIGS |
---|
167 | |
---|
168 | map F = RIGR, mapIdeal; |
---|
169 | groupid = F(Gn); |
---|
170 | actionid = F(newGaction); |
---|
171 | export(groupid); |
---|
172 | export(actionid); |
---|
173 | dbprint(dbPrt, " |
---|
174 | // 'ImageGroup' created a new ring. |
---|
175 | // To see the ring, type (if the name of the ring is R): |
---|
176 | show(R); |
---|
177 | // To access the ideal of the image-group Gn of the group G w.r.t. 'action' |
---|
178 | // and the new action of Gn, type |
---|
179 | def R = ImageGroup(G, action); setring R; groupid; actionid; |
---|
180 | // 'groupid' is the ideal defining the image of the group G w.r.t. 'action' |
---|
181 | // and 'actionid' is the new action of 'groupid'. |
---|
182 | "); |
---|
183 | return(RIGS); |
---|
184 | } |
---|
185 | example |
---|
186 | {"EXAMPLE:"; echo = 2; |
---|
187 | ring B = 0,(s(1..2), t(1..2)),dp; |
---|
188 | ideal G = s(1)^3-1, s(2)^10-1; |
---|
189 | ideal action = s(1)*s(2)^8*t(1), s(1)*s(2)^7*t(2); |
---|
190 | def R = ImageGroup(G, action); |
---|
191 | setring R; |
---|
192 | groupid; |
---|
193 | actionid; |
---|
194 | } |
---|
195 | |
---|
196 | /////////////////////////////////////////////////////////////////////////////// |
---|
197 | |
---|
198 | proc HilbertWeights(ideal I, wt) |
---|
199 | "USAGE: HilbertWeights(I, w); ideal I, intvec wt |
---|
200 | PURPOSE: compute the weights of the "slack" varaibles needed for the |
---|
201 | computation of the algebraic relations of the generators of 'I' s.t. |
---|
202 | the Hilbert driven 'std' can be used. |
---|
203 | RETURN: intvec |
---|
204 | ASSUME: basering = K[t_1,...,t_m,...], 'I' is quasihomogenous w.r.t. 'w' and |
---|
205 | contains only polynomials in t_1,...,t_m |
---|
206 | " |
---|
207 | { |
---|
208 | int offset = size(wt); |
---|
209 | intvec wtn = wt; |
---|
210 | |
---|
211 | for(int i = 1; i <= size(I); i++) { wtn[offset + i] = deg(I[i], wt); } |
---|
212 | return(wtn); |
---|
213 | } |
---|
214 | |
---|
215 | /////////////////////////////////////////////////////////////////////////////// |
---|
216 | |
---|
217 | proc HilbertSeries(ideal I, wt) |
---|
218 | "USAGE: HilbertSeries(I, w); ideal I, intvec wt |
---|
219 | PURPOSE: compute the polynomial p of the Hilbert Series,represented by p/q, of |
---|
220 | the ring K[t_1,...,t_m,y_1,...,y_r]/I1 where 'w' are the weights of |
---|
221 | the variables, computed, e.g., by 'HilbertWeights', 'I1' is of the |
---|
222 | form I[1] - y_1,...,I[r] - y_r and is quasihomogenous w.r.t. 'w' |
---|
223 | RETURN: intvec |
---|
224 | NOTE: the leading 0 of the result does not belong to p, but is needed in |
---|
225 | the hilbert-driven 'std'. |
---|
226 | " |
---|
227 | { |
---|
228 | int i; |
---|
229 | intvec hs1; |
---|
230 | matrix coMx; |
---|
231 | poly f = 1; |
---|
232 | |
---|
233 | for(i = 1; i <= ncols(I); i++) { f = f * (1 - var(1)^deg(I[i], wt));} |
---|
234 | coMx = coeffs(f, var(1)); |
---|
235 | for(i = 1; i <= deg(f) + 1; i++) { |
---|
236 | hs1[i] = int(coMx[i, 1]); |
---|
237 | } |
---|
238 | hs1[size(hs1) + 1] = 0; |
---|
239 | return(hs1); |
---|
240 | } |
---|
241 | |
---|
242 | proc HilbertSeries1(wt) |
---|
243 | "USAGE: HilbertSeries1(wt); ideal I, intvec wt |
---|
244 | PURPOSE: compute the polynomial p of the Hilbert Series represented by p/q of |
---|
245 | the ring K[t_1,...,t_m,y_1,...,y_r]/I where I is a complete inter- |
---|
246 | section and the generator I[i] has degree wt[i] |
---|
247 | RETURN: poly |
---|
248 | EXAMPLE: |
---|
249 | " |
---|
250 | { |
---|
251 | int i, j; |
---|
252 | intvec hs1; |
---|
253 | matrix ma; |
---|
254 | poly f = 1; |
---|
255 | |
---|
256 | for(i = 1; i <= size(wt); i++) { f = f * (1 - var(1)^wt[i]);} |
---|
257 | ma = coef(f, var(1)); |
---|
258 | j = ncols(ma); |
---|
259 | for(i = 0; i <= deg(f); i++) { |
---|
260 | if(var(1)^i == ma[1, j]) { |
---|
261 | hs1[i + 1] = int(ma[2, j]); |
---|
262 | j--; |
---|
263 | } |
---|
264 | else { hs1[i + 1] = 0; } |
---|
265 | } |
---|
266 | hs1[size(hs1) + 1] = 0; |
---|
267 | return(hs1); |
---|
268 | } |
---|
269 | |
---|
270 | /////////////////////////////////////////////////////////////////////////////// |
---|
271 | |
---|
272 | proc ImageVariety(ideal I, F, list #) |
---|
273 | "USAGE: ImageVariety(ideal I, F [, w]);ideal I; F is a list/ideal, intvec w. |
---|
274 | PURPOSE: compute the Zariski closure of the image of the variety of I under |
---|
275 | the morphism F. |
---|
276 | NOTE: if 'I' and 'F' are quasihomogenous w.r.t. 'w' then the Hilbert-driven |
---|
277 | 'std' is used. |
---|
278 | RETURN: polynomial ring over the same groundfield, containing the ideal |
---|
279 | 'imageid'. The variables are Y(1),...,Y(k) where k = size(F) |
---|
280 | - 'imageid' is the ideal of the Zariski closure of F(X) where |
---|
281 | X is the variety of I. |
---|
282 | EXAMPLE: example ImageVariety; shows an example |
---|
283 | " |
---|
284 | { |
---|
285 | int i, dbPrt, nrNewVars; |
---|
286 | intvec wt, wth, hs1; |
---|
287 | string ringSTR1, ringSTR2, order; |
---|
288 | |
---|
289 | def RARB = basering; |
---|
290 | nrNewVars = size(F); |
---|
291 | |
---|
292 | dbPrt = printlevel-voice+2; |
---|
293 | dbprint(dbPrt, "ImageVariety of " + string(I) + " under the map " + string(F)); |
---|
294 | |
---|
295 | if(size(#) > 0) { wt = #[1]; } |
---|
296 | |
---|
297 | // create new ring for elimination, Y(1),...,Y(m) are slack variables. |
---|
298 | |
---|
299 | poly mPoly = minpoly; |
---|
300 | order = "(dp(" + string(nvars(basering)) + "), dp);"; |
---|
301 | ringSTR1 = "ring RAR1 = (" + charstr(basering) + "), (" + varstr(basering) + ", Y(1.." + string(nrNewVars) + ")), " + order; |
---|
302 | ringSTR2 = "ring RAR2 = (" + charstr(basering) + "), Y(1.." + string(nrNewVars) + "), dp;"; |
---|
303 | execute(ringSTR1); |
---|
304 | minpoly = number(imap(RARB, mPoly)); |
---|
305 | |
---|
306 | ideal I, J1, J2, Fm; |
---|
307 | |
---|
308 | I = imap(RARB, I); |
---|
309 | Fm = imap(RARB, F); |
---|
310 | |
---|
311 | if(size(wt) > 1) { |
---|
312 | wth = HilbertWeights(Fm, wt); |
---|
313 | hs1 = HilbertSeries(Fm, wt); |
---|
314 | } |
---|
315 | |
---|
316 | // get the ideal of the graph of F : X -> Y and compute a standard basis |
---|
317 | |
---|
318 | for(i = 1; i <= nrNewVars; i++) { J1[i] = var(i + nvars(RARB)) - Fm[i];} |
---|
319 | J1 = J1, I; |
---|
320 | if(size(wt) > 1) { |
---|
321 | J1 = std(J1, hs1, wth); // Hilbert-driven algorithm |
---|
322 | } |
---|
323 | else { |
---|
324 | J1 = std(J1); |
---|
325 | } |
---|
326 | |
---|
327 | // forget all elements which contain other than the slack variables |
---|
328 | |
---|
329 | J2 = nselect(J1, 1, nvars(RARB)); |
---|
330 | |
---|
331 | execute(ringSTR2); |
---|
332 | minpoly = number(imap(RARB, mPoly)); |
---|
333 | ideal imageid = imap(RAR1, J2); |
---|
334 | export(imageid); |
---|
335 | dbprint(dbPrt, " |
---|
336 | // 'ImageVariety' created a new ring. |
---|
337 | // To see the ring, type (if the name of the ring is R): |
---|
338 | show(R); |
---|
339 | // To access the ideal of the image F(X), where F is a map and X is a variety |
---|
340 | // with ideal I,type |
---|
341 | def R = ImageVariety(I, F); setring R; imageid; |
---|
342 | // 'imageid' is the ideal of the Zariski closure of F(X). |
---|
343 | "); |
---|
344 | return(RAR2); |
---|
345 | } |
---|
346 | example |
---|
347 | {"EXAMPLE:"; echo = 2; |
---|
348 | ring B = 0,(x,y),dp; |
---|
349 | ideal I = x4 - y4; |
---|
350 | ideal F = x2, y2, x*y; |
---|
351 | def R = ImageVariety(I, F); |
---|
352 | setring R; |
---|
353 | imageid; |
---|
354 | } |
---|
355 | |
---|
356 | /////////////////////////////////////////////////////////////////////////////// |
---|
357 | |
---|
358 | proc LinearizeAction(ideal Grp, Gaction, int nrs) |
---|
359 | "USAGE: LinearizeAction(G,action,r); ideal G, action; int r |
---|
360 | PURPOSE: linearize the group action 'action' and find an equivariant |
---|
361 | embedding of K^m where m = size(action). |
---|
362 | ASSUME: G contains only variables var(1..r) (r = nrs) |
---|
363 | basering = K[s(1..r),t(1..m)], K = Q or K = Q(a) and minpoly != 0. |
---|
364 | RETURN: polynomial ring contianing the ideals 'actionid','embedid','groupid' |
---|
365 | - 'actionid' is the ideal defining the linearized action of G |
---|
366 | - 'embedid' is a parameterization of an equivariant embedding |
---|
367 | - 'groupid' is the ideal of G in the new ring |
---|
368 | NOTE: set printlevel > 0 to see a trace |
---|
369 | EXAMPLE: example LinearizeAction; shows an example |
---|
370 | " |
---|
371 | { |
---|
372 | int i, j, k, ok, loop, nrt, sizeOfDecomp, dbPrt; |
---|
373 | intvec wt; |
---|
374 | ideal action, basis, G, reduceIdeal; |
---|
375 | matrix decompMx; |
---|
376 | poly actCoeff; |
---|
377 | string str, order, mPoly; |
---|
378 | |
---|
379 | dbPrt = printlevel-voice+2; |
---|
380 | dbprint(dbPrt, "LinearizeAction " + string(Gaction)); |
---|
381 | def RLAR = basering; |
---|
382 | mPoly = "minpoly = " + string(minpoly) + ";"; |
---|
383 | order = ordstr(basering); |
---|
384 | nrt = ncols(Gaction); |
---|
385 | for(i = 1; i <= nrs; i++) { wt[i] = 0;} |
---|
386 | for(i = nrs + 1; i <= nrs + nrt; i++) { basis[i - nrs] = var(i); wt[i] = 1;} |
---|
387 | dbprint(dbPrt, " basis = " + string(basis)); |
---|
388 | if(attrib(Grp, "isSB")) { G = Grp; } |
---|
389 | else { G = std(Grp); } |
---|
390 | reduceIdeal = G; |
---|
391 | action = Gaction; |
---|
392 | loop = 1; |
---|
393 | i = 1; |
---|
394 | |
---|
395 | // check if each component of 'action' is linear in t(1),...,t(nrt). |
---|
396 | |
---|
397 | while(loop){ |
---|
398 | if(deg(action[i], wt) <= 1) { |
---|
399 | sizeOfDecomp = 0; |
---|
400 | dbprint(dbPrt, " " + string(action[i]) + " is linear"); |
---|
401 | } |
---|
402 | else { // action[i] is not linear |
---|
403 | |
---|
404 | // compute the minimal decomposition of action[i] |
---|
405 | // action[i] = decompMx[1,1]*decompMx[2,1] + ... + decompMx[1,k]*decompMx[2,k] |
---|
406 | // decompMx[1,j] contains variables var(1)...var(nrs) |
---|
407 | // decompMx[2,j] contains variables var(nrs + 1)...var(nvars(basering)) |
---|
408 | |
---|
409 | dbprint(dbPrt, " " + string(action[i]) + " is not linear, a minimal decomposition is :"); |
---|
410 | decompMx = MinimalDecomposition(action[i], nrs, nrt); |
---|
411 | sizeOfDecomp = ncols(decompMx); |
---|
412 | dbprint(dbPrt, decompMx); |
---|
413 | |
---|
414 | for(j = 1; j <= sizeOfDecomp; j++) { // check if decompMx[2,j] is a linear combination of basis elements |
---|
415 | actCoeff = decompMx[2, j]; |
---|
416 | ok = LinearCombinationQ(basis, actCoeff, nrt + nrs); |
---|
417 | if(ok == 0) { |
---|
418 | |
---|
419 | // nonlinear element, compute new component of the action |
---|
420 | |
---|
421 | dbprint(dbPrt, " the polynomial " + string(actCoeff) + " is not a linear combination of the elements of basis"); |
---|
422 | nrt++; |
---|
423 | str = charstr(basering) + ", (" + varstr(basering) + ",t(" + string(nrt) + ")),"; |
---|
424 | if(defined(RLAB)) { kill(RLAB);} |
---|
425 | def RLAB = basering; |
---|
426 | if(defined(RLAR)) { kill(RLAR);} |
---|
427 | execute("ring RLAR = " + str + "(" + order + ");"); |
---|
428 | execute(mPoly); |
---|
429 | |
---|
430 | ideal basis, action, G, reduceIdeal; |
---|
431 | matrix decompMx; |
---|
432 | map F; |
---|
433 | poly actCoeff; |
---|
434 | |
---|
435 | wt[nrs + nrt] = 1; |
---|
436 | basis = imap(RLAB, basis), imap(RLAB, actCoeff); |
---|
437 | action = imap(RLAB, action); |
---|
438 | decompMx = imap(RLAB, decompMx); |
---|
439 | actCoeff = imap(RLAB, actCoeff); |
---|
440 | G = imap(RLAB, G); |
---|
441 | attrib(G, "isSB", 1); |
---|
442 | reduceIdeal = imap(RLAB, reduceIdeal), actCoeff - var(nrs + nrt); |
---|
443 | |
---|
444 | // compute action on the new basis element |
---|
445 | |
---|
446 | for(k = 1; k <= nrs; k++) { F[k] = 0;} |
---|
447 | for(k = nrs + 1; k < nrs + nrt; k++) { F[k] = action[k - nrs];} |
---|
448 | actCoeff = reduce(F(actCoeff), G); |
---|
449 | action[ncols(action) + 1] = actCoeff; |
---|
450 | dbprint(dbPrt, " extend basering by " + string(var(nrs + nrt))); |
---|
451 | dbprint(dbPrt, " new basis = " + string(basis)); |
---|
452 | dbprint(dbPrt, " action of G on new basis element = " + string(actCoeff)); |
---|
453 | dbprint(dbPrt, " decomp : " + string(decompMx[2, j]) + " -> " + string(var(nrs + nrt))); |
---|
454 | } // end if |
---|
455 | else { |
---|
456 | dbprint(dbPrt, " the polynomial " + string(actCoeff) + " is a linear combination of the elements of basis"); |
---|
457 | } |
---|
458 | } // end for |
---|
459 | reduceIdeal = std(reduceIdeal); |
---|
460 | action[i] = reduce(action[i], reduceIdeal); |
---|
461 | } // end else |
---|
462 | if(i < ncols(action)) { i++;} |
---|
463 | else {loop = 0;} |
---|
464 | } // end while |
---|
465 | if(defined(actionid)) { kill(actionid); } |
---|
466 | ideal actionid, embedid, groupid; |
---|
467 | actionid = action; |
---|
468 | embedid = basis; |
---|
469 | groupid = G; |
---|
470 | export(actionid); |
---|
471 | export(embedid); |
---|
472 | export(groupid); |
---|
473 | dbprint(dbPrt, " |
---|
474 | // 'LinearizeAction' created a new ring. |
---|
475 | // To see the ring, type (if the name of the ring is R): |
---|
476 | show(R); |
---|
477 | // To access the new action and the equivariant embedding, where G and 'action' |
---|
478 | // are the original group and group-action contained in K[s(1..ns)] and |
---|
479 | // K[s(1..ns),t(1..nt)] respectively, type |
---|
480 | def R = LinearizeAction(G, action, ns, nt); setring R; actionid; embedid; groupid |
---|
481 | // 'actionid' is the ideal of the linearized action, 'embedid' is the ideal |
---|
482 | // defining the equivariant embedding and 'grouid' is the ideal G. |
---|
483 | "); |
---|
484 | return(RLAR); |
---|
485 | } |
---|
486 | example |
---|
487 | {"EXAMPLE:"; echo = 2; |
---|
488 | ring B = 0,(s(1..5), t(1..3)),dp; |
---|
489 | ideal G = s(3)-s(4), s(2)-s(5), s(4)*s(5), s(1)^2*s(4)+s(1)^2*s(5)-1, s(1)^2*s(5)^2-s(5), s(4)^4-s(5)^4+s(1)^2, s(1)^4+s(4)^3-s(5)^3, s(5)^5-s(1)^2*s(5); |
---|
490 | ideal action = -s(4)*t(1)+s(5)*t(1), -s(4)^2*t(2)+2*s(4)^2*t(3)^2+s(5)^2*t(2), s(4)*t(3)+s(5)*t(3); |
---|
491 | LinearActionQ(action, 5); |
---|
492 | def R = LinearizeAction(G, action, 5); |
---|
493 | setring R; |
---|
494 | R; |
---|
495 | actionid; |
---|
496 | embedid; |
---|
497 | groupid; |
---|
498 | LinearActionQ(actionid, 5); |
---|
499 | } |
---|
500 | |
---|
501 | /////////////////////////////////////////////////////////////////////////////// |
---|
502 | |
---|
503 | proc LinearActionQ(Gaction, int nrs) |
---|
504 | "USAGE: LinearActionQ(action,nrs,nrt); ideal action, int nrs |
---|
505 | PURPOSE: check if the action defined by 'action' is linear wrt. the variables |
---|
506 | var(nrs + 1...nvars(basering)). |
---|
507 | RETURN: 0 action not linear |
---|
508 | 1 action is linear |
---|
509 | EXAMPLE: example LinearActionQ; shows an example |
---|
510 | " |
---|
511 | { |
---|
512 | int i, nrt, loop; |
---|
513 | intvec wt; |
---|
514 | |
---|
515 | nrt = ncols(Gaction); |
---|
516 | for(i = 1; i <= nrs; i++) { wt[i] = 0;} |
---|
517 | for(i = nrs + 1; i <= nrs + nrt; i++) { wt[i] = 1;} |
---|
518 | loop = 1; |
---|
519 | i = 1; |
---|
520 | while(loop){ |
---|
521 | if(deg(Gaction[i], wt) > 1) { loop = 0; } |
---|
522 | else { |
---|
523 | i++; |
---|
524 | if(i > ncols(Gaction)) { loop = 0;} |
---|
525 | } |
---|
526 | } |
---|
527 | return(i > ncols(Gaction)); |
---|
528 | } |
---|
529 | example |
---|
530 | {"EXAMPLE:"; echo = 2; |
---|
531 | ring R = 0,(s(1..5), t(1..3)),dp; |
---|
532 | ideal G = s(3)-s(4), s(2)-s(5), s(4)*s(5), s(1)^2*s(4)+s(1)^2*s(5)-1, s(1)^2*s(5)^2-s(5), s(4)^4-s(5)^4+s(1)^2, s(1)^4+s(4)^3-s(5)^3, s(5)^5-s(1)^2*s(5); |
---|
533 | ideal Gaction = -s(4)*t(1)+s(5)*t(1), -s(4)^2*t(2)+2*s(4)^2*t(3)^2+s(5)^2*t(2), s(4)*t(3)+s(5)*t(3); |
---|
534 | LinearActionQ(Gaction, 5, 3); |
---|
535 | } |
---|
536 | |
---|
537 | /////////////////////////////////////////////////////////////////////////////// |
---|
538 | |
---|
539 | proc LinearCombinationQ(ideal I, poly f) |
---|
540 | "USAGE: LinearCombination(I, f); ideal I, poly f |
---|
541 | PURPOSE: test if f can be written as a linear combination of the gens. of I |
---|
542 | RETURN: 0 'f' is not a linear combination |
---|
543 | 1 'f' is a linear combination |
---|
544 | " |
---|
545 | { |
---|
546 | int i, loop, sizeJ; |
---|
547 | ideal J; |
---|
548 | |
---|
549 | J = I, f; |
---|
550 | sizeJ = size(J); |
---|
551 | |
---|
552 | def RLC = ImageVariety(ideal(0), J); // compute algebraic relations |
---|
553 | setring RLC; |
---|
554 | matrix coMx; |
---|
555 | poly relation = 0; |
---|
556 | |
---|
557 | loop = 1; |
---|
558 | i = 1; |
---|
559 | while(loop) { // look for a linear relation containing Y(nr) |
---|
560 | if(deg(imageid[i]) == 1) { |
---|
561 | coMx = coef(imageid[i], var(sizeJ)); |
---|
562 | if(coMx[1,1] == var(sizeJ)) { |
---|
563 | relation = imageid[i]; |
---|
564 | loop = 0; |
---|
565 | } |
---|
566 | } |
---|
567 | else { |
---|
568 | i++; |
---|
569 | if(i > ncols(imageid)) { loop = 0;} |
---|
570 | } |
---|
571 | } |
---|
572 | return(i <= ncols(imageid)); |
---|
573 | } |
---|
574 | |
---|
575 | /////////////////////////////////////////////////////////////////////////////// |
---|
576 | |
---|
577 | proc InvariantRing(ideal G, ideal action, list #) |
---|
578 | "USAGE: InvariantRing(G, Gact [, opt]); ideal G, Gact; int opt |
---|
579 | PURPOSE: compute generators of the invariant ring of G wrt. the action 'Gact' |
---|
580 | ASSUME: G is a finite group and 'Gact' is a linear action. |
---|
581 | RETURN: polynomial ring over a simple extension of the groundfield of the |
---|
582 | basering (the extension might be trivial), containing the ideals |
---|
583 | 'invars' and 'groupid' and the poly 'newA' |
---|
584 | - 'invars' contains the algebra-generators of the invariant ring |
---|
585 | - 'groupid' is the ideal of G in the new ring |
---|
586 | - 'newA' if the minpoly changes this is the new representation of |
---|
587 | the algebraic number, otherwise it is set to 'a'. |
---|
588 | NOTE: the delivered ring might have a different minimal polynomial |
---|
589 | EXAMPLE: example InvariantRing; shows an example |
---|
590 | " |
---|
591 | { |
---|
592 | int i, ok, dbPrt, noReynolds, primaryDec; |
---|
593 | ideal invarsGens, groupid; |
---|
594 | |
---|
595 | dbPrt = printlevel-voice+2; |
---|
596 | |
---|
597 | if(size(#) > 0) { primaryDec = #[1]; } |
---|
598 | else { primaryDec = 0; } |
---|
599 | |
---|
600 | dbprint(dbPrt, "InvariantRing of " + string(G)); |
---|
601 | dbprint(dbPrt, " action = " + string(action)); |
---|
602 | |
---|
603 | if(!attrib(G, "isSB")) { groupid = std(G);} |
---|
604 | else { groupid = G; } |
---|
605 | |
---|
606 | // compute the nullcone of G by means of Derksen's algorithm |
---|
607 | |
---|
608 | invarsGens = NullCone(groupid, action); // compute the nullcone of the linear action |
---|
609 | dbprint(dbPrt, " generators of zero-fibre ideal are " + string(invarsGens)); |
---|
610 | |
---|
611 | // make all generators of the nullcone invariant |
---|
612 | // if necessary, compute the Reynolds Operator, i.e., find all elements |
---|
613 | // of the variety defined by G. It might be necessary to extend the groundfield. |
---|
614 | |
---|
615 | def IRB = basering; |
---|
616 | if(defined(RIRR)) { kill(RIRR);} |
---|
617 | def RIRR = basering; |
---|
618 | setring RIRR; |
---|
619 | export(RIRR); |
---|
620 | export(invarsGens); |
---|
621 | noReynolds = 1; |
---|
622 | dbprint(dbPrt, " nullcone is generated by " + string(size(invarsGens))); |
---|
623 | dbprint(dbPrt, " degrees = " + string(maxdeg(invarsGens))); |
---|
624 | for(i = 1; i <= ncols(invarsGens); i++){ |
---|
625 | ok = InvariantQ(invarsGens[i], groupid, action); |
---|
626 | if(ok) { dbprint(dbPrt, string(i) + ": poly " + string(invarsGens[i]) + " is invariant");} |
---|
627 | else { |
---|
628 | if(noReynolds) { |
---|
629 | |
---|
630 | // compute the Reynolds operator and change the ring ! |
---|
631 | |
---|
632 | def RORN = ReynoldsOperator(groupid, action, primaryDec); |
---|
633 | noReynolds = 0; |
---|
634 | setring RORN; |
---|
635 | export(RORN); |
---|
636 | ideal groupid = std(id); |
---|
637 | kill(id); |
---|
638 | attrib(groupid, "isSB", 1); |
---|
639 | ideal action = actionid; |
---|
640 | ideal invarsGens = TransferIdeal(RIRR, "invarsGens", newA); |
---|
641 | export(invarsGens); |
---|
642 | kill(RIRR); |
---|
643 | |
---|
644 | } |
---|
645 | dbprint(dbPrt, string(i) + ": poly " + string(invarsGens[i]) + " is NOT invariant"); |
---|
646 | invarsGens[i] = ReynoldsImage(ROelements, invarsGens[i]); |
---|
647 | dbprint(dbPrt, " --> " + string(invarsGens[i])); |
---|
648 | } |
---|
649 | } |
---|
650 | for(i = 1; i <= ncols(invarsGens); i++){ |
---|
651 | ok = InvariantQ(invarsGens[i], groupid, action); |
---|
652 | if(ok) { dbprint(dbPrt, string(i) + ": poly " + string(invarsGens[i]) + " is invariant"); } |
---|
653 | else { print(string(i) + ": Fatal Error with Reynolds ");} |
---|
654 | } |
---|
655 | kill(IRB); |
---|
656 | if(noReynolds == 0) { |
---|
657 | def RIRS = RORN; |
---|
658 | setring(RIRS); |
---|
659 | kill(RORN);export(groupid); |
---|
660 | } |
---|
661 | else { |
---|
662 | def RIRS = RIRR; |
---|
663 | kill(RIRR); |
---|
664 | setring(RIRS); |
---|
665 | export(groupid); |
---|
666 | } |
---|
667 | ideal invars = invarsGens; |
---|
668 | kill(invarsGens); |
---|
669 | export(invars); |
---|
670 | // export(groupid); |
---|
671 | dbprint(dbPrt, " |
---|
672 | // 'InvariantRing' created a new ring. |
---|
673 | // To see the ring, type (if the name of the ring is R): |
---|
674 | show(R); |
---|
675 | // To access the generators of the invariant ring of G w.r.t. the linear |
---|
676 | // group-action 'action' of G, where G is contained in K[s(1..ns)] and |
---|
677 | // 'action' in K[s(1..ns),t(1..nt)], type |
---|
678 | def R = InvariantRing(G, action); setring R; invars; |
---|
679 | // 'invars' contains generator of the invariant ring. |
---|
680 | // Note that G is containd in R as the ideal 'groupid', to see it, type |
---|
681 | groupid; |
---|
682 | // Note that 'InvariantRing' might change the minimal polynomial |
---|
683 | // The representation of the algebraic number is given by 'newA' |
---|
684 | "); |
---|
685 | return(RIRS); |
---|
686 | } |
---|
687 | example |
---|
688 | {"EXAMPLE:"; echo = 2; |
---|
689 | ring B = 0, (s(1..2), t(1..2)), dp; |
---|
690 | ideal G = -s(1)+s(2)^3, s(1)^4-1; |
---|
691 | ideal action = s(1)*t(1), s(2)*t(2); |
---|
692 | |
---|
693 | def R = InvariantRing(std(G), action); |
---|
694 | setring R; |
---|
695 | invars; |
---|
696 | } |
---|
697 | |
---|
698 | /////////////////////////////////////////////////////////////////////////////// |
---|
699 | |
---|
700 | proc InvariantQ(poly f, ideal G, action) |
---|
701 | "USAGE: InvariantQ(f, G, action); poly f; ideal G, action |
---|
702 | PURPOSE: check if the polynomial f is invariant w.r.t. G where G acts via |
---|
703 | 'action' on K^m. |
---|
704 | ASSUME: basering = K[s_1,...,s_m,t_1,...,t_m] where K = Q of K = Q(a) and |
---|
705 | minpoly != 0, f contains only t_1,...,t_m, G is the ideal of an |
---|
706 | algebraic group and a standardbasis. |
---|
707 | RETURN: int; |
---|
708 | 0 if f is not invariant, |
---|
709 | 1 if f is invariant |
---|
710 | NOTE: G need not be finite |
---|
711 | EXAMPLE: example InvariantQ; shows an example |
---|
712 | " |
---|
713 | { |
---|
714 | map F; |
---|
715 | |
---|
716 | if(deg(f) == 0) { return(1); } |
---|
717 | for(int i = 1; i <= size(action); i++) { |
---|
718 | F[nvars(basering) - size(action) + i] = action[i]; |
---|
719 | } |
---|
720 | return(reduce(f - F(f), G) == 0); |
---|
721 | } |
---|
722 | |
---|
723 | /////////////////////////////////////////////////////////////////////////////// |
---|
724 | |
---|
725 | proc MinimalDecomposition(poly f, int nrs, int nrt) |
---|
726 | "USAGE: MinimalDecomposition(f,a,b); poly f; int a, b. |
---|
727 | PURPOSE: decompose f as a sum M[1,1]*M[2,1] + ... + M[1,r]*M[2,r] where M[1,i] |
---|
728 | contains only s(1..a), M[2,i] contains only t(1...b) st. r is minimal |
---|
729 | ASSUME: f polynomial in K[s(1..a),t(1..b)],K = Q or K = Q(a) and minpoly != 0 |
---|
730 | RETURN: 2 x r matrix M s.t. f = M[1,1]*M[2,1] + ... + M[1,r]*M[2,r] |
---|
731 | EXAMPLE: example MinimalDecomposition; |
---|
732 | " |
---|
733 | { |
---|
734 | int i, sizeOfMx, changed, loop; |
---|
735 | list initialTerms; |
---|
736 | matrix coM1, coM2, coM, decompMx, auxM; |
---|
737 | matrix m[2][2] = 0,1,1,0; |
---|
738 | poly vars1, vars2; |
---|
739 | |
---|
740 | if(f == 0) { return(decompMx); } |
---|
741 | |
---|
742 | // first decompose f w.r.t. t(1..nrt) |
---|
743 | // then decompose f w.r.t. s(1..nrs) |
---|
744 | |
---|
745 | vars1 = RingVarProduct(nrs+1..nrt+nrs); |
---|
746 | vars2 = RingVarProduct(1..nrs); |
---|
747 | coM1 = SimplifyCoefficientMatrix(m*coef(f, vars1)); // exchange rows of decomposition |
---|
748 | coM2 = SimplifyCoefficientMatrix(coef(f, vars2)); |
---|
749 | if(ncols(coM2) < ncols(coM1)) { |
---|
750 | auxM = coM1; |
---|
751 | coM1 = coM2; |
---|
752 | coM2 = auxM; |
---|
753 | } |
---|
754 | decompMx = coM1; // decompMx is the smaller decomposition |
---|
755 | if(ncols(decompMx) == 1) { return(decompMx);} // n = 1 is minimal |
---|
756 | changed = 0; |
---|
757 | loop = 1; |
---|
758 | i = 1; |
---|
759 | |
---|
760 | // first loop, try coM1 |
---|
761 | |
---|
762 | while(loop) { |
---|
763 | coM = MinimalDecomposition(f - coM1[1, i]*coM1[2, i], nrs, nrt); |
---|
764 | if(size(coM) == 1) { sizeOfMx = 0; } // coM = 0 |
---|
765 | else {sizeOfMx = ncols(coM); } // number of columns |
---|
766 | if(sizeOfMx + 1 < ncols(decompMx)) { // shorter decomposition |
---|
767 | changed = 1; |
---|
768 | decompMx = coM; |
---|
769 | initialTerms[1] = coM1[1, i]; |
---|
770 | initialTerms[2] = coM1[2, i]; |
---|
771 | } |
---|
772 | if(sizeOfMx == 1) { loop = 0;} // n = 2 is minimal |
---|
773 | if(i < ncols(coM1)) {i++;} |
---|
774 | else {loop = 0;} |
---|
775 | } |
---|
776 | if(sizeOfMx > 1) { // n > 2 |
---|
777 | loop = 1; // coM2 might yield |
---|
778 | i = 1; // a smaller decomposition |
---|
779 | } |
---|
780 | |
---|
781 | // first loop, try coM2 |
---|
782 | |
---|
783 | while(loop) { |
---|
784 | coM = MinimalDecomposition(f - coM2[1, i]*coM2[2, i], nrs, nrt); |
---|
785 | if(size(coM) == 1) { sizeOfMx = 0; } |
---|
786 | else {sizeOfMx = ncols(coM); } |
---|
787 | if(sizeOfMx + 1 < ncols(decompMx)) { |
---|
788 | changed = 1; |
---|
789 | decompMx = coM; |
---|
790 | initialTerms[1] = coM2[1, i]; |
---|
791 | initialTerms[2] = coM2[2, i]; |
---|
792 | } |
---|
793 | if(sizeOfMx == 1) { loop = 0;} |
---|
794 | if(i < ncols(coM2)) {i++;} |
---|
795 | else {loop = 0;} |
---|
796 | } |
---|
797 | if(!changed) { return(decompMx); } |
---|
798 | if(size(decompMx) == 1) { matrix decompositionM[2][1];} |
---|
799 | else { matrix decompositionM[2][ncols(decompMx) + 1];} |
---|
800 | decompositionM[1, 1] = initialTerms[1]; |
---|
801 | decompositionM[2, 1] = initialTerms[2]; |
---|
802 | if(size(decompMx) > 1) { |
---|
803 | for(i = 1; i <= ncols(decompMx); i++) { |
---|
804 | decompositionM[1, i + 1] = decompMx[1, i]; |
---|
805 | decompositionM[2, i + 1] = decompMx[2, i]; |
---|
806 | } |
---|
807 | } |
---|
808 | return(decompositionM); |
---|
809 | } |
---|
810 | example |
---|
811 | {"EXAMPLE:"; echo = 2; |
---|
812 | ring R = 0, (s(1..2), t(1..2)), dp; |
---|
813 | poly h = s(1)*(t(1) + t(1)^2) + (t(2) + t(2)^2)*(s(1)^2 + s(2)); |
---|
814 | matrix M = MinimalDecomposition(h, 2, 2); |
---|
815 | M; |
---|
816 | M[1,1]*M[2,1] + M[1,2]*M[2,2] - h; |
---|
817 | } |
---|
818 | |
---|
819 | /////////////////////////////////////////////////////////////////////////////// |
---|
820 | |
---|
821 | proc NullCone(ideal G, action) |
---|
822 | "USAGE: NullCone(G, action); ideal G, action |
---|
823 | PURPOSE: compute the ideal of the nullcone of the linear action of G on K^n, |
---|
824 | given by 'action', by means of Deksen's algorithm |
---|
825 | ASSUME: basering = K[s(1..r),t(1..n)], K = Q or K = Q(a) and minpoly != 0, |
---|
826 | G is an ideal of a reductive algebraic group in K[s(1..r)], |
---|
827 | 'action' is a linear group action of G on K^n (n = ncols(action)) |
---|
828 | RETURN: ideal of the nullcone of G. |
---|
829 | NOTE: the generators of the nullcone are homogenous, but ig. not invariant |
---|
830 | EXAMPLE: example NullCone; shows an example |
---|
831 | " |
---|
832 | { |
---|
833 | int i, nt, dbPrt, offset, groupVars; |
---|
834 | poly minPoly; |
---|
835 | string ringSTR, vars, order; |
---|
836 | def RNCB = basering; |
---|
837 | |
---|
838 | // prepare the ring needed for the computation |
---|
839 | // s(1...) variables of the group |
---|
840 | // t(1...) variables of the affine space |
---|
841 | // y(1...) additional 'slack' variables |
---|
842 | |
---|
843 | nt = size(action); |
---|
844 | order = "(dp(" + string(nvars(basering) - nt) + "), dp);"; |
---|
845 | vars = "(s(1.." + string(nvars(basering) - nt); |
---|
846 | vars = vars + "), t(1.." + string(nt) + "), Y(1.." + string(nt) + "))," + order; |
---|
847 | ringSTR = "ring RNCR = (" + charstr(basering) + ")," + vars; // ring for the computation |
---|
848 | |
---|
849 | minPoly = minpoly; |
---|
850 | offset = size(G) + nt; |
---|
851 | execute(ringSTR); |
---|
852 | minpoly = number(imap(RNCB, minPoly)); |
---|
853 | ideal action, G, I, J, N, generators; |
---|
854 | map F; |
---|
855 | poly f; |
---|
856 | |
---|
857 | // built the ideal of the graph of GxV -> V, (s,v) -> s(v), i.e. |
---|
858 | // of the image of the map GxV -> GxVxV, (s,v) -> (s,v,s(v)) |
---|
859 | |
---|
860 | G = fetch(RNCB, G); |
---|
861 | action = fetch(RNCB, action); |
---|
862 | groupVars = nvars(basering) - 2*nt; |
---|
863 | offset = groupVars + nt; |
---|
864 | I = G; |
---|
865 | for(i = 1; i <= nt; i = i + 1) { |
---|
866 | I = I, var(offset + i) - action[i]; |
---|
867 | } |
---|
868 | |
---|
869 | J = std(I); // takes long, try to improve |
---|
870 | |
---|
871 | // eliminate |
---|
872 | |
---|
873 | N = nselect(J, 1, groupVars); |
---|
874 | |
---|
875 | // substitute |
---|
876 | |
---|
877 | for(i = 1; i <= nvars(basering); i = i + 1) { F[i] = 0; } |
---|
878 | for(i = groupVars + 1; i <= offset; i = i + 1) { F[i] = var(i); } |
---|
879 | |
---|
880 | generators = mstd(F(N))[2]; |
---|
881 | setring(RNCB); |
---|
882 | return(fetch(RNCR, generators)); |
---|
883 | } |
---|
884 | example |
---|
885 | {"EXAMPLE:"; echo = 2; |
---|
886 | ring R = 0, (s(1..2), x, y), dp; |
---|
887 | ideal G = -s(1)+s(2)^3, s(1)^4-1; |
---|
888 | ideal action = s(1)*x, s(2)*y; |
---|
889 | |
---|
890 | ideal inv = NullCone(G, action); |
---|
891 | inv; |
---|
892 | } |
---|
893 | |
---|
894 | /////////////////////////////////////////////////////////////////////////////// |
---|
895 | |
---|
896 | proc ReynoldsOperator(ideal Grp, ideal Gaction, list #) |
---|
897 | "USAGE: ReynoldsOperator(G, action [, opt); ideal G, action; int opt |
---|
898 | PURPOSE: compute the Reynolds operator of the group G which act via 'action' |
---|
899 | RETURN: polynomial ring R over a simple extension of the groundfield of the |
---|
900 | basering (the extension might be trivial), containing a list |
---|
901 | 'ROelements', the ideals 'id', 'actionid' and the polynomial 'newA'. |
---|
902 | R = K(a)[s(1..r),t(1..n)]. |
---|
903 | - 'ROelements' is a list of ideal, each ideal represents a |
---|
904 | substitution map F : R -> R according to the zero-set of G |
---|
905 | - 'id' is the ideal of G in the new ring |
---|
906 | - 'newA' is the new representation of a' in terms of a. If the |
---|
907 | basering does not contain a parameter then 'newA' = 'a'. |
---|
908 | ASSUME: basering = K[s(1..r),t(1..n)], K = Q or K = Q(a') and minpoly != 0, |
---|
909 | G is the ideal of a finite group in K[s(1..r)],'action' is a linear |
---|
910 | group action of G |
---|
911 | EXAMPLE: example ReynoldsOperator; shows an example |
---|
912 | " |
---|
913 | { |
---|
914 | int i, j, n, ns, primaryDec; |
---|
915 | ideal G1 = Grp; |
---|
916 | list solution, saction; |
---|
917 | string str; |
---|
918 | |
---|
919 | if(size(#) > 0) { primaryDec = #[1]; } |
---|
920 | else { primaryDec = 0; } |
---|
921 | |
---|
922 | n = nvars(basering); |
---|
923 | ns = n - size(Gaction); |
---|
924 | for(i = ns + 1; i <= n; i++) { G1 = G1, var(i);} |
---|
925 | |
---|
926 | def ROBR = basering; |
---|
927 | export(Grp); |
---|
928 | export(Gaction); |
---|
929 | def RORN = ZeroSet(G1, primaryDec); |
---|
930 | setring RORN; |
---|
931 | id = TransferIdeal(ROBR, "Grp", newA); // defined in ZeroSet ... |
---|
932 | ideal actionid = TransferIdeal(ROBR, "Gaction", newA); |
---|
933 | list ROelements; |
---|
934 | ideal Rf; |
---|
935 | map groupElem; |
---|
936 | poly h1, h2; |
---|
937 | |
---|
938 | for(i = 1; i <= size(zeroset); i++) { |
---|
939 | groupElem = zeroset[i]; // element of G |
---|
940 | for(j = ns + 1; j <= n; j++) { groupElem[j] = var(j); } // do not change t's |
---|
941 | for(j = 1; j <= n - ns; j++) { |
---|
942 | h1 = actionid[j]; |
---|
943 | h2 = groupElem(h1); |
---|
944 | Rf[ns + j] = h2; |
---|
945 | } |
---|
946 | ROelements[i] = Rf; |
---|
947 | } |
---|
948 | export(actionid); |
---|
949 | export(ROelements); |
---|
950 | return(RORN); |
---|
951 | } |
---|
952 | |
---|
953 | /////////////////////////////////////////////////////////////////////////////// |
---|
954 | |
---|
955 | proc ReynoldsImage(list reynoldsOp, poly f) |
---|
956 | "USAGE: ReynoldsImage(RO, f); list RO, poly f |
---|
957 | PURPOSE: compute the Reynolds image of the polynomial f where RO represents |
---|
958 | the Reynolds operator |
---|
959 | RETURN: poly |
---|
960 | " |
---|
961 | { |
---|
962 | map F; |
---|
963 | poly h = 0; |
---|
964 | |
---|
965 | for(int i = 1; i <= size(reynoldsOp); i++) { |
---|
966 | F = basering, reynoldsOp[i]; |
---|
967 | h = h + F(f); |
---|
968 | } |
---|
969 | return(h/size(reynoldsOp)); |
---|
970 | } |
---|
971 | |
---|
972 | /////////////////////////////////////////////////////////////////////////////// |
---|
973 | |
---|
974 | static proc SimplifyCoefficientMatrix(matrix coefMatrix) |
---|
975 | "USAGE: SimplifyCoefficientMatrix(M); M matrix coming from coef(...) |
---|
976 | PURPOSE: simplify the matrix, i.e. find linear dependencies among the columns |
---|
977 | RETURN: matrix M, f = M[1,1]*M[2,1] + ... + M[1,n]*M[2,n] |
---|
978 | " |
---|
979 | { |
---|
980 | int i, j , loop; |
---|
981 | intvec columnList; |
---|
982 | matrix decompMx = coefMatrix; |
---|
983 | |
---|
984 | loop = 1; |
---|
985 | i = 1; |
---|
986 | while(loop) { |
---|
987 | columnList = 1..i; // current column |
---|
988 | for(j = i + 1; j <= ncols(decompMx); j++) { |
---|
989 | // test if decompMx[2, j] equals const * decompMx[2, i] |
---|
990 | if(LinearCombinationQ(ideal(decompMx[2, i]), decompMx[2, j])) { // column not needed |
---|
991 | decompMx[1, i] = decompMx[1, i] + decompMx[2, j] / decompMx[2, i] * decompMx[1, j]; |
---|
992 | } |
---|
993 | else { columnList[size(columnList) + 1] = j; } |
---|
994 | } |
---|
995 | if(defined(auxM)) { kill(auxM);} |
---|
996 | matrix auxM[2][size(columnList)]; // built new matrix and omit |
---|
997 | for(j = 1; j <= size(columnList); j++) { // the linear dependent colums |
---|
998 | auxM[1, j] = decompMx[1, columnList[j]]; // found above |
---|
999 | auxM[2, j] = decompMx[2, columnList[j]]; |
---|
1000 | } |
---|
1001 | decompMx = auxM; |
---|
1002 | if(i < ncols(decompMx) - 1) { i++;} |
---|
1003 | else { loop = 0;} |
---|
1004 | } |
---|
1005 | return(decompMx); |
---|
1006 | } |
---|
1007 | |
---|
1008 | /////////////////////////////////////////////////////////////////////////////// |
---|
1009 | |
---|
1010 | proc SimplifyIdeal(ideal I, list #) |
---|
1011 | "USAGE: SimplifyIdeal(I [,m, name]); ideal I; int m, string name |
---|
1012 | PURPOSE: simplify ideal I to the ideal I', do not change the names of the |
---|
1013 | first m variables, new ideal I' might contain less variables. |
---|
1014 | I' contains variables var(1..m) |
---|
1015 | RETURN: list |
---|
1016 | _[1] ideal I' |
---|
1017 | _[2] ideal representing a map phi to a ring with probably less |
---|
1018 | varsiables s.t. phi(I) = I' |
---|
1019 | _[3] list of variables |
---|
1020 | _[4] list from 'elimpart' |
---|
1021 | NOTE: |
---|
1022 | " |
---|
1023 | { |
---|
1024 | int i, k, m; |
---|
1025 | string nameCMD; |
---|
1026 | ideal mId, In, mapId; // ideal for the map |
---|
1027 | list sList, result; |
---|
1028 | |
---|
1029 | sList = elimpart(I); |
---|
1030 | In = sList[1]; |
---|
1031 | mapId = sList[5]; |
---|
1032 | |
---|
1033 | if(size(#) > 0) { |
---|
1034 | m = #[1]; |
---|
1035 | nameCMD = #[2]; |
---|
1036 | } |
---|
1037 | else { m = 0;} // nvars(basering); |
---|
1038 | k = 0; |
---|
1039 | for(i = 1; i <= nvars(basering); i++) { |
---|
1040 | if(sList[4][i] != 0) { |
---|
1041 | k++; |
---|
1042 | if(k <= m) { mId[i] = sList[4][i]; } |
---|
1043 | else { execute("mId["+string(i) +"] = "+nameCMD+"("+string(k-m)+");");} |
---|
1044 | } |
---|
1045 | else { mId[i] = 0;} |
---|
1046 | } |
---|
1047 | map phi = basering, mId; |
---|
1048 | result[1] = phi(In); |
---|
1049 | result[2] = phi(mapId); |
---|
1050 | result[3] = simplify(sList[4], 2); |
---|
1051 | result[4] = sList; |
---|
1052 | return(result); |
---|
1053 | } |
---|
1054 | |
---|
1055 | //////////////////////////////////////////////////////////////////////////////// |
---|
1056 | |
---|
1057 | static proc TransferIdeal(R, string name, poly newA) |
---|
1058 | " USAGE: TransferIdeal(R, name, newA); ring R, string name, poly newA |
---|
1059 | PURPOSE: Maps an ideal with name 'name' in R to the basering, s.t. all |
---|
1060 | variables are fixed but par(1) is replaced by 'newA'. |
---|
1061 | RETURN: ideal |
---|
1062 | NOTE: this is used to transfor ideals if the minimal polynomial has changed |
---|
1063 | " |
---|
1064 | { |
---|
1065 | def RAB = basering; |
---|
1066 | def RA1 = TransferRing(R); |
---|
1067 | |
---|
1068 | setring RA1; |
---|
1069 | execute("ideal I = imap(R, " + name + ");"); |
---|
1070 | setring RAB; |
---|
1071 | map F = RA1, maxideal(1); |
---|
1072 | F[nvars(RAB) + 1] = newA; |
---|
1073 | return(F(I)); |
---|
1074 | } |
---|
1075 | |
---|
1076 | /////////////////////////////////////////////////////////////////////////////// |
---|
1077 | |
---|
1078 | static proc RingVarProduct(index) |
---|
1079 | // list of indices |
---|
1080 | { |
---|
1081 | poly f = 1; |
---|
1082 | |
---|
1083 | for(int i = 1; i <= size(index); i++) { |
---|
1084 | f = f * var(index[i]); |
---|
1085 | } |
---|
1086 | return(f); |
---|
1087 | } |
---|
1088 | /////////////////////////////////////////////////////////////////////////////// |
---|