1 | /**************************************** |
---|
2 | * Computer Algebra System SINGULAR * |
---|
3 | ****************************************/ |
---|
4 | /* |
---|
5 | * ABSTRACT - Hilbert series |
---|
6 | */ |
---|
7 | |
---|
8 | #include "kernel/mod2.h" |
---|
9 | |
---|
10 | #include "omalloc/omalloc.h" |
---|
11 | #include "misc/mylimits.h" |
---|
12 | #include "misc/intvec.h" |
---|
13 | |
---|
14 | #include "kernel/combinatorics/hilb.h" |
---|
15 | #include "kernel/combinatorics/stairc.h" |
---|
16 | #include "kernel/combinatorics/hutil.h" |
---|
17 | |
---|
18 | #include "polys/monomials/ring.h" |
---|
19 | #include "polys/monomials/p_polys.h" |
---|
20 | #include "polys/simpleideals.h" |
---|
21 | |
---|
22 | |
---|
23 | // #include "kernel/structs.h" |
---|
24 | // #include "kernel/polys.h" |
---|
25 | //ADICHANGES: |
---|
26 | #include "kernel/ideals.h" |
---|
27 | // #include "kernel/GBEngine/kstd1.h" |
---|
28 | |
---|
29 | # define omsai 1 |
---|
30 | #if omsai |
---|
31 | |
---|
32 | #include "polys/ext_fields/transext.h" |
---|
33 | #include "coeffs/coeffs.h" |
---|
34 | #include "kernel/linear_algebra/linearAlgebra.h" |
---|
35 | #include "coeffs/numbers.h" |
---|
36 | #include <vector> |
---|
37 | #include "Singular/ipshell.h" |
---|
38 | |
---|
39 | |
---|
40 | #include <Singular/ipshell.h> |
---|
41 | #include <ctime> |
---|
42 | #include <iostream> |
---|
43 | #endif |
---|
44 | |
---|
45 | static int **Qpol; |
---|
46 | static int *Q0, *Ql; |
---|
47 | static int hLength; |
---|
48 | |
---|
49 | |
---|
50 | static int hMinModulweight(intvec *modulweight) |
---|
51 | { |
---|
52 | int i,j,k; |
---|
53 | |
---|
54 | if(modulweight==NULL) return 0; |
---|
55 | j=(*modulweight)[0]; |
---|
56 | for(i=modulweight->rows()-1;i!=0;i--) |
---|
57 | { |
---|
58 | k=(*modulweight)[i]; |
---|
59 | if(k<j) j=k; |
---|
60 | } |
---|
61 | return j; |
---|
62 | } |
---|
63 | |
---|
64 | static void hHilbEst(scfmon stc, int Nstc, varset var, int Nvar) |
---|
65 | { |
---|
66 | int i, j; |
---|
67 | int x, y, z = 1; |
---|
68 | int *p; |
---|
69 | for (i = Nvar; i>0; i--) |
---|
70 | { |
---|
71 | x = 0; |
---|
72 | for (j = 0; j < Nstc; j++) |
---|
73 | { |
---|
74 | y = stc[j][var[i]]; |
---|
75 | if (y > x) |
---|
76 | x = y; |
---|
77 | } |
---|
78 | z += x; |
---|
79 | j = i - 1; |
---|
80 | if (z > Ql[j]) |
---|
81 | { |
---|
82 | if (z>(MAX_INT_VAL)/2) |
---|
83 | { |
---|
84 | WerrorS("internal arrays too big"); |
---|
85 | return; |
---|
86 | } |
---|
87 | p = (int *)omAlloc((unsigned long)z * sizeof(int)); |
---|
88 | if (Ql[j]!=0) |
---|
89 | { |
---|
90 | if (j==0) |
---|
91 | memcpy(p, Qpol[j], Ql[j] * sizeof(int)); |
---|
92 | omFreeSize((ADDRESS)Qpol[j], Ql[j] * sizeof(int)); |
---|
93 | } |
---|
94 | if (j==0) |
---|
95 | { |
---|
96 | for (x = Ql[j]; x < z; x++) |
---|
97 | p[x] = 0; |
---|
98 | } |
---|
99 | Ql[j] = z; |
---|
100 | Qpol[j] = p; |
---|
101 | } |
---|
102 | } |
---|
103 | } |
---|
104 | |
---|
105 | static int *hAddHilb(int Nv, int x, int *pol, int *lp) |
---|
106 | { |
---|
107 | int l = *lp, ln, i; |
---|
108 | int *pon; |
---|
109 | *lp = ln = l + x; |
---|
110 | pon = Qpol[Nv]; |
---|
111 | memcpy(pon, pol, l * sizeof(int)); |
---|
112 | if (l > x) |
---|
113 | { |
---|
114 | for (i = x; i < l; i++) |
---|
115 | pon[i] -= pol[i - x]; |
---|
116 | for (i = l; i < ln; i++) |
---|
117 | pon[i] = -pol[i - x]; |
---|
118 | } |
---|
119 | else |
---|
120 | { |
---|
121 | for (i = l; i < x; i++) |
---|
122 | pon[i] = 0; |
---|
123 | for (i = x; i < ln; i++) |
---|
124 | pon[i] = -pol[i - x]; |
---|
125 | } |
---|
126 | return pon; |
---|
127 | } |
---|
128 | |
---|
129 | static void hLastHilb(scmon pure, int Nv, varset var, int *pol, int lp) |
---|
130 | { |
---|
131 | int l = lp, x, i, j; |
---|
132 | int *p, *pl; |
---|
133 | p = pol; |
---|
134 | for (i = Nv; i>0; i--) |
---|
135 | { |
---|
136 | x = pure[var[i + 1]]; |
---|
137 | if (x!=0) |
---|
138 | p = hAddHilb(i, x, p, &l); |
---|
139 | } |
---|
140 | pl = *Qpol; |
---|
141 | j = Q0[Nv + 1]; |
---|
142 | for (i = 0; i < l; i++) |
---|
143 | pl[i + j] += p[i]; |
---|
144 | x = pure[var[1]]; |
---|
145 | if (x!=0) |
---|
146 | { |
---|
147 | j += x; |
---|
148 | for (i = 0; i < l; i++) |
---|
149 | pl[i + j] -= p[i]; |
---|
150 | } |
---|
151 | j += l; |
---|
152 | if (j > hLength) |
---|
153 | hLength = j; |
---|
154 | } |
---|
155 | |
---|
156 | static void hHilbStep(scmon pure, scfmon stc, int Nstc, varset var, |
---|
157 | int Nvar, int *pol, int Lpol) |
---|
158 | { |
---|
159 | int iv = Nvar -1, ln, a, a0, a1, b, i; |
---|
160 | int x, x0; |
---|
161 | scmon pn; |
---|
162 | scfmon sn; |
---|
163 | int *pon; |
---|
164 | if (Nstc==0) |
---|
165 | { |
---|
166 | hLastHilb(pure, iv, var, pol, Lpol); |
---|
167 | return; |
---|
168 | } |
---|
169 | x = a = 0; |
---|
170 | pn = hGetpure(pure); |
---|
171 | sn = hGetmem(Nstc, stc, stcmem[iv]); |
---|
172 | hStepS(sn, Nstc, var, Nvar, &a, &x); |
---|
173 | Q0[iv] = Q0[Nvar]; |
---|
174 | ln = Lpol; |
---|
175 | pon = pol; |
---|
176 | if (a == Nstc) |
---|
177 | { |
---|
178 | x = pure[var[Nvar]]; |
---|
179 | if (x!=0) |
---|
180 | pon = hAddHilb(iv, x, pon, &ln); |
---|
181 | hHilbStep(pn, sn, a, var, iv, pon, ln); |
---|
182 | return; |
---|
183 | } |
---|
184 | else |
---|
185 | { |
---|
186 | pon = hAddHilb(iv, x, pon, &ln); |
---|
187 | hHilbStep(pn, sn, a, var, iv, pon, ln); |
---|
188 | } |
---|
189 | b = a; |
---|
190 | x0 = 0; |
---|
191 | loop |
---|
192 | { |
---|
193 | Q0[iv] += (x - x0); |
---|
194 | a0 = a; |
---|
195 | x0 = x; |
---|
196 | hStepS(sn, Nstc, var, Nvar, &a, &x); |
---|
197 | hElimS(sn, &b, a0, a, var, iv); |
---|
198 | a1 = a; |
---|
199 | hPure(sn, a0, &a1, var, iv, pn, &i); |
---|
200 | hLex2S(sn, b, a0, a1, var, iv, hwork); |
---|
201 | b += (a1 - a0); |
---|
202 | ln = Lpol; |
---|
203 | if (a < Nstc) |
---|
204 | { |
---|
205 | pon = hAddHilb(iv, x - x0, pol, &ln); |
---|
206 | hHilbStep(pn, sn, b, var, iv, pon, ln); |
---|
207 | } |
---|
208 | else |
---|
209 | { |
---|
210 | x = pure[var[Nvar]]; |
---|
211 | if (x!=0) |
---|
212 | pon = hAddHilb(iv, x - x0, pol, &ln); |
---|
213 | else |
---|
214 | pon = pol; |
---|
215 | hHilbStep(pn, sn, b, var, iv, pon, ln); |
---|
216 | return; |
---|
217 | } |
---|
218 | } |
---|
219 | } |
---|
220 | |
---|
221 | /* |
---|
222 | *basic routines |
---|
223 | */ |
---|
224 | static void hWDegree(intvec *wdegree) |
---|
225 | { |
---|
226 | int i, k; |
---|
227 | int x; |
---|
228 | |
---|
229 | for (i=(currRing->N); i; i--) |
---|
230 | { |
---|
231 | x = (*wdegree)[i-1]; |
---|
232 | if (x != 1) |
---|
233 | { |
---|
234 | for (k=hNexist-1; k>=0; k--) |
---|
235 | { |
---|
236 | hexist[k][i] *= x; |
---|
237 | } |
---|
238 | } |
---|
239 | } |
---|
240 | } |
---|
241 | // ---------------------------------- ADICHANGES --------------------------------------------- |
---|
242 | //!!!!!!!!!!!!!!!!!!!!! Just for Monomial Ideals !!!!!!!!!!!!!!!!!!!!!!!!!!!! |
---|
243 | |
---|
244 | #if 0 // unused |
---|
245 | //Tests if the ideal is sorted by degree |
---|
246 | static bool idDegSortTest(ideal I) |
---|
247 | { |
---|
248 | if((I == NULL)||(idIs0(I))) |
---|
249 | { |
---|
250 | return(TRUE); |
---|
251 | } |
---|
252 | for(int i = 0; i<IDELEMS(I)-1; i++) |
---|
253 | { |
---|
254 | if(p_Totaldegree(I->m[i],currRing)>p_Totaldegree(I->m[i+1],currRing)) |
---|
255 | { |
---|
256 | idPrint(I); |
---|
257 | WerrorS("Ideal is not deg sorted!!"); |
---|
258 | return(FALSE); |
---|
259 | } |
---|
260 | } |
---|
261 | return(TRUE); |
---|
262 | } |
---|
263 | #endif |
---|
264 | |
---|
265 | //adds the new polynomial at the coresponding position |
---|
266 | //and simplifies the ideal |
---|
267 | static void SortByDeg_p(ideal I, poly p) |
---|
268 | { |
---|
269 | int i,j; |
---|
270 | if(idIs0(I)) |
---|
271 | { |
---|
272 | I->m[0] = p; |
---|
273 | return; |
---|
274 | } |
---|
275 | idSkipZeroes(I); |
---|
276 | #if 1 |
---|
277 | for(i = 0; (i<IDELEMS(I)) && (p_Totaldegree(I->m[i],currRing)<=p_Totaldegree(p,currRing)); i++) |
---|
278 | { |
---|
279 | if(p_DivisibleBy( I->m[i],p, currRing)) |
---|
280 | { |
---|
281 | return; |
---|
282 | } |
---|
283 | } |
---|
284 | for(i = IDELEMS(I)-1; (i>=0) && (p_Totaldegree(I->m[i],currRing)>=p_Totaldegree(p,currRing)); i--) |
---|
285 | { |
---|
286 | if(p_DivisibleBy(p,I->m[i], currRing)) |
---|
287 | { |
---|
288 | I->m[i] = NULL; |
---|
289 | } |
---|
290 | } |
---|
291 | if(idIs0(I)) |
---|
292 | { |
---|
293 | idSkipZeroes(I); |
---|
294 | I->m[0] = p; |
---|
295 | return; |
---|
296 | } |
---|
297 | #endif |
---|
298 | idSkipZeroes(I); |
---|
299 | //First I take the case when all generators have the same degree |
---|
300 | if(p_Totaldegree(I->m[0],currRing) == p_Totaldegree(I->m[IDELEMS(I)-1],currRing)) |
---|
301 | { |
---|
302 | if(p_Totaldegree(p,currRing)<p_Totaldegree(I->m[0],currRing)) |
---|
303 | { |
---|
304 | idInsertPoly(I,p); |
---|
305 | idSkipZeroes(I); |
---|
306 | for(i=IDELEMS(I)-1;i>=1; i--) |
---|
307 | { |
---|
308 | I->m[i] = I->m[i-1]; |
---|
309 | } |
---|
310 | I->m[0] = p; |
---|
311 | return; |
---|
312 | } |
---|
313 | if(p_Totaldegree(p,currRing)>=p_Totaldegree(I->m[IDELEMS(I)-1],currRing)) |
---|
314 | { |
---|
315 | idInsertPoly(I,p); |
---|
316 | idSkipZeroes(I); |
---|
317 | return; |
---|
318 | } |
---|
319 | } |
---|
320 | if(p_Totaldegree(p,currRing)<=p_Totaldegree(I->m[0],currRing)) |
---|
321 | { |
---|
322 | idInsertPoly(I,p); |
---|
323 | idSkipZeroes(I); |
---|
324 | for(i=IDELEMS(I)-1;i>=1; i--) |
---|
325 | { |
---|
326 | I->m[i] = I->m[i-1]; |
---|
327 | } |
---|
328 | I->m[0] = p; |
---|
329 | return; |
---|
330 | } |
---|
331 | if(p_Totaldegree(p,currRing)>=p_Totaldegree(I->m[IDELEMS(I)-1],currRing)) |
---|
332 | { |
---|
333 | idInsertPoly(I,p); |
---|
334 | idSkipZeroes(I); |
---|
335 | return; |
---|
336 | } |
---|
337 | for(i = IDELEMS(I)-2; ;) |
---|
338 | { |
---|
339 | if(p_Totaldegree(p,currRing)==p_Totaldegree(I->m[i],currRing)) |
---|
340 | { |
---|
341 | idInsertPoly(I,p); |
---|
342 | idSkipZeroes(I); |
---|
343 | for(j = IDELEMS(I)-1; j>=i+1;j--) |
---|
344 | { |
---|
345 | I->m[j] = I->m[j-1]; |
---|
346 | } |
---|
347 | I->m[i] = p; |
---|
348 | return; |
---|
349 | } |
---|
350 | if(p_Totaldegree(p,currRing)>p_Totaldegree(I->m[i],currRing)) |
---|
351 | { |
---|
352 | idInsertPoly(I,p); |
---|
353 | idSkipZeroes(I); |
---|
354 | for(j = IDELEMS(I)-1; j>=i+2;j--) |
---|
355 | { |
---|
356 | I->m[j] = I->m[j-1]; |
---|
357 | } |
---|
358 | I->m[i+1] = p; |
---|
359 | return; |
---|
360 | } |
---|
361 | i--; |
---|
362 | } |
---|
363 | } |
---|
364 | |
---|
365 | //it sorts the ideal by the degrees |
---|
366 | static ideal SortByDeg(ideal I) |
---|
367 | { |
---|
368 | if(idIs0(I)) |
---|
369 | { |
---|
370 | return id_Copy(I,currRing); |
---|
371 | } |
---|
372 | int i; |
---|
373 | ideal res; |
---|
374 | idSkipZeroes(I); |
---|
375 | res = idInit(1,1); |
---|
376 | res->m[0] = poly(0); |
---|
377 | for(i = 0; i<=IDELEMS(I)-1;i++) |
---|
378 | { |
---|
379 | SortByDeg_p(res, I->m[i]); |
---|
380 | } |
---|
381 | idSkipZeroes(res); |
---|
382 | //idDegSortTest(res); |
---|
383 | return(res); |
---|
384 | } |
---|
385 | |
---|
386 | //idQuot(I,p) for I monomial ideal, p a ideal with a single monomial. |
---|
387 | ideal idQuotMon(ideal Iorig, ideal p) |
---|
388 | { |
---|
389 | if(idIs0(Iorig)) |
---|
390 | { |
---|
391 | ideal res = idInit(1,1); |
---|
392 | res->m[0] = poly(0); |
---|
393 | return(res); |
---|
394 | } |
---|
395 | if(idIs0(p)) |
---|
396 | { |
---|
397 | ideal res = idInit(1,1); |
---|
398 | res->m[0] = pOne(); |
---|
399 | return(res); |
---|
400 | } |
---|
401 | ideal I = id_Head(Iorig,currRing); |
---|
402 | ideal res = idInit(IDELEMS(I),1); |
---|
403 | int i,j; |
---|
404 | int dummy; |
---|
405 | for(i = 0; i<IDELEMS(I); i++) |
---|
406 | { |
---|
407 | res->m[i] = p_Head(I->m[i], currRing); |
---|
408 | for(j = 1; (j<=currRing->N) ; j++) |
---|
409 | { |
---|
410 | dummy = p_GetExp(p->m[0], j, currRing); |
---|
411 | if(dummy > 0) |
---|
412 | { |
---|
413 | if(p_GetExp(I->m[i], j, currRing) < dummy) |
---|
414 | { |
---|
415 | p_SetExp(res->m[i], j, 0, currRing); |
---|
416 | } |
---|
417 | else |
---|
418 | { |
---|
419 | p_SetExp(res->m[i], j, p_GetExp(I->m[i], j, currRing) - dummy, currRing); |
---|
420 | } |
---|
421 | } |
---|
422 | } |
---|
423 | p_Setm(res->m[i], currRing); |
---|
424 | if(p_Totaldegree(res->m[i],currRing) == p_Totaldegree(I->m[i],currRing)) |
---|
425 | { |
---|
426 | p_Delete(&res->m[i],currRing); |
---|
427 | } |
---|
428 | else |
---|
429 | { |
---|
430 | p_Delete(&I->m[i],currRing); |
---|
431 | } |
---|
432 | } |
---|
433 | idSkipZeroes(res); |
---|
434 | idSkipZeroes(I); |
---|
435 | if(!idIs0(res)) |
---|
436 | { |
---|
437 | for(i = 0; i<=IDELEMS(res)-1; i++) |
---|
438 | { |
---|
439 | SortByDeg_p(I,res->m[i]); |
---|
440 | } |
---|
441 | } |
---|
442 | id_Delete(&res,currRing); |
---|
443 | //idDegSortTest(I); |
---|
444 | return(I); |
---|
445 | } |
---|
446 | |
---|
447 | //id_Add for monomials |
---|
448 | static void idAddMon(ideal I, ideal p) |
---|
449 | { |
---|
450 | SortByDeg_p(I,p->m[0]); |
---|
451 | //idSkipZeroes(I); |
---|
452 | } |
---|
453 | |
---|
454 | //searches for a variable that is not yet used (assumes that the ideal is sqrfree) |
---|
455 | static poly ChoosePVar (ideal I) |
---|
456 | { |
---|
457 | bool flag=TRUE; |
---|
458 | int i,j; |
---|
459 | poly res; |
---|
460 | for(i=1;i<=currRing->N;i++) |
---|
461 | { |
---|
462 | flag=TRUE; |
---|
463 | for(j=IDELEMS(I)-1;(j>=0)&&(flag);j--) |
---|
464 | { |
---|
465 | if(p_GetExp(I->m[j], i, currRing)>0) |
---|
466 | { |
---|
467 | flag=FALSE; |
---|
468 | } |
---|
469 | } |
---|
470 | |
---|
471 | if(flag == TRUE) |
---|
472 | { |
---|
473 | res = p_ISet(1, currRing); |
---|
474 | p_SetExp(res, i, 1, currRing); |
---|
475 | p_Setm(res,currRing); |
---|
476 | return(res); |
---|
477 | } |
---|
478 | else |
---|
479 | { |
---|
480 | p_Delete(&res, currRing); |
---|
481 | } |
---|
482 | } |
---|
483 | return(NULL); //i.e. it is the maximal ideal |
---|
484 | } |
---|
485 | |
---|
486 | #if 0 // unused |
---|
487 | //choice XL: last entry divided by x (xy10z15 -> y9z14) |
---|
488 | static poly ChoosePXL(ideal I) |
---|
489 | { |
---|
490 | int i,j,dummy=0; |
---|
491 | poly m; |
---|
492 | for(i = IDELEMS(I)-1; (i>=0) && (dummy == 0); i--) |
---|
493 | { |
---|
494 | for(j = 1; (j<=currRing->N) && (dummy == 0); j++) |
---|
495 | { |
---|
496 | if(p_GetExp(I->m[i],j, currRing)>1) |
---|
497 | { |
---|
498 | dummy = 1; |
---|
499 | } |
---|
500 | } |
---|
501 | } |
---|
502 | m = p_Copy(I->m[i+1],currRing); |
---|
503 | for(j = 1; j<=currRing->N; j++) |
---|
504 | { |
---|
505 | dummy = p_GetExp(m,j,currRing); |
---|
506 | if(dummy >= 1) |
---|
507 | { |
---|
508 | p_SetExp(m, j, dummy-1, currRing); |
---|
509 | } |
---|
510 | } |
---|
511 | if(!p_IsOne(m, currRing)) |
---|
512 | { |
---|
513 | p_Setm(m, currRing); |
---|
514 | return(m); |
---|
515 | } |
---|
516 | m = ChoosePVar(I); |
---|
517 | return(m); |
---|
518 | } |
---|
519 | #endif |
---|
520 | |
---|
521 | #if 0 // unused |
---|
522 | //choice XF: first entry divided by x (xy10z15 -> y9z14) |
---|
523 | static poly ChoosePXF(ideal I) |
---|
524 | { |
---|
525 | int i,j,dummy=0; |
---|
526 | poly m; |
---|
527 | for(i =0 ; (i<=IDELEMS(I)-1) && (dummy == 0); i++) |
---|
528 | { |
---|
529 | for(j = 1; (j<=currRing->N) && (dummy == 0); j++) |
---|
530 | { |
---|
531 | if(p_GetExp(I->m[i],j, currRing)>1) |
---|
532 | { |
---|
533 | dummy = 1; |
---|
534 | } |
---|
535 | } |
---|
536 | } |
---|
537 | m = p_Copy(I->m[i-1],currRing); |
---|
538 | for(j = 1; j<=currRing->N; j++) |
---|
539 | { |
---|
540 | dummy = p_GetExp(m,j,currRing); |
---|
541 | if(dummy >= 1) |
---|
542 | { |
---|
543 | p_SetExp(m, j, dummy-1, currRing); |
---|
544 | } |
---|
545 | } |
---|
546 | if(!p_IsOne(m, currRing)) |
---|
547 | { |
---|
548 | p_Setm(m, currRing); |
---|
549 | return(m); |
---|
550 | } |
---|
551 | m = ChoosePVar(I); |
---|
552 | return(m); |
---|
553 | } |
---|
554 | #endif |
---|
555 | |
---|
556 | #if 0 // unused |
---|
557 | //choice OL: last entry the first power (xy10z15 -> xy9z15) |
---|
558 | static poly ChoosePOL(ideal I) |
---|
559 | { |
---|
560 | int i,j,dummy; |
---|
561 | poly m; |
---|
562 | for(i = IDELEMS(I)-1;i>=0;i--) |
---|
563 | { |
---|
564 | m = p_Copy(I->m[i],currRing); |
---|
565 | for(j=1;j<=currRing->N;j++) |
---|
566 | { |
---|
567 | dummy = p_GetExp(m,j,currRing); |
---|
568 | if(dummy > 0) |
---|
569 | { |
---|
570 | p_SetExp(m,j,dummy-1,currRing); |
---|
571 | p_Setm(m,currRing); |
---|
572 | } |
---|
573 | } |
---|
574 | if(!p_IsOne(m, currRing)) |
---|
575 | { |
---|
576 | return(m); |
---|
577 | } |
---|
578 | else |
---|
579 | { |
---|
580 | p_Delete(&m,currRing); |
---|
581 | } |
---|
582 | } |
---|
583 | m = ChoosePVar(I); |
---|
584 | return(m); |
---|
585 | } |
---|
586 | #endif |
---|
587 | |
---|
588 | #if 0 // unused |
---|
589 | //choice OF: first entry the first power (xy10z15 -> xy9z15) |
---|
590 | static poly ChoosePOF(ideal I) |
---|
591 | { |
---|
592 | int i,j,dummy; |
---|
593 | poly m; |
---|
594 | for(i = 0 ;i<=IDELEMS(I)-1;i++) |
---|
595 | { |
---|
596 | m = p_Copy(I->m[i],currRing); |
---|
597 | for(j=1;j<=currRing->N;j++) |
---|
598 | { |
---|
599 | dummy = p_GetExp(m,j,currRing); |
---|
600 | if(dummy > 0) |
---|
601 | { |
---|
602 | p_SetExp(m,j,dummy-1,currRing); |
---|
603 | p_Setm(m,currRing); |
---|
604 | } |
---|
605 | } |
---|
606 | if(!p_IsOne(m, currRing)) |
---|
607 | { |
---|
608 | return(m); |
---|
609 | } |
---|
610 | else |
---|
611 | { |
---|
612 | p_Delete(&m,currRing); |
---|
613 | } |
---|
614 | } |
---|
615 | m = ChoosePVar(I); |
---|
616 | return(m); |
---|
617 | } |
---|
618 | #endif |
---|
619 | |
---|
620 | #if 0 // unused |
---|
621 | //choice VL: last entry the first variable with power (xy10z15 -> y) |
---|
622 | static poly ChoosePVL(ideal I) |
---|
623 | { |
---|
624 | int i,j,dummy; |
---|
625 | bool flag = TRUE; |
---|
626 | poly m = p_ISet(1,currRing); |
---|
627 | for(i = IDELEMS(I)-1;(i>=0) && (flag);i--) |
---|
628 | { |
---|
629 | flag = TRUE; |
---|
630 | for(j=1;(j<=currRing->N) && (flag);j++) |
---|
631 | { |
---|
632 | dummy = p_GetExp(I->m[i],j,currRing); |
---|
633 | if(dummy >= 2) |
---|
634 | { |
---|
635 | p_SetExp(m,j,1,currRing); |
---|
636 | p_Setm(m,currRing); |
---|
637 | flag = FALSE; |
---|
638 | } |
---|
639 | } |
---|
640 | if(!p_IsOne(m, currRing)) |
---|
641 | { |
---|
642 | return(m); |
---|
643 | } |
---|
644 | } |
---|
645 | m = ChoosePVar(I); |
---|
646 | return(m); |
---|
647 | } |
---|
648 | #endif |
---|
649 | |
---|
650 | #if 0 // unused |
---|
651 | //choice VF: first entry the first variable with power (xy10z15 -> y) |
---|
652 | static poly ChoosePVF(ideal I) |
---|
653 | { |
---|
654 | int i,j,dummy; |
---|
655 | bool flag = TRUE; |
---|
656 | poly m = p_ISet(1,currRing); |
---|
657 | for(i = 0;(i<=IDELEMS(I)-1) && (flag);i++) |
---|
658 | { |
---|
659 | flag = TRUE; |
---|
660 | for(j=1;(j<=currRing->N) && (flag);j++) |
---|
661 | { |
---|
662 | dummy = p_GetExp(I->m[i],j,currRing); |
---|
663 | if(dummy >= 2) |
---|
664 | { |
---|
665 | p_SetExp(m,j,1,currRing); |
---|
666 | p_Setm(m,currRing); |
---|
667 | flag = FALSE; |
---|
668 | } |
---|
669 | } |
---|
670 | if(!p_IsOne(m, currRing)) |
---|
671 | { |
---|
672 | return(m); |
---|
673 | } |
---|
674 | } |
---|
675 | m = ChoosePVar(I); |
---|
676 | return(m); |
---|
677 | } |
---|
678 | #endif |
---|
679 | |
---|
680 | //choice JL: last entry just variable with power (xy10z15 -> y10) |
---|
681 | static poly ChoosePJL(ideal I) |
---|
682 | { |
---|
683 | int i,j,dummy; |
---|
684 | bool flag = TRUE; |
---|
685 | poly m = p_ISet(1,currRing); |
---|
686 | for(i = IDELEMS(I)-1;(i>=0) && (flag);i--) |
---|
687 | { |
---|
688 | flag = TRUE; |
---|
689 | for(j=1;(j<=currRing->N) && (flag);j++) |
---|
690 | { |
---|
691 | dummy = p_GetExp(I->m[i],j,currRing); |
---|
692 | if(dummy >= 2) |
---|
693 | { |
---|
694 | p_SetExp(m,j,dummy-1,currRing); |
---|
695 | p_Setm(m,currRing); |
---|
696 | flag = FALSE; |
---|
697 | } |
---|
698 | } |
---|
699 | if(!p_IsOne(m, currRing)) |
---|
700 | { |
---|
701 | return(m); |
---|
702 | } |
---|
703 | } |
---|
704 | p_Delete(&m,currRing); |
---|
705 | m = ChoosePVar(I); |
---|
706 | return(m); |
---|
707 | } |
---|
708 | |
---|
709 | #if 0 |
---|
710 | //choice JF: last entry just variable with power -1 (xy10z15 -> y9) |
---|
711 | static poly ChoosePJF(ideal I) |
---|
712 | { |
---|
713 | int i,j,dummy; |
---|
714 | bool flag = TRUE; |
---|
715 | poly m = p_ISet(1,currRing); |
---|
716 | for(i = 0;(i<=IDELEMS(I)-1) && (flag);i++) |
---|
717 | { |
---|
718 | flag = TRUE; |
---|
719 | for(j=1;(j<=currRing->N) && (flag);j++) |
---|
720 | { |
---|
721 | dummy = p_GetExp(I->m[i],j,currRing); |
---|
722 | if(dummy >= 2) |
---|
723 | { |
---|
724 | p_SetExp(m,j,dummy-1,currRing); |
---|
725 | p_Setm(m,currRing); |
---|
726 | flag = FALSE; |
---|
727 | } |
---|
728 | } |
---|
729 | if(!p_IsOne(m, currRing)) |
---|
730 | { |
---|
731 | return(m); |
---|
732 | } |
---|
733 | } |
---|
734 | m = ChoosePVar(I); |
---|
735 | return(m); |
---|
736 | } |
---|
737 | #endif |
---|
738 | |
---|
739 | //chooses 1 \neq p \not\in S. This choice should be made optimal |
---|
740 | static poly ChooseP(ideal I) |
---|
741 | { |
---|
742 | poly m; |
---|
743 | // TEST TO SEE WHICH ONE IS BETTER |
---|
744 | //m = ChoosePXL(I); |
---|
745 | //m = ChoosePXF(I); |
---|
746 | //m = ChoosePOL(I); |
---|
747 | //m = ChoosePOF(I); |
---|
748 | //m = ChoosePVL(I); |
---|
749 | //m = ChoosePVF(I); |
---|
750 | m = ChoosePJL(I); |
---|
751 | //m = ChoosePJF(I); |
---|
752 | return(m); |
---|
753 | } |
---|
754 | |
---|
755 | ///searches for a monomial of degree d>=2 and divides it by a variable (result monomial of deg d-1) |
---|
756 | static poly SearchP(ideal I) |
---|
757 | { |
---|
758 | int i,j,exp; |
---|
759 | poly res; |
---|
760 | if(p_Totaldegree(I->m[IDELEMS(I)-1],currRing)<=1) |
---|
761 | { |
---|
762 | res = ChoosePVar(I); |
---|
763 | return(res); |
---|
764 | } |
---|
765 | i = IDELEMS(I)-1; |
---|
766 | res = p_Copy(I->m[i], currRing); |
---|
767 | for(j=1;j<=currRing->N;j++) |
---|
768 | { |
---|
769 | exp = p_GetExp(I->m[i], j, currRing); |
---|
770 | if(exp > 0) |
---|
771 | { |
---|
772 | p_SetExp(res, j, exp - 1, currRing); |
---|
773 | p_Setm(res,currRing); |
---|
774 | break; |
---|
775 | } |
---|
776 | } |
---|
777 | assume( j <= currRing->N ); |
---|
778 | return(res); |
---|
779 | } |
---|
780 | |
---|
781 | //test if the ideal is of the form (x1, ..., xr) |
---|
782 | static bool JustVar(ideal I) |
---|
783 | { |
---|
784 | #if 0 |
---|
785 | int i,j; |
---|
786 | bool foundone; |
---|
787 | for(i=0;i<=IDELEMS(I)-1;i++) |
---|
788 | { |
---|
789 | foundone = FALSE; |
---|
790 | for(j = 1;j<=currRing->N;j++) |
---|
791 | { |
---|
792 | if(p_GetExp(I->m[i], j, currRing)>0) |
---|
793 | { |
---|
794 | if(foundone == TRUE) |
---|
795 | { |
---|
796 | return(FALSE); |
---|
797 | } |
---|
798 | foundone = TRUE; |
---|
799 | } |
---|
800 | } |
---|
801 | } |
---|
802 | return(TRUE); |
---|
803 | #else |
---|
804 | if(p_Totaldegree(I->m[IDELEMS(I)-1],currRing)>1) |
---|
805 | { |
---|
806 | return(FALSE); |
---|
807 | } |
---|
808 | return(TRUE); |
---|
809 | #endif |
---|
810 | } |
---|
811 | |
---|
812 | //computes the Euler Characteristic of the ideal |
---|
813 | static void eulerchar (ideal I, int variables, mpz_ptr ec) |
---|
814 | { |
---|
815 | loop |
---|
816 | { |
---|
817 | mpz_t dummy; |
---|
818 | if(JustVar(I) == TRUE) |
---|
819 | { |
---|
820 | if(IDELEMS(I) == variables) |
---|
821 | { |
---|
822 | mpz_init(dummy); |
---|
823 | if((variables % 2) == 0) |
---|
824 | mpz_set_ui(dummy, 1); |
---|
825 | else |
---|
826 | mpz_set_si(dummy, -1); |
---|
827 | mpz_add(ec, ec, dummy); |
---|
828 | mpz_clear(dummy); |
---|
829 | } |
---|
830 | return; |
---|
831 | } |
---|
832 | ideal p = idInit(1,1); |
---|
833 | p->m[0] = SearchP(I); |
---|
834 | //idPrint(I); |
---|
835 | //idPrint(p); |
---|
836 | //printf("\nNow get in idQuotMon\n"); |
---|
837 | ideal Ip = idQuotMon(I,p); |
---|
838 | //idPrint(Ip); |
---|
839 | //Ip = SortByDeg(Ip); |
---|
840 | int i,howmanyvarinp = 0; |
---|
841 | for(i = 1;i<=currRing->N;i++) |
---|
842 | { |
---|
843 | if(p_GetExp(p->m[0],i,currRing)>0) |
---|
844 | { |
---|
845 | howmanyvarinp++; |
---|
846 | } |
---|
847 | } |
---|
848 | eulerchar(Ip, variables-howmanyvarinp, ec); |
---|
849 | id_Delete(&Ip, currRing); |
---|
850 | idAddMon(I,p); |
---|
851 | id_Delete(&p, currRing); |
---|
852 | } |
---|
853 | } |
---|
854 | |
---|
855 | //tests if an ideal is Square Free, if no, returns the variable which appears at powers >1 |
---|
856 | static poly SqFree (ideal I) |
---|
857 | { |
---|
858 | int i,j; |
---|
859 | bool flag=TRUE; |
---|
860 | poly notsqrfree = NULL; |
---|
861 | if(p_Totaldegree(I->m[IDELEMS(I)-1],currRing)<=1) |
---|
862 | { |
---|
863 | return(notsqrfree); |
---|
864 | } |
---|
865 | for(i=IDELEMS(I)-1;(i>=0)&&(flag);i--) |
---|
866 | { |
---|
867 | for(j=1;(j<=currRing->N)&&(flag);j++) |
---|
868 | { |
---|
869 | if(p_GetExp(I->m[i],j,currRing)>1) |
---|
870 | { |
---|
871 | flag=FALSE; |
---|
872 | notsqrfree = p_ISet(1,currRing); |
---|
873 | p_SetExp(notsqrfree,j,1,currRing); |
---|
874 | } |
---|
875 | } |
---|
876 | } |
---|
877 | if(notsqrfree != NULL) |
---|
878 | { |
---|
879 | p_Setm(notsqrfree,currRing); |
---|
880 | } |
---|
881 | return(notsqrfree); |
---|
882 | } |
---|
883 | |
---|
884 | //checks if a polynomial is in I |
---|
885 | static bool IsIn(poly p, ideal I) |
---|
886 | { |
---|
887 | //assumes that I is ordered by degree |
---|
888 | if(idIs0(I)) |
---|
889 | { |
---|
890 | if(p==poly(0)) |
---|
891 | { |
---|
892 | return(TRUE); |
---|
893 | } |
---|
894 | else |
---|
895 | { |
---|
896 | return(FALSE); |
---|
897 | } |
---|
898 | } |
---|
899 | if(p==poly(0)) |
---|
900 | { |
---|
901 | return(FALSE); |
---|
902 | } |
---|
903 | int i,j; |
---|
904 | bool flag; |
---|
905 | for(i = 0;i<IDELEMS(I);i++) |
---|
906 | { |
---|
907 | flag = TRUE; |
---|
908 | for(j = 1;(j<=currRing->N) &&(flag);j++) |
---|
909 | { |
---|
910 | if(p_GetExp(p, j, currRing)<p_GetExp(I->m[i], j, currRing)) |
---|
911 | { |
---|
912 | flag = FALSE; |
---|
913 | } |
---|
914 | } |
---|
915 | if(flag) |
---|
916 | { |
---|
917 | return(TRUE); |
---|
918 | } |
---|
919 | } |
---|
920 | return(FALSE); |
---|
921 | } |
---|
922 | |
---|
923 | //computes the lcm of min I, I monomial ideal |
---|
924 | static poly LCMmon(ideal I) |
---|
925 | { |
---|
926 | if(idIs0(I)) |
---|
927 | { |
---|
928 | return(NULL); |
---|
929 | } |
---|
930 | poly m; |
---|
931 | int dummy,i,j; |
---|
932 | m = p_ISet(1,currRing); |
---|
933 | for(i=1;i<=currRing->N;i++) |
---|
934 | { |
---|
935 | dummy=0; |
---|
936 | for(j=IDELEMS(I)-1;j>=0;j--) |
---|
937 | { |
---|
938 | if(p_GetExp(I->m[j],i,currRing) > dummy) |
---|
939 | { |
---|
940 | dummy = p_GetExp(I->m[j],i,currRing); |
---|
941 | } |
---|
942 | } |
---|
943 | p_SetExp(m,i,dummy,currRing); |
---|
944 | } |
---|
945 | p_Setm(m,currRing); |
---|
946 | return(m); |
---|
947 | } |
---|
948 | |
---|
949 | //the Roune Slice Algorithm |
---|
950 | void rouneslice(ideal I, ideal S, poly q, poly x, int &prune, int &moreprune, int &steps, int &NNN, mpz_ptr &hilbertcoef, int* &hilbpower) |
---|
951 | { |
---|
952 | loop |
---|
953 | { |
---|
954 | (steps)++; |
---|
955 | int i,j; |
---|
956 | int dummy; |
---|
957 | poly m; |
---|
958 | ideal p; |
---|
959 | //----------- PRUNING OF S --------------- |
---|
960 | //S SHOULD IN THIS POINT BE ORDERED BY DEGREE |
---|
961 | for(i=IDELEMS(S)-1;i>=0;i--) |
---|
962 | { |
---|
963 | if(IsIn(S->m[i],I)) |
---|
964 | { |
---|
965 | p_Delete(&S->m[i],currRing); |
---|
966 | prune++; |
---|
967 | } |
---|
968 | } |
---|
969 | idSkipZeroes(S); |
---|
970 | //---------------------------------------- |
---|
971 | for(i=IDELEMS(I)-1;i>=0;i--) |
---|
972 | { |
---|
973 | m = p_Head(I->m[i],currRing); |
---|
974 | for(j=1;j<=currRing->N;j++) |
---|
975 | { |
---|
976 | dummy = p_GetExp(m,j,currRing); |
---|
977 | if(dummy > 0) |
---|
978 | { |
---|
979 | p_SetExp(m,j,dummy-1,currRing); |
---|
980 | } |
---|
981 | } |
---|
982 | p_Setm(m, currRing); |
---|
983 | if(IsIn(m,S)) |
---|
984 | { |
---|
985 | p_Delete(&I->m[i],currRing); |
---|
986 | //printf("\n Deleted, since pi(m) is in S\n");pWrite(m); |
---|
987 | } |
---|
988 | p_Delete(&m,currRing); |
---|
989 | } |
---|
990 | idSkipZeroes(I); |
---|
991 | //----------- MORE PRUNING OF S ------------ |
---|
992 | m = LCMmon(I); |
---|
993 | if(m != NULL) |
---|
994 | { |
---|
995 | for(i=0;i<IDELEMS(S);i++) |
---|
996 | { |
---|
997 | if(!(p_DivisibleBy(S->m[i], m, currRing))) |
---|
998 | { |
---|
999 | S->m[i] = NULL; |
---|
1000 | j++; |
---|
1001 | moreprune++; |
---|
1002 | } |
---|
1003 | else |
---|
1004 | { |
---|
1005 | if(pLmEqual(S->m[i],m)) |
---|
1006 | { |
---|
1007 | S->m[i] = NULL; |
---|
1008 | moreprune++; |
---|
1009 | } |
---|
1010 | } |
---|
1011 | } |
---|
1012 | idSkipZeroes(S); |
---|
1013 | } |
---|
1014 | p_Delete(&m,currRing); |
---|
1015 | /*printf("\n---------------------------\n"); |
---|
1016 | printf("\n I\n");idPrint(I); |
---|
1017 | printf("\n S\n");idPrint(S); |
---|
1018 | printf("\n q\n");pWrite(q); |
---|
1019 | getchar();*/ |
---|
1020 | |
---|
1021 | if(idIs0(I)) |
---|
1022 | { |
---|
1023 | id_Delete(&I, currRing); |
---|
1024 | id_Delete(&S, currRing); |
---|
1025 | break; |
---|
1026 | } |
---|
1027 | m = LCMmon(I); |
---|
1028 | if(!p_DivisibleBy(x,m, currRing)) |
---|
1029 | { |
---|
1030 | //printf("\nx does not divide lcm(I)"); |
---|
1031 | //printf("\nEmpty set");pWrite(q); |
---|
1032 | id_Delete(&I, currRing); |
---|
1033 | id_Delete(&S, currRing); |
---|
1034 | p_Delete(&m, currRing); |
---|
1035 | break; |
---|
1036 | } |
---|
1037 | p_Delete(&m, currRing); |
---|
1038 | m = SqFree(I); |
---|
1039 | if(m==NULL) |
---|
1040 | { |
---|
1041 | //printf("\n Corner: "); |
---|
1042 | //pWrite(q); |
---|
1043 | //printf("\n With the facets of the dual simplex:\n"); |
---|
1044 | //idPrint(I); |
---|
1045 | mpz_t ec; |
---|
1046 | mpz_init(ec); |
---|
1047 | mpz_ptr ec_ptr = ec; |
---|
1048 | eulerchar(I, currRing->N, ec_ptr); |
---|
1049 | bool flag = FALSE; |
---|
1050 | if(NNN==0) |
---|
1051 | { |
---|
1052 | hilbertcoef = (mpz_ptr)omAlloc((NNN+1)*sizeof(mpz_t)); |
---|
1053 | hilbpower = (int*)omAlloc((NNN+1)*sizeof(int)); |
---|
1054 | mpz_init_set( &hilbertcoef[NNN], ec); |
---|
1055 | hilbpower[NNN] = p_Totaldegree(q,currRing); |
---|
1056 | NNN++; |
---|
1057 | } |
---|
1058 | else |
---|
1059 | { |
---|
1060 | //I look if the power appears already |
---|
1061 | for(i = 0;(i<NNN)&&(flag == FALSE)&&(p_Totaldegree(q,currRing)>=hilbpower[i]);i++) |
---|
1062 | { |
---|
1063 | if((hilbpower[i]) == (p_Totaldegree(q,currRing))) |
---|
1064 | { |
---|
1065 | flag = TRUE; |
---|
1066 | mpz_add(&hilbertcoef[i],&hilbertcoef[i],ec_ptr); |
---|
1067 | } |
---|
1068 | } |
---|
1069 | if(flag == FALSE) |
---|
1070 | { |
---|
1071 | hilbertcoef = (mpz_ptr)omRealloc(hilbertcoef, (NNN+1)*sizeof(mpz_t)); |
---|
1072 | hilbpower = (int*)omRealloc(hilbpower, (NNN+1)*sizeof(int)); |
---|
1073 | mpz_init(&hilbertcoef[NNN]); |
---|
1074 | for(j = NNN; j>i; j--) |
---|
1075 | { |
---|
1076 | mpz_set(&hilbertcoef[j],&hilbertcoef[j-1]); |
---|
1077 | hilbpower[j] = hilbpower[j-1]; |
---|
1078 | } |
---|
1079 | mpz_set( &hilbertcoef[i], ec); |
---|
1080 | hilbpower[i] = p_Totaldegree(q,currRing); |
---|
1081 | NNN++; |
---|
1082 | } |
---|
1083 | } |
---|
1084 | mpz_clear(ec); |
---|
1085 | id_Delete(&I, currRing); |
---|
1086 | id_Delete(&S, currRing); |
---|
1087 | break; |
---|
1088 | } |
---|
1089 | else |
---|
1090 | p_Delete(&m, currRing); |
---|
1091 | m = ChooseP(I); |
---|
1092 | p = idInit(1,1); |
---|
1093 | p->m[0] = m; |
---|
1094 | ideal Ip = idQuotMon(I,p); |
---|
1095 | ideal Sp = idQuotMon(S,p); |
---|
1096 | poly pq = pp_Mult_mm(q,m,currRing); |
---|
1097 | rouneslice(Ip, Sp, pq, x, prune, moreprune, steps, NNN, hilbertcoef,hilbpower); |
---|
1098 | idAddMon(S,p); |
---|
1099 | p->m[0]=NULL; |
---|
1100 | id_Delete(&p, currRing); // p->m[0] was also in S |
---|
1101 | p_Delete(&pq,currRing); |
---|
1102 | } |
---|
1103 | } |
---|
1104 | |
---|
1105 | //it computes the first hilbert series by means of Roune Slice Algorithm |
---|
1106 | void slicehilb(ideal I) |
---|
1107 | { |
---|
1108 | //printf("Adi changes are here: \n"); |
---|
1109 | int i, NNN = 0; |
---|
1110 | int steps = 0, prune = 0, moreprune = 0; |
---|
1111 | mpz_ptr hilbertcoef; |
---|
1112 | int *hilbpower; |
---|
1113 | ideal S = idInit(1,1); |
---|
1114 | poly q = p_One(currRing); |
---|
1115 | ideal X = idInit(1,1); |
---|
1116 | X->m[0]=p_One(currRing); |
---|
1117 | for(i=1;i<=currRing->N;i++) |
---|
1118 | { |
---|
1119 | p_SetExp(X->m[0],i,1,currRing); |
---|
1120 | } |
---|
1121 | p_Setm(X->m[0],currRing); |
---|
1122 | I = id_Mult(I,X,currRing); |
---|
1123 | ideal Itmp = SortByDeg(I); |
---|
1124 | id_Delete(&I,currRing); |
---|
1125 | I = Itmp; |
---|
1126 | //printf("\n-------------RouneSlice--------------\n"); |
---|
1127 | rouneslice(I,S,q,X->m[0],prune, moreprune, steps, NNN, hilbertcoef, hilbpower); |
---|
1128 | id_Delete(&X,currRing); |
---|
1129 | p_Delete(&q,currRing); |
---|
1130 | //printf("\nIn total Prune got rid of %i elements\n",prune); |
---|
1131 | //printf("\nIn total More Prune got rid of %i elements\n",moreprune); |
---|
1132 | //printf("\nSteps of rouneslice: %i\n\n", steps); |
---|
1133 | printf("\n// %8d t^0",1); |
---|
1134 | for(i = 0; i<NNN; i++) |
---|
1135 | { |
---|
1136 | if(mpz_sgn(&hilbertcoef[i])!=0) |
---|
1137 | { |
---|
1138 | gmp_printf("\n// %8Zd t^%d",&hilbertcoef[i],hilbpower[i]); |
---|
1139 | } |
---|
1140 | } |
---|
1141 | PrintLn(); |
---|
1142 | omFreeSize(hilbertcoef, (NNN)*sizeof(mpz_t)); |
---|
1143 | omFreeSize(hilbpower, (NNN)*sizeof(int)); |
---|
1144 | //printf("\n-------------------------------------\n"); |
---|
1145 | } |
---|
1146 | |
---|
1147 | // -------------------------------- END OF CHANGES ------------------------------------------- |
---|
1148 | static intvec * hSeries(ideal S, intvec *modulweight, |
---|
1149 | int /*notstc*/, intvec *wdegree, ideal Q, ring tailRing) |
---|
1150 | { |
---|
1151 | // id_TestTail(S, currRing, tailRing); |
---|
1152 | |
---|
1153 | intvec *work, *hseries1=NULL; |
---|
1154 | int mc; |
---|
1155 | int p0; |
---|
1156 | int i, j, k, l, ii, mw; |
---|
1157 | hexist = hInit(S, Q, &hNexist, tailRing); |
---|
1158 | if (hNexist==0) |
---|
1159 | { |
---|
1160 | hseries1=new intvec(2); |
---|
1161 | (*hseries1)[0]=1; |
---|
1162 | (*hseries1)[1]=0; |
---|
1163 | return hseries1; |
---|
1164 | } |
---|
1165 | |
---|
1166 | #if 0 |
---|
1167 | if (wdegree == NULL) |
---|
1168 | hWeight(); |
---|
1169 | else |
---|
1170 | hWDegree(wdegree); |
---|
1171 | #else |
---|
1172 | if (wdegree != NULL) hWDegree(wdegree); |
---|
1173 | #endif |
---|
1174 | |
---|
1175 | p0 = 1; |
---|
1176 | hwork = (scfmon)omAlloc(hNexist * sizeof(scmon)); |
---|
1177 | hvar = (varset)omAlloc(((currRing->N) + 1) * sizeof(int)); |
---|
1178 | hpure = (scmon)omAlloc((1 + ((currRing->N) * (currRing->N))) * sizeof(int)); |
---|
1179 | stcmem = hCreate((currRing->N) - 1); |
---|
1180 | Qpol = (int **)omAlloc(((currRing->N) + 1) * sizeof(int *)); |
---|
1181 | Ql = (int *)omAlloc0(((currRing->N) + 1) * sizeof(int)); |
---|
1182 | Q0 = (int *)omAlloc(((currRing->N) + 1) * sizeof(int)); |
---|
1183 | *Qpol = NULL; |
---|
1184 | hLength = k = j = 0; |
---|
1185 | mc = hisModule; |
---|
1186 | if (mc!=0) |
---|
1187 | { |
---|
1188 | mw = hMinModulweight(modulweight); |
---|
1189 | hstc = (scfmon)omAlloc(hNexist * sizeof(scmon)); |
---|
1190 | } |
---|
1191 | else |
---|
1192 | { |
---|
1193 | mw = 0; |
---|
1194 | hstc = hexist; |
---|
1195 | hNstc = hNexist; |
---|
1196 | } |
---|
1197 | loop |
---|
1198 | { |
---|
1199 | if (mc!=0) |
---|
1200 | { |
---|
1201 | hComp(hexist, hNexist, mc, hstc, &hNstc); |
---|
1202 | if (modulweight != NULL) |
---|
1203 | j = (*modulweight)[mc-1]-mw; |
---|
1204 | } |
---|
1205 | if (hNstc!=0) |
---|
1206 | { |
---|
1207 | hNvar = (currRing->N); |
---|
1208 | for (i = hNvar; i>=0; i--) |
---|
1209 | hvar[i] = i; |
---|
1210 | //if (notstc) // TODO: no mon divides another |
---|
1211 | hStaircase(hstc, &hNstc, hvar, hNvar); |
---|
1212 | hSupp(hstc, hNstc, hvar, &hNvar); |
---|
1213 | if (hNvar!=0) |
---|
1214 | { |
---|
1215 | if ((hNvar > 2) && (hNstc > 10)) |
---|
1216 | hOrdSupp(hstc, hNstc, hvar, hNvar); |
---|
1217 | hHilbEst(hstc, hNstc, hvar, hNvar); |
---|
1218 | memset(hpure, 0, ((currRing->N) + 1) * sizeof(int)); |
---|
1219 | hPure(hstc, 0, &hNstc, hvar, hNvar, hpure, &hNpure); |
---|
1220 | hLexS(hstc, hNstc, hvar, hNvar); |
---|
1221 | Q0[hNvar] = 0; |
---|
1222 | hHilbStep(hpure, hstc, hNstc, hvar, hNvar, &p0, 1); |
---|
1223 | } |
---|
1224 | } |
---|
1225 | else |
---|
1226 | { |
---|
1227 | if(*Qpol!=NULL) |
---|
1228 | (**Qpol)++; |
---|
1229 | else |
---|
1230 | { |
---|
1231 | *Qpol = (int *)omAlloc(sizeof(int)); |
---|
1232 | hLength = *Ql = **Qpol = 1; |
---|
1233 | } |
---|
1234 | } |
---|
1235 | if (*Qpol!=NULL) |
---|
1236 | { |
---|
1237 | i = hLength; |
---|
1238 | while ((i > 0) && ((*Qpol)[i - 1] == 0)) |
---|
1239 | i--; |
---|
1240 | if (i > 0) |
---|
1241 | { |
---|
1242 | l = i + j; |
---|
1243 | if (l > k) |
---|
1244 | { |
---|
1245 | work = new intvec(l); |
---|
1246 | for (ii=0; ii<k; ii++) |
---|
1247 | (*work)[ii] = (*hseries1)[ii]; |
---|
1248 | if (hseries1 != NULL) |
---|
1249 | delete hseries1; |
---|
1250 | hseries1 = work; |
---|
1251 | k = l; |
---|
1252 | } |
---|
1253 | while (i > 0) |
---|
1254 | { |
---|
1255 | (*hseries1)[i + j - 1] += (*Qpol)[i - 1]; |
---|
1256 | (*Qpol)[i - 1] = 0; |
---|
1257 | i--; |
---|
1258 | } |
---|
1259 | } |
---|
1260 | } |
---|
1261 | mc--; |
---|
1262 | if (mc <= 0) |
---|
1263 | break; |
---|
1264 | } |
---|
1265 | if (k==0) |
---|
1266 | { |
---|
1267 | hseries1=new intvec(2); |
---|
1268 | (*hseries1)[0]=0; |
---|
1269 | (*hseries1)[1]=0; |
---|
1270 | } |
---|
1271 | else |
---|
1272 | { |
---|
1273 | l = k+1; |
---|
1274 | while ((*hseries1)[l-2]==0) l--; |
---|
1275 | if (l!=k) |
---|
1276 | { |
---|
1277 | work = new intvec(l); |
---|
1278 | for (ii=l-2; ii>=0; ii--) |
---|
1279 | (*work)[ii] = (*hseries1)[ii]; |
---|
1280 | delete hseries1; |
---|
1281 | hseries1 = work; |
---|
1282 | } |
---|
1283 | (*hseries1)[l-1] = mw; |
---|
1284 | } |
---|
1285 | for (i = 0; i <= (currRing->N); i++) |
---|
1286 | { |
---|
1287 | if (Ql[i]!=0) |
---|
1288 | omFreeSize((ADDRESS)Qpol[i], Ql[i] * sizeof(int)); |
---|
1289 | } |
---|
1290 | omFreeSize((ADDRESS)Q0, ((currRing->N) + 1) * sizeof(int)); |
---|
1291 | omFreeSize((ADDRESS)Ql, ((currRing->N) + 1) * sizeof(int)); |
---|
1292 | omFreeSize((ADDRESS)Qpol, ((currRing->N) + 1) * sizeof(int *)); |
---|
1293 | hKill(stcmem, (currRing->N) - 1); |
---|
1294 | omFreeSize((ADDRESS)hpure, (1 + ((currRing->N) * (currRing->N))) * sizeof(int)); |
---|
1295 | omFreeSize((ADDRESS)hvar, ((currRing->N) + 1) * sizeof(int)); |
---|
1296 | omFreeSize((ADDRESS)hwork, hNexist * sizeof(scmon)); |
---|
1297 | hDelete(hexist, hNexist); |
---|
1298 | if (hisModule!=0) |
---|
1299 | omFreeSize((ADDRESS)hstc, hNexist * sizeof(scmon)); |
---|
1300 | return hseries1; |
---|
1301 | } |
---|
1302 | |
---|
1303 | |
---|
1304 | intvec * hHstdSeries(ideal S, intvec *modulweight, intvec *wdegree, ideal Q, ring tailRing) |
---|
1305 | { |
---|
1306 | id_TestTail(S, currRing, tailRing); |
---|
1307 | if (Q!=NULL) id_TestTail(Q, currRing, tailRing); |
---|
1308 | return hSeries(S, modulweight, 0, wdegree, Q, tailRing); |
---|
1309 | } |
---|
1310 | |
---|
1311 | intvec * hFirstSeries(ideal S, intvec *modulweight, ideal Q, intvec *wdegree, ring tailRing) |
---|
1312 | { |
---|
1313 | id_TestTail(S, currRing, tailRing); |
---|
1314 | if (Q!= NULL) id_TestTail(Q, currRing, tailRing); |
---|
1315 | |
---|
1316 | return hSeries(S, modulweight, 1, wdegree, Q, tailRing); |
---|
1317 | } |
---|
1318 | |
---|
1319 | intvec * hSecondSeries(intvec *hseries1) |
---|
1320 | { |
---|
1321 | intvec *work, *hseries2; |
---|
1322 | int i, j, k, s, t, l; |
---|
1323 | if (hseries1 == NULL) |
---|
1324 | return NULL; |
---|
1325 | work = new intvec(hseries1); |
---|
1326 | k = l = work->length()-1; |
---|
1327 | s = 0; |
---|
1328 | for (i = k-1; i >= 0; i--) |
---|
1329 | s += (*work)[i]; |
---|
1330 | loop |
---|
1331 | { |
---|
1332 | if ((s != 0) || (k == 1)) |
---|
1333 | break; |
---|
1334 | s = 0; |
---|
1335 | t = (*work)[k-1]; |
---|
1336 | k--; |
---|
1337 | for (i = k-1; i >= 0; i--) |
---|
1338 | { |
---|
1339 | j = (*work)[i]; |
---|
1340 | (*work)[i] = -t; |
---|
1341 | s += t; |
---|
1342 | t += j; |
---|
1343 | } |
---|
1344 | } |
---|
1345 | hseries2 = new intvec(k+1); |
---|
1346 | for (i = k-1; i >= 0; i--) |
---|
1347 | (*hseries2)[i] = (*work)[i]; |
---|
1348 | (*hseries2)[k] = (*work)[l]; |
---|
1349 | delete work; |
---|
1350 | return hseries2; |
---|
1351 | } |
---|
1352 | |
---|
1353 | void hDegreeSeries(intvec *s1, intvec *s2, int *co, int *mu) |
---|
1354 | { |
---|
1355 | int m, i, j, k; |
---|
1356 | *co = *mu = 0; |
---|
1357 | if ((s1 == NULL) || (s2 == NULL)) |
---|
1358 | return; |
---|
1359 | i = s1->length(); |
---|
1360 | j = s2->length(); |
---|
1361 | if (j > i) |
---|
1362 | return; |
---|
1363 | m = 0; |
---|
1364 | for(k=j-2; k>=0; k--) |
---|
1365 | m += (*s2)[k]; |
---|
1366 | *mu = m; |
---|
1367 | *co = i - j; |
---|
1368 | } |
---|
1369 | |
---|
1370 | static void hPrintHilb(intvec *hseries) |
---|
1371 | { |
---|
1372 | int i, j, l, k; |
---|
1373 | if (hseries == NULL) |
---|
1374 | return; |
---|
1375 | l = hseries->length()-1; |
---|
1376 | k = (*hseries)[l]; |
---|
1377 | for (i = 0; i < l; i++) |
---|
1378 | { |
---|
1379 | j = (*hseries)[i]; |
---|
1380 | if (j != 0) |
---|
1381 | { |
---|
1382 | Print("// %8d t^%d\n", j, i+k); |
---|
1383 | } |
---|
1384 | } |
---|
1385 | } |
---|
1386 | |
---|
1387 | /* |
---|
1388 | *caller |
---|
1389 | */ |
---|
1390 | void hLookSeries(ideal S, intvec *modulweight, ideal Q, intvec *wdegree, ring tailRing) |
---|
1391 | { |
---|
1392 | id_TestTail(S, currRing, tailRing); |
---|
1393 | |
---|
1394 | intvec *hseries1 = hFirstSeries(S, modulweight, Q, wdegree, tailRing); |
---|
1395 | |
---|
1396 | hPrintHilb(hseries1); |
---|
1397 | |
---|
1398 | const int l = hseries1->length()-1; |
---|
1399 | |
---|
1400 | intvec *hseries2 = (l > 1) ? hSecondSeries(hseries1) : hseries1; |
---|
1401 | |
---|
1402 | int co, mu; |
---|
1403 | hDegreeSeries(hseries1, hseries2, &co, &mu); |
---|
1404 | |
---|
1405 | PrintLn(); |
---|
1406 | hPrintHilb(hseries2); |
---|
1407 | if ((l == 1) &&(mu == 0)) |
---|
1408 | scPrintDegree(rVar(currRing)+1, 0); |
---|
1409 | else |
---|
1410 | scPrintDegree(co, mu); |
---|
1411 | if (l>1) |
---|
1412 | delete hseries1; |
---|
1413 | delete hseries2; |
---|
1414 | } |
---|
1415 | |
---|
1416 | /*********************************************************************** |
---|
1417 | Computation of Hilbert series of non-commutative monomial algebras |
---|
1418 | ************************************************************************/ |
---|
1419 | |
---|
1420 | |
---|
1421 | static void idInsertMonomial(ideal I, poly p) |
---|
1422 | { |
---|
1423 | /* |
---|
1424 | * It adds monomial in I and if required, |
---|
1425 | * enlarge the size of poly-set by 16. |
---|
1426 | * It does not make copy of p. |
---|
1427 | */ |
---|
1428 | |
---|
1429 | if(I == NULL) |
---|
1430 | { |
---|
1431 | return; |
---|
1432 | } |
---|
1433 | |
---|
1434 | int j = IDELEMS(I) - 1; |
---|
1435 | while ((j >= 0) && (I->m[j] == NULL)) |
---|
1436 | { |
---|
1437 | j--; |
---|
1438 | } |
---|
1439 | j++; |
---|
1440 | if (j == IDELEMS(I)) |
---|
1441 | { |
---|
1442 | pEnlargeSet(&(I->m), IDELEMS(I), 16); |
---|
1443 | IDELEMS(I) +=16; |
---|
1444 | } |
---|
1445 | I->m[j] = p; |
---|
1446 | } |
---|
1447 | |
---|
1448 | static int comapreMonoIdBases(ideal J, ideal Ob) |
---|
1449 | { |
---|
1450 | /* |
---|
1451 | * Monomials of J and Ob are assumed to |
---|
1452 | * be already sorted. J and Ob are |
---|
1453 | * represented by the minimal generating set. |
---|
1454 | */ |
---|
1455 | int i, s; |
---|
1456 | s = 1; |
---|
1457 | int JCount = IDELEMS(J); |
---|
1458 | int ObCount = IDELEMS(Ob); |
---|
1459 | |
---|
1460 | if(idIs0(J)) |
---|
1461 | { |
---|
1462 | return(1); |
---|
1463 | } |
---|
1464 | if(JCount != ObCount) |
---|
1465 | { |
---|
1466 | return(0); |
---|
1467 | } |
---|
1468 | |
---|
1469 | for(i = 0; i < JCount; i++) |
---|
1470 | { |
---|
1471 | if(!(p_LmEqual(J->m[i], Ob->m[i], currRing))) |
---|
1472 | { |
---|
1473 | return(0); |
---|
1474 | } |
---|
1475 | } |
---|
1476 | return(s); |
---|
1477 | } |
---|
1478 | |
---|
1479 | static int CountOnIdUptoTruncationIndex(ideal I, int tr) |
---|
1480 | { |
---|
1481 | /* |
---|
1482 | * The ideal I must be sorted in increasing total degree. |
---|
1483 | * It counts the number of monomials in I up to |
---|
1484 | * degree less than or equal to tr. |
---|
1485 | */ |
---|
1486 | |
---|
1487 | //case when I=1; |
---|
1488 | if(p_Totaldegree(I->m[0], currRing) == 0) |
---|
1489 | { |
---|
1490 | return(1); |
---|
1491 | } |
---|
1492 | |
---|
1493 | int count = 0; |
---|
1494 | for(int i = 0; i < IDELEMS(I); i++) |
---|
1495 | { |
---|
1496 | if(p_Totaldegree(I->m[i], currRing) > tr) |
---|
1497 | { |
---|
1498 | return (count); |
---|
1499 | } |
---|
1500 | count = count + 1; |
---|
1501 | } |
---|
1502 | |
---|
1503 | return(count); |
---|
1504 | } |
---|
1505 | |
---|
1506 | static int comapreMonoIdBases_IG_Case(ideal J, int JCount, ideal Ob, int ObCount) |
---|
1507 | { |
---|
1508 | /* |
---|
1509 | * Monomials of J and Ob are assumed to |
---|
1510 | * be already sorted in increasing degrees. |
---|
1511 | * J and Ob are represented by the minimal |
---|
1512 | * generating set. It checks if J and Ob have |
---|
1513 | * same monomials up to deg <=tr. |
---|
1514 | */ |
---|
1515 | |
---|
1516 | int i, s; |
---|
1517 | s = 1; |
---|
1518 | //when J is null |
---|
1519 | // |
---|
1520 | if(JCount != ObCount) |
---|
1521 | { |
---|
1522 | return(0); |
---|
1523 | } |
---|
1524 | |
---|
1525 | if(JCount == 0) |
---|
1526 | { |
---|
1527 | return(1); |
---|
1528 | } |
---|
1529 | |
---|
1530 | for(i = 0; i< JCount; i++) |
---|
1531 | { |
---|
1532 | if(!(p_LmEqual(J->m[i], Ob->m[i], currRing))) |
---|
1533 | { |
---|
1534 | return(0); |
---|
1535 | } |
---|
1536 | } |
---|
1537 | |
---|
1538 | return(s); |
---|
1539 | } |
---|
1540 | |
---|
1541 | static int positionInOrbit_IG_Case(ideal I, poly w, std::vector<ideal> idorb, std::vector<poly> polist, int trInd, int trunDegHs) |
---|
1542 | { |
---|
1543 | /* |
---|
1544 | * It compares the ideal I with ideals in the set 'idorb' |
---|
1545 | * up to total degree = |
---|
1546 | * trInd - max(deg of w, deg of word in polist) polynomials. |
---|
1547 | * |
---|
1548 | * It returns 0 if I is not equal to any ideal in the |
---|
1549 | * 'idorb' else returns position of the matched ideal. |
---|
1550 | */ |
---|
1551 | |
---|
1552 | int ps = 0; |
---|
1553 | int i, s = 0; |
---|
1554 | int orbCount = idorb.size(); |
---|
1555 | |
---|
1556 | if(idIs0(I)) |
---|
1557 | { |
---|
1558 | return(1); |
---|
1559 | } |
---|
1560 | |
---|
1561 | int degw = p_Totaldegree(w, currRing); |
---|
1562 | int degp; |
---|
1563 | int dtr; |
---|
1564 | int dtrp; |
---|
1565 | |
---|
1566 | dtr = trInd - degw; |
---|
1567 | int IwCount; |
---|
1568 | |
---|
1569 | IwCount = CountOnIdUptoTruncationIndex(I, dtr); |
---|
1570 | |
---|
1571 | if(IwCount == 0) |
---|
1572 | { |
---|
1573 | return(1); |
---|
1574 | } |
---|
1575 | |
---|
1576 | int ObCount; |
---|
1577 | |
---|
1578 | bool flag2 = FALSE; |
---|
1579 | |
---|
1580 | for(i = 1;i < orbCount; i++) |
---|
1581 | { |
---|
1582 | degp = p_Totaldegree(polist[i], currRing); |
---|
1583 | if(degw > degp) |
---|
1584 | { |
---|
1585 | dtr = trInd - degw; |
---|
1586 | |
---|
1587 | ObCount = 0; |
---|
1588 | ObCount = CountOnIdUptoTruncationIndex(idorb[i], dtr); |
---|
1589 | if(ObCount == 0) |
---|
1590 | {continue;} |
---|
1591 | if(flag2) |
---|
1592 | { |
---|
1593 | IwCount = 0; |
---|
1594 | IwCount = CountOnIdUptoTruncationIndex(I, dtr); |
---|
1595 | flag2 = FALSE; |
---|
1596 | } |
---|
1597 | } |
---|
1598 | else |
---|
1599 | { |
---|
1600 | flag2 = TRUE; |
---|
1601 | dtrp = trInd - degp; |
---|
1602 | ObCount = 0; |
---|
1603 | ObCount = CountOnIdUptoTruncationIndex(idorb[i], dtrp); |
---|
1604 | IwCount = 0; |
---|
1605 | IwCount = CountOnIdUptoTruncationIndex(I, dtrp); |
---|
1606 | } |
---|
1607 | |
---|
1608 | s = comapreMonoIdBases_IG_Case(I, IwCount, idorb[i], ObCount); |
---|
1609 | |
---|
1610 | if(s) |
---|
1611 | { |
---|
1612 | ps = i + 1; |
---|
1613 | break; |
---|
1614 | } |
---|
1615 | } |
---|
1616 | return(ps); |
---|
1617 | } |
---|
1618 | |
---|
1619 | static int positionInOrbit_FG_Case(ideal I, poly, std::vector<ideal> idorb, std::vector<poly>, int, int) |
---|
1620 | { |
---|
1621 | /* |
---|
1622 | * It compares the ideal I with ideals in the set 'idorb'. |
---|
1623 | * I and ideals of 'idorb' are sorted. |
---|
1624 | * |
---|
1625 | * It returns 0 if I is not equal to any ideal of 'idorb' |
---|
1626 | * else returns position of the matched ideal. |
---|
1627 | */ |
---|
1628 | int ps = 0; |
---|
1629 | int i, s = 0; |
---|
1630 | int OrbCount = idorb.size(); |
---|
1631 | |
---|
1632 | if(idIs0(I)) |
---|
1633 | { |
---|
1634 | return(1); |
---|
1635 | } |
---|
1636 | |
---|
1637 | for(i = 1; i < OrbCount; i++) |
---|
1638 | { |
---|
1639 | s = comapreMonoIdBases(I, idorb[i]); |
---|
1640 | if(s) |
---|
1641 | { |
---|
1642 | ps = i + 1; |
---|
1643 | break; |
---|
1644 | } |
---|
1645 | } |
---|
1646 | |
---|
1647 | return(ps); |
---|
1648 | } |
---|
1649 | |
---|
1650 | static int positionInOrbitTruncationCase(ideal I, poly w, std::vector<ideal> idorb, std::vector<poly> polist, int , int trunDegHs) |
---|
1651 | { |
---|
1652 | /* |
---|
1653 | * It compares the ideal I with ideals in the set 'idorb'. |
---|
1654 | * I and ideals in 'idorb' are sorted. |
---|
1655 | |
---|
1656 | * returns 0 if I is not equal to any ideal of 'idorb' |
---|
1657 | * else returns position of the matched ideal. |
---|
1658 | */ |
---|
1659 | |
---|
1660 | int ps = 0; |
---|
1661 | int i, s = 0; |
---|
1662 | int OrbCount = idorb.size(); |
---|
1663 | int dtr=0; int IwCount, ObCount; |
---|
1664 | dtr = trunDegHs - 1 - p_Totaldegree(w, currRing); |
---|
1665 | |
---|
1666 | if(idIs0(I)) |
---|
1667 | { |
---|
1668 | for(i = 1; i < OrbCount; i++) |
---|
1669 | { |
---|
1670 | if(p_Totaldegree(w, currRing) == p_Totaldegree(polist[i], currRing)) |
---|
1671 | { |
---|
1672 | if(idIs0(idorb[i])) |
---|
1673 | return(i+1); |
---|
1674 | ObCount=0; |
---|
1675 | ObCount = CountOnIdUptoTruncationIndex(idorb[i], dtr); |
---|
1676 | if(ObCount==0) |
---|
1677 | { |
---|
1678 | ps = i + 1; |
---|
1679 | break; |
---|
1680 | } |
---|
1681 | } |
---|
1682 | } |
---|
1683 | |
---|
1684 | return(ps); |
---|
1685 | } |
---|
1686 | |
---|
1687 | IwCount = CountOnIdUptoTruncationIndex(I, dtr); |
---|
1688 | |
---|
1689 | if(p_Totaldegree(I->m[0], currRing)==0) |
---|
1690 | { |
---|
1691 | for(i = 1; i < OrbCount; i++) |
---|
1692 | { |
---|
1693 | if(idIs0(idorb[i])) |
---|
1694 | continue; |
---|
1695 | if(p_Totaldegree(idorb[i]->m[0], currRing)==0) |
---|
1696 | { |
---|
1697 | ps = i + 1; |
---|
1698 | break; |
---|
1699 | } |
---|
1700 | } |
---|
1701 | return(ps); |
---|
1702 | } |
---|
1703 | |
---|
1704 | for(i = 1; i < OrbCount; i++) |
---|
1705 | { |
---|
1706 | if(p_Totaldegree(w, currRing) == p_Totaldegree(polist[i], currRing)) |
---|
1707 | { |
---|
1708 | if(idIs0(idorb[i])) |
---|
1709 | continue; |
---|
1710 | ObCount=0; |
---|
1711 | ObCount = CountOnIdUptoTruncationIndex(idorb[i], dtr); |
---|
1712 | s = comapreMonoIdBases_IG_Case(I, IwCount, idorb[i], ObCount); |
---|
1713 | if(s) |
---|
1714 | { |
---|
1715 | ps = i + 1; |
---|
1716 | break; |
---|
1717 | } |
---|
1718 | } |
---|
1719 | } |
---|
1720 | |
---|
1721 | return(ps); |
---|
1722 | } |
---|
1723 | |
---|
1724 | static int monCompare( const void *m, const void *n) |
---|
1725 | { |
---|
1726 | /* compares monomials */ |
---|
1727 | |
---|
1728 | return(p_Compare(*(poly*) m, *(poly*)n, currRing)); |
---|
1729 | } |
---|
1730 | |
---|
1731 | void sortMonoIdeal_pCompare(ideal I) |
---|
1732 | { |
---|
1733 | /* |
---|
1734 | * sorts monomial ideal in ascending order |
---|
1735 | * order must be a total degree |
---|
1736 | */ |
---|
1737 | |
---|
1738 | qsort(I->m, IDELEMS(I), sizeof(poly), monCompare); |
---|
1739 | |
---|
1740 | } |
---|
1741 | |
---|
1742 | |
---|
1743 | |
---|
1744 | static ideal minimalMonomialGenSet(ideal I) |
---|
1745 | { |
---|
1746 | /* |
---|
1747 | * eliminates monomials which |
---|
1748 | * can be generated by others in I |
---|
1749 | */ |
---|
1750 | //first sort monomials of the ideal |
---|
1751 | |
---|
1752 | idSkipZeroes(I); |
---|
1753 | |
---|
1754 | sortMonoIdeal_pCompare(I); |
---|
1755 | |
---|
1756 | int i, k; |
---|
1757 | int ICount = IDELEMS(I); |
---|
1758 | |
---|
1759 | for(k = ICount - 1; k >=1; k--) |
---|
1760 | { |
---|
1761 | for(i = 0; i < k; i++) |
---|
1762 | { |
---|
1763 | |
---|
1764 | if(p_LmDivisibleBy(I->m[i], I->m[k], currRing)) |
---|
1765 | { |
---|
1766 | pDelete(&(I->m[k])); |
---|
1767 | break; |
---|
1768 | } |
---|
1769 | } |
---|
1770 | } |
---|
1771 | |
---|
1772 | idSkipZeroes(I); |
---|
1773 | return(I); |
---|
1774 | } |
---|
1775 | |
---|
1776 | static poly shiftInMon(poly p, int i, int lV, const ring r) |
---|
1777 | { |
---|
1778 | /* |
---|
1779 | * shifts the varibles of monomial p in the i^th layer, |
---|
1780 | * p remains unchanged, |
---|
1781 | * creates new poly and returns it for the colon ideal |
---|
1782 | */ |
---|
1783 | poly smon = p_One(r); |
---|
1784 | int j, sh, cnt; |
---|
1785 | cnt = r->N; |
---|
1786 | sh = i*lV; |
---|
1787 | int *e=(int *)omAlloc((r->N+1)*sizeof(int)); |
---|
1788 | int *s=(int *)omAlloc0((r->N+1)*sizeof(int)); |
---|
1789 | p_GetExpV(p, e, r); |
---|
1790 | |
---|
1791 | for(j = 1; j <= cnt; j++) |
---|
1792 | { |
---|
1793 | if(e[j] == 1) |
---|
1794 | { |
---|
1795 | s[j+sh] = e[j]; |
---|
1796 | } |
---|
1797 | } |
---|
1798 | |
---|
1799 | p_SetExpV(smon, s, currRing); |
---|
1800 | omFree(e); |
---|
1801 | omFree(s); |
---|
1802 | |
---|
1803 | p_SetComp(smon, p_GetComp(p, currRing), currRing); |
---|
1804 | p_Setm(smon, currRing); |
---|
1805 | |
---|
1806 | return(smon); |
---|
1807 | } |
---|
1808 | |
---|
1809 | static poly deleteInMon(poly w, int i, int lV, const ring r) |
---|
1810 | { |
---|
1811 | /* |
---|
1812 | * deletes the variables upto i^th layer of monomial w |
---|
1813 | * w remains unchanged |
---|
1814 | * creates new poly and returns it for the colon ideal |
---|
1815 | */ |
---|
1816 | |
---|
1817 | poly dw = p_One(currRing); |
---|
1818 | int *e = (int *)omAlloc((r->N+1)*sizeof(int)); |
---|
1819 | int *s=(int *)omAlloc0((r->N+1)*sizeof(int)); |
---|
1820 | p_GetExpV(w, e, r); |
---|
1821 | int j, cnt; |
---|
1822 | cnt = i*lV; |
---|
1823 | /* |
---|
1824 | for(j=1;j<=cnt;j++) |
---|
1825 | { |
---|
1826 | e[j]=0; |
---|
1827 | }*/ |
---|
1828 | for(j = (cnt+1); j < (r->N+1); j++) |
---|
1829 | { |
---|
1830 | s[j] = e[j]; |
---|
1831 | } |
---|
1832 | |
---|
1833 | p_SetExpV(dw, s, currRing);//new exponents |
---|
1834 | omFree(e); |
---|
1835 | omFree(s); |
---|
1836 | |
---|
1837 | p_SetComp(dw, p_GetComp(w, currRing), currRing); |
---|
1838 | p_Setm(dw, currRing); |
---|
1839 | |
---|
1840 | return(dw); |
---|
1841 | } |
---|
1842 | |
---|
1843 | static void TwordMap(poly p, poly w, int lV, int d, ideal Jwi, bool &flag) |
---|
1844 | { |
---|
1845 | /* |
---|
1846 | * computes T_w(p) in a new poly object and places it |
---|
1847 | * in Jwi which stores elements of colon ideal of I, |
---|
1848 | * p and w remain unchanged, |
---|
1849 | * the new polys for Jwi are constructed by sub-routines |
---|
1850 | * deleteInMon, shiftInMon, p_MDivide, |
---|
1851 | * places the result in Jwi and deletes the new polys |
---|
1852 | * coming in dw, smon, qmon |
---|
1853 | */ |
---|
1854 | int i; |
---|
1855 | poly smon, dw; |
---|
1856 | poly qmonp = NULL; |
---|
1857 | bool del; |
---|
1858 | |
---|
1859 | for(i = 0;i <= d - 1; i++) |
---|
1860 | { |
---|
1861 | dw = deleteInMon(w, i, lV, currRing); |
---|
1862 | smon = shiftInMon(p, i, lV, currRing); |
---|
1863 | del = TRUE; |
---|
1864 | |
---|
1865 | if(pLmDivisibleBy(smon, w)) |
---|
1866 | { |
---|
1867 | flag = TRUE; |
---|
1868 | del = FALSE; |
---|
1869 | |
---|
1870 | pDelete(&dw); |
---|
1871 | pDelete(&smon); |
---|
1872 | |
---|
1873 | //delete all monomials of Jwi |
---|
1874 | //and make Jwi =1 |
---|
1875 | |
---|
1876 | for(int j = 0;j < IDELEMS(Jwi); j++) |
---|
1877 | { |
---|
1878 | pDelete(&Jwi->m[j]); |
---|
1879 | } |
---|
1880 | |
---|
1881 | idInsertMonomial(Jwi, p_One(currRing)); |
---|
1882 | break; |
---|
1883 | } |
---|
1884 | |
---|
1885 | if(pLmDivisibleBy(dw, smon)) |
---|
1886 | { |
---|
1887 | del = FALSE; |
---|
1888 | qmonp = p_MDivide(smon, dw, currRing); |
---|
1889 | idInsertMonomial(Jwi, shiftInMon(qmonp, -d, lV, currRing)); |
---|
1890 | pLmFree(&qmonp); |
---|
1891 | pDelete(&dw); |
---|
1892 | pDelete(&smon); |
---|
1893 | } |
---|
1894 | //in case both if are false, delete dw and smon |
---|
1895 | if(del) |
---|
1896 | { |
---|
1897 | pDelete(&dw); |
---|
1898 | pDelete(&smon); |
---|
1899 | } |
---|
1900 | } |
---|
1901 | |
---|
1902 | } |
---|
1903 | |
---|
1904 | static ideal colonIdeal(ideal S, poly w, int lV, ideal Jwi, int trunDegHs) |
---|
1905 | { |
---|
1906 | /* |
---|
1907 | * It computes the right colon ideal of a two-sided ideal S |
---|
1908 | * w.r.t. word w and save it in a new object Jwi. |
---|
1909 | * It keeps S and w unchanged. |
---|
1910 | */ |
---|
1911 | |
---|
1912 | if(idIs0(S)) |
---|
1913 | { |
---|
1914 | return(S); |
---|
1915 | } |
---|
1916 | |
---|
1917 | int i, d; |
---|
1918 | d = p_Totaldegree(w, currRing); |
---|
1919 | if(trunDegHs !=0 && d >= trunDegHs) |
---|
1920 | { |
---|
1921 | idInsertMonomial(Jwi, p_One(currRing)); |
---|
1922 | return(Jwi); |
---|
1923 | } |
---|
1924 | bool flag = FALSE; |
---|
1925 | int SCount = IDELEMS(S); |
---|
1926 | for(i = 0; i < SCount; i++) |
---|
1927 | { |
---|
1928 | TwordMap(S->m[i], w, lV, d, Jwi, flag); |
---|
1929 | if(flag) |
---|
1930 | { |
---|
1931 | break; |
---|
1932 | } |
---|
1933 | } |
---|
1934 | |
---|
1935 | Jwi = minimalMonomialGenSet(Jwi); |
---|
1936 | return(Jwi); |
---|
1937 | } |
---|
1938 | |
---|
1939 | void HilbertSeries_OrbitData(ideal S, int lV, bool IG_CASE, bool mgrad, bool odp, int trunDegHs) |
---|
1940 | { |
---|
1941 | /* |
---|
1942 | * This is based on iterative right colon operations on a |
---|
1943 | * two-sided monomial ideal of the free associative algebra. |
---|
1944 | * The algorithm terminates for those monomial ideals |
---|
1945 | * whose monomials define "regular formal languages", |
---|
1946 | * that is, all monomials of the input ideal can be obtained |
---|
1947 | * from finite languages by applying finite number of |
---|
1948 | * rational operations. |
---|
1949 | */ |
---|
1950 | |
---|
1951 | int trInd; |
---|
1952 | S = minimalMonomialGenSet(S); |
---|
1953 | if( !idIs0(S) && p_Totaldegree(S->m[0], currRing)==0) |
---|
1954 | { |
---|
1955 | PrintS("Hilbert Series:\n 0\n"); |
---|
1956 | return; |
---|
1957 | } |
---|
1958 | int (*POS)(ideal, poly, std::vector<ideal>, std::vector<poly>, int, int); |
---|
1959 | if(trunDegHs != 0) |
---|
1960 | { |
---|
1961 | Print("\nTruncation degree = %d\n",trunDegHs); |
---|
1962 | POS=&positionInOrbitTruncationCase; |
---|
1963 | } |
---|
1964 | else |
---|
1965 | { |
---|
1966 | if(IG_CASE) |
---|
1967 | { |
---|
1968 | if(idIs0(S)) |
---|
1969 | { |
---|
1970 | WerrorS("wrong input: it is not an infinitely gen. case"); |
---|
1971 | return; |
---|
1972 | } |
---|
1973 | trInd = p_Totaldegree(S->m[IDELEMS(S)-1], currRing); |
---|
1974 | POS = &positionInOrbit_IG_Case; |
---|
1975 | } |
---|
1976 | else |
---|
1977 | POS = &positionInOrbit_FG_Case; |
---|
1978 | } |
---|
1979 | std::vector<ideal > idorb; |
---|
1980 | std::vector< poly > polist; |
---|
1981 | |
---|
1982 | ideal orb_init = idInit(1, 1); |
---|
1983 | idorb.push_back(orb_init); |
---|
1984 | |
---|
1985 | polist.push_back( p_One(currRing)); |
---|
1986 | |
---|
1987 | std::vector< std::vector<int> > posMat; |
---|
1988 | std::vector<int> posRow(lV,0); |
---|
1989 | std::vector<int> C; |
---|
1990 | |
---|
1991 | int ds, is, ps; |
---|
1992 | int lpcnt = 0; |
---|
1993 | |
---|
1994 | poly w, wi; |
---|
1995 | ideal Jwi; |
---|
1996 | |
---|
1997 | while(lpcnt < idorb.size()) |
---|
1998 | { |
---|
1999 | w = NULL; |
---|
2000 | w = polist[lpcnt]; |
---|
2001 | if(lpcnt >= 1 && idIs0(idorb[lpcnt]) == FALSE) |
---|
2002 | { |
---|
2003 | if(p_Totaldegree(idorb[lpcnt]->m[0], currRing) != 0) |
---|
2004 | { |
---|
2005 | C.push_back(1); |
---|
2006 | } |
---|
2007 | else |
---|
2008 | C.push_back(0); |
---|
2009 | } |
---|
2010 | else |
---|
2011 | { |
---|
2012 | C.push_back(1); |
---|
2013 | } |
---|
2014 | |
---|
2015 | ds = p_Totaldegree(w, currRing); |
---|
2016 | lpcnt++; |
---|
2017 | |
---|
2018 | for(is = 1; is <= lV; is++) |
---|
2019 | { |
---|
2020 | wi = NULL; |
---|
2021 | //make new copy 'wi' of word w=polist[lpcnt] |
---|
2022 | //and update it (for the colon operation). |
---|
2023 | //if corresponding to wi, right colon operation gives |
---|
2024 | //a new (right colon) ideal of S, |
---|
2025 | //keep 'wi' in the polist else delete it |
---|
2026 | |
---|
2027 | wi = pCopy(w); |
---|
2028 | p_SetExp(wi, (ds*lV)+is, 1, currRing); |
---|
2029 | p_Setm(wi, currRing); |
---|
2030 | Jwi = NULL; |
---|
2031 | //Jwi stores (right) colon ideal of S w.r.t. word |
---|
2032 | //wi if colon operation gives a new ideal place it |
---|
2033 | //in the vector of ideals 'idorb' |
---|
2034 | //otherwise delete it |
---|
2035 | |
---|
2036 | Jwi = idInit(1,1); |
---|
2037 | |
---|
2038 | Jwi = colonIdeal(S, wi, lV, Jwi, trunDegHs); |
---|
2039 | ps = (*POS)(Jwi, wi, idorb, polist, trInd, trunDegHs); |
---|
2040 | |
---|
2041 | if(ps == 0) // finds a new ideal |
---|
2042 | { |
---|
2043 | posRow[is-1] = idorb.size(); |
---|
2044 | |
---|
2045 | idorb.push_back(Jwi); |
---|
2046 | polist.push_back(wi); |
---|
2047 | } |
---|
2048 | else // ideal is already there in the set |
---|
2049 | { |
---|
2050 | posRow[is-1]=ps-1; |
---|
2051 | idDelete(&Jwi); |
---|
2052 | pDelete(&wi); |
---|
2053 | } |
---|
2054 | } |
---|
2055 | posMat.push_back(posRow); |
---|
2056 | posRow.resize(lV,0); |
---|
2057 | } |
---|
2058 | int lO = C.size();//size of the orbit |
---|
2059 | PrintLn(); |
---|
2060 | Print("maximal length of words = %ld\n", p_Totaldegree(polist[lO-1], currRing)); |
---|
2061 | Print("\nlength of the Orbit = %d", lO); |
---|
2062 | PrintLn(); |
---|
2063 | |
---|
2064 | if(odp) |
---|
2065 | { |
---|
2066 | Print("words description of the Orbit: \n"); |
---|
2067 | for(is = 0; is < lO; is++) |
---|
2068 | { |
---|
2069 | pWrite0(polist[is]); |
---|
2070 | PrintS(" "); |
---|
2071 | } |
---|
2072 | PrintLn(); |
---|
2073 | PrintS("\nmaximal degree, #(sum_j R(w,w_j))"); |
---|
2074 | PrintLn(); |
---|
2075 | for(is = 0; is < lO; is++) |
---|
2076 | { |
---|
2077 | if(idIs0(idorb[is])) |
---|
2078 | { |
---|
2079 | PrintS("NULL\n"); |
---|
2080 | } |
---|
2081 | else |
---|
2082 | { |
---|
2083 | Print("%ld, %d \n",p_Totaldegree(idorb[is]->m[IDELEMS(idorb[is])-1], currRing),IDELEMS(idorb[is])); |
---|
2084 | } |
---|
2085 | } |
---|
2086 | } |
---|
2087 | |
---|
2088 | for(is = idorb.size()-1; is >= 0; is--) |
---|
2089 | { |
---|
2090 | idDelete(&idorb[is]); |
---|
2091 | } |
---|
2092 | for(is = polist.size()-1; is >= 0; is--) |
---|
2093 | { |
---|
2094 | pDelete(&polist[is]); |
---|
2095 | } |
---|
2096 | |
---|
2097 | idorb.resize(0); |
---|
2098 | polist.resize(0); |
---|
2099 | |
---|
2100 | int adjMatrix[lO][lO]; |
---|
2101 | memset(adjMatrix, 0, lO*lO*sizeof(int)); |
---|
2102 | int rowCount, colCount; |
---|
2103 | int tm = 0; |
---|
2104 | if(!mgrad) |
---|
2105 | { |
---|
2106 | for(rowCount = 0; rowCount < lO; rowCount++) |
---|
2107 | { |
---|
2108 | for(colCount = 0; colCount < lV; colCount++) |
---|
2109 | { |
---|
2110 | tm = posMat[rowCount][colCount]; |
---|
2111 | adjMatrix[rowCount][tm] = adjMatrix[rowCount][tm] + 1; |
---|
2112 | } |
---|
2113 | } |
---|
2114 | } |
---|
2115 | |
---|
2116 | ring r = currRing; |
---|
2117 | int npar; |
---|
2118 | char** tt; |
---|
2119 | TransExtInfo p; |
---|
2120 | if(!mgrad) |
---|
2121 | { |
---|
2122 | tt=(char**)omalloc(sizeof(char*)); |
---|
2123 | tt[0] = omStrDup("t"); |
---|
2124 | npar = 1; |
---|
2125 | } |
---|
2126 | else |
---|
2127 | { |
---|
2128 | tt=(char**)omalloc(lV*sizeof(char*)); |
---|
2129 | for(is = 0; is < lV; is++) |
---|
2130 | { |
---|
2131 | tt[is] = (char*)omalloc(7*sizeof(char)); //if required enlarge it later |
---|
2132 | sprintf (tt[is], "t%d", is+1); |
---|
2133 | } |
---|
2134 | npar = lV; |
---|
2135 | } |
---|
2136 | |
---|
2137 | p.r = rDefault(0, npar, tt); |
---|
2138 | coeffs cf = nInitChar(n_transExt, &p); |
---|
2139 | char** xx = (char**)omalloc(sizeof(char*)); |
---|
2140 | xx[0] = omStrDup("x"); |
---|
2141 | ring R = rDefault(cf, 1, xx); |
---|
2142 | rChangeCurrRing(R);//rWrite(R); |
---|
2143 | /* |
---|
2144 | * matrix corresponding to the orbit of the ideal |
---|
2145 | */ |
---|
2146 | matrix mR = mpNew(lO, lO); |
---|
2147 | matrix cMat = mpNew(lO,1); |
---|
2148 | poly rc; |
---|
2149 | |
---|
2150 | if(!mgrad) |
---|
2151 | { |
---|
2152 | for(rowCount = 0; rowCount < lO; rowCount++) |
---|
2153 | { |
---|
2154 | for(colCount = 0; colCount < lO; colCount++) |
---|
2155 | { |
---|
2156 | if(adjMatrix[rowCount][colCount] != 0) |
---|
2157 | { |
---|
2158 | MATELEM(mR, rowCount + 1, colCount + 1) = p_ISet(adjMatrix[rowCount][colCount], R); |
---|
2159 | p_SetCoeff(MATELEM(mR, rowCount + 1, colCount + 1), n_Mult(pGetCoeff(mR->m[lO*rowCount+colCount]),n_Param(1, R->cf), R->cf), R); |
---|
2160 | } |
---|
2161 | } |
---|
2162 | } |
---|
2163 | } |
---|
2164 | else |
---|
2165 | { |
---|
2166 | for(rowCount = 0; rowCount < lO; rowCount++) |
---|
2167 | { |
---|
2168 | for(colCount = 0; colCount < lV; colCount++) |
---|
2169 | { |
---|
2170 | rc=NULL; |
---|
2171 | rc=p_One(R); |
---|
2172 | p_SetCoeff(rc, n_Mult(pGetCoeff(rc), n_Param(colCount+1, R->cf),R->cf), R); |
---|
2173 | MATELEM(mR, rowCount +1, posMat[rowCount][colCount]+1)=p_Add_q(rc,MATELEM(mR, rowCount +1, posMat[rowCount][colCount]+1), R); |
---|
2174 | } |
---|
2175 | } |
---|
2176 | } |
---|
2177 | |
---|
2178 | for(rowCount = 0; rowCount < lO; rowCount++) |
---|
2179 | { |
---|
2180 | if(C[rowCount] != 0) |
---|
2181 | { |
---|
2182 | MATELEM(cMat, rowCount + 1, 1) = p_ISet(C[rowCount], R); |
---|
2183 | } |
---|
2184 | } |
---|
2185 | |
---|
2186 | matrix u; |
---|
2187 | unitMatrix(lO, u); //unit matrix |
---|
2188 | matrix gMat = mp_Sub(u, mR, R); |
---|
2189 | |
---|
2190 | char* s; |
---|
2191 | |
---|
2192 | if(odp) |
---|
2193 | { |
---|
2194 | PrintS("\nlinear system:\n"); |
---|
2195 | if(!mgrad) |
---|
2196 | { |
---|
2197 | for(rowCount = 0; rowCount < lO; rowCount++) |
---|
2198 | { |
---|
2199 | Print("H(%d) = ", rowCount+1); |
---|
2200 | for(colCount = 0; colCount < lV; colCount++) |
---|
2201 | { |
---|
2202 | StringSetS(""); nWrite(n_Param(1, R->cf)); |
---|
2203 | s = StringEndS(); PrintS(s); |
---|
2204 | Print("*"); omFree(s); |
---|
2205 | Print("H(%d) + ", posMat[rowCount][colCount] + 1); |
---|
2206 | } |
---|
2207 | Print(" %d\n", C[rowCount] ); |
---|
2208 | } |
---|
2209 | PrintS("where H(1) represents the series corresp. to input ideal\n"); |
---|
2210 | PrintS("and i^th summand in the rhs of an eqn. is according\n"); |
---|
2211 | PrintS("to the right colon map corresp. to the i^th variable\n"); |
---|
2212 | } |
---|
2213 | else |
---|
2214 | { |
---|
2215 | for(rowCount = 0; rowCount < lO; rowCount++) |
---|
2216 | { |
---|
2217 | Print("H(%d) = ", rowCount+1); |
---|
2218 | for(colCount = 0; colCount < lV; colCount++) |
---|
2219 | { |
---|
2220 | StringSetS(""); nWrite(n_Param(colCount+1, R->cf)); |
---|
2221 | s = StringEndS(); PrintS(s); |
---|
2222 | Print("*");omFree(s); |
---|
2223 | Print("H(%d) + ", posMat[rowCount][colCount] + 1); |
---|
2224 | } |
---|
2225 | Print(" %d\n", C[rowCount] ); |
---|
2226 | } |
---|
2227 | PrintS("where H(1) represents the series corresp. to input ideal\n"); |
---|
2228 | } |
---|
2229 | } |
---|
2230 | PrintLn(); |
---|
2231 | posMat.resize(0); |
---|
2232 | C.resize(0); |
---|
2233 | matrix pMat; |
---|
2234 | matrix lMat; |
---|
2235 | matrix uMat; |
---|
2236 | matrix H_serVec = mpNew(lO, 1); |
---|
2237 | matrix Hnot; |
---|
2238 | |
---|
2239 | //std::clock_t start; |
---|
2240 | //start = std::clock(); |
---|
2241 | |
---|
2242 | luDecomp(gMat, pMat, lMat, uMat, R); |
---|
2243 | luSolveViaLUDecomp(pMat, lMat, uMat, cMat, H_serVec, Hnot); |
---|
2244 | |
---|
2245 | //to print system solving time |
---|
2246 | //if(odp){ |
---|
2247 | //std::cout<<"solving time of the system = "<<(std::clock()-start)/(double)(CLOCKS_PER_SEC / 1000)<<" ms"<<std::endl;} |
---|
2248 | |
---|
2249 | mp_Delete(&mR, R); |
---|
2250 | mp_Delete(&u, R); |
---|
2251 | mp_Delete(&pMat, R); |
---|
2252 | mp_Delete(&lMat, R); |
---|
2253 | mp_Delete(&uMat, R); |
---|
2254 | mp_Delete(&cMat, R); |
---|
2255 | mp_Delete(&gMat, R); |
---|
2256 | mp_Delete(&Hnot, R); |
---|
2257 | //print the Hilbert series and length of the Orbit |
---|
2258 | PrintLn(); |
---|
2259 | Print("Hilbert series:"); |
---|
2260 | PrintLn(); |
---|
2261 | pWrite(H_serVec->m[0]); |
---|
2262 | if(!mgrad) |
---|
2263 | { |
---|
2264 | omFree(tt[0]); |
---|
2265 | } |
---|
2266 | else |
---|
2267 | { |
---|
2268 | for(is = lV-1; is >= 0; is--) |
---|
2269 | |
---|
2270 | omFree( tt[is]); |
---|
2271 | } |
---|
2272 | omFree(tt); |
---|
2273 | omFree(xx[0]); |
---|
2274 | omFree(xx); |
---|
2275 | rChangeCurrRing(r); |
---|
2276 | rKill(R); |
---|
2277 | } |
---|
2278 | |
---|
2279 | ideal RightColonOperation(ideal S, poly w, int lV) |
---|
2280 | { |
---|
2281 | /* |
---|
2282 | * This returns right colon ideal of a monomial two-sided ideal of |
---|
2283 | * the free associative algebra with respect to a monomial 'w' |
---|
2284 | * (S:_R w). |
---|
2285 | */ |
---|
2286 | S = minimalMonomialGenSet(S); |
---|
2287 | ideal Iw = idInit(1,1); |
---|
2288 | Iw = colonIdeal(S, w, lV, Iw, 0); |
---|
2289 | return (Iw); |
---|
2290 | } |
---|
2291 | |
---|