source: git/Singular/LIB/modstd.lib @ a2e51b

spielwiese
Last change on this file since a2e51b was a2e51b, checked in by Andreas Steenpass <steenpass@…>, 10 years ago
base modstd.lib on modular.lib (cherry picked from commit 5ec123fda2041b4cace52475654a231bc4c8adaa) Signed-off-by: Andreas Steenpass <steenpass@mathematik.uni-kl.de> Conflicts: Singular/LIB/modstd.lib
  • Property mode set to 100644
File size: 10.2 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2version="version modstd.lib 4.0.0.0 May_2014 "; // $Id$
3category="Commutative Algebra";
4info="
5LIBRARY:  modstd.lib      Groebner bases of ideals using modular methods
6
7AUTHORS:  A. Hashemi      Amir.Hashemi@lip6.fr
8          G. Pfister      pfister@mathematik.uni-kl.de
9          H. Schoenemann  hannes@mathematik.uni-kl.de
10          A. Steenpass    steenpass@mathematik.uni-kl.de
11          S. Steidel      steidel@mathematik.uni-kl.de
12
13OVERVIEW:
14  A library for computing Groebner bases of ideals in the polynomial ring over
15  the rational numbers using modular methods.
16
17REFERENCES:
18  E. A. Arnold: Modular algorithms for computing Groebner bases.
19  J. Symb. Comp. 35, 403-419 (2003).
20
21  N. Idrees, G. Pfister, S. Steidel: Parallelization of Modular Algorithms.
22  J. Symb. Comp. 46, 672-684 (2011).
23
24PROCEDURES:
25  modStd(I);    standard basis of I using modular methods
26";
27
28LIB "poly.lib";
29LIB "modular.lib";
30
31proc modStd(ideal I, list #)
32"USAGE:   modStd(I[, exactness]); I ideal, exactness int
33RETURN:   a standard basis of I
34NOTE:     The procedure computes a standard basis of I (over the rational
35          numbers) by using modular methods.
36       @* An optional parameter 'exactness' can be provided.
37          If exactness = 1, the procedure computes a standard basis of I for
38          sure; if exactness = 0, it computes a standard basis of I
39          with high probability.
40SEE ALSO: modular
41EXAMPLE:  example modStd; shows an example"
42{
43    /* read optional parameter */
44    int exactness = 1;
45    if (size(#) > 0) {
46        /* For compatibility, we only test size(#) > 4. This can be changed to
47         * size(#) > 1 in the future. */
48        if (size(#) > 4 || typeof(#[1]) != "int") {
49            ERROR("wrong optional parameter");
50        }
51        exactness = #[1];
52    }
53
54    /* save options */
55    intvec opt = option(get);
56    option(redSB);
57
58    /* choose the right command */
59    string command = "groebner";
60    if (npars(basering) > 0) {
61        command = "Modstd::groebner_norm";
62    }
63
64    /* call modular() */
65    if (exactness) {
66        I = modular(command, list(I), primeTest_std,
67            deleteUnluckyPrimes_std, pTest_std, finalTest_std);
68    }
69    else {
70        I = modular(command, list(I), primeTest_std,
71            deleteUnluckyPrimes_std, pTest_std);
72    }
73
74    /* return the result */
75    attrib(I, "isSB", 1);
76    option(set, opt);
77    return(I);
78}
79example
80{
81    "EXAMPLE:";
82    echo = 2;
83    ring R1 = 0, (x,y,z,t), dp;
84    ideal I = 3x3+x2+1, 11y5+y3+2, 5z4+z2+4;
85    ideal J = modStd(I);
86    J;
87    I = homog(I, t);
88    J = modStd(I);
89    J;
90
91    ring R2 = 0, (x,y,z), ds;
92    ideal I = jacob(x5+y6+z7+xyz);
93    ideal J = modStd(I, 0);
94    J;
95
96    ring R3 = 0, x(1..4), lp;
97    ideal I = cyclic(4);
98    ideal J1 = modStd(I, 1);   // default
99    ideal J2 = modStd(I, 0);
100    size(reduce(J1, J2));
101    size(reduce(J2, J1));
102}
103
104/* compute a normalized GB via groebner() */
105static proc groebner_norm(ideal I)
106{
107    I = simplify(groebner(I), 1);
108    attrib(I, "isSB", 1);
109    return(I);
110}
111
112/* test if the prime p is suitable for the input, i.e. it does not divide
113 * the numerator or denominator of any of the coefficients */
114static proc primeTest_std(int p, alias list args)
115{
116    /* erase zero generators */
117    ideal I = simplify(args[1], 2);
118
119    /* clear denominators and count the terms */
120    ideal J;
121    ideal K;
122    int n = ncols(I);
123    intvec sizes;
124    number cnt;
125    int i;
126    for(i = n; i > 0; i--) {
127        J[i] = cleardenom(I[i]);
128        cnt = leadcoef(J[i])/leadcoef(I[i]);
129        K[i] = numerator(cnt)*var(1)+denominator(cnt);
130    }
131    sizes = size(J[1..n]);
132
133    /* change to characteristic p */
134    def br = basering;
135    list lbr = ringlist(br);
136    if (typeof(lbr[1]) == "int") {
137        lbr[1] = p;
138    }
139    else {
140        lbr[1][1] = p;
141    }
142    def rp = ring(lbr);
143    setring(rp);
144    ideal Jp = fetch(br, J);
145    ideal Kp = fetch(br, K);
146
147    /* test if any coefficient is missing */
148    if (intvec(size(Kp[1..n])) != 2:n) {
149        setring(br);
150        return(0);
151    }
152    if (intvec(size(Jp[1..n])) != sizes) {
153        setring(br);
154        return(0);
155    }
156    setring(br);
157    return(1);
158}
159
160/* find entries in modresults which come from unlucky primes.
161 * For this, sort the entries into categories depending on their leading
162 * ideal and return the indices in all but the biggest category. */
163static proc deleteUnluckyPrimes_std(alias list modresults)
164{
165    int size_modresults = size(modresults);
166
167    /* sort results into categories.
168     * each category is represented by three entries:
169     * - the corresponding leading ideal
170     * - the number of elements
171     * - the indices of the elements
172     */
173    list cat;
174    int size_cat;
175    ideal L;
176    int i;
177    int j;
178    for (i = 1; i <= size_modresults; i++) {
179        L = lead(modresults[i]);
180        attrib(L, "isSB", 1);
181        for (j = 1; j <= size_cat; j++) {
182            if (size(L) == size(cat[j][1])
183                && size(reduce(L, cat[j][1])) == 0
184                && size(reduce(cat[j][1], L)) == 0) {
185                cat[j][2] = cat[j][2]+1;
186                cat[j][3][cat[j][2]] = i;
187                break;
188            }
189        }
190        if (j > size_cat) {
191            size_cat++;
192            cat[size_cat] = list();
193            cat[size_cat][1] = L;
194            cat[size_cat][2] = 1;
195            cat[size_cat][3] = list(i);
196        }
197    }
198
199    /* find the biggest categories */
200    int cat_max = 1;
201    int max = cat[1][2];
202    for (i = 2; i <= size_cat; i++) {
203        if (cat[i][2] > max) {
204            cat_max = i;
205            max = cat[i][2];
206        }
207    }
208
209    /* return all other indices */
210    list unluckyIndices;
211    for (i = 1; i <= size_cat; i++) {
212        if (i != cat_max) {
213            unluckyIndices = unluckyIndices + cat[i][3];
214        }
215    }
216    return(unluckyIndices);
217}
218
219/* test if 'command' applied to 'args' in characteristic p is the same as
220   'result' mapped to characteristic p */
221static proc pTest_std(string command, list args, ideal result, int p)
222{
223    /* change to characteristic p */
224    def br = basering;
225    list lbr = ringlist(br);
226    if (typeof(lbr[1]) == "int") {
227        lbr[1] = p;
228    }
229    else {
230        lbr[1][1] = p;
231    }
232    def rp = ring(lbr);
233    setring(rp);
234    ideal Ip = fetch(br, args)[1];
235    ideal Gp = fetch(br, result);
236    attrib(Gp, "isSB", 1);
237
238    /* test if Ip is in Gp */
239    int i;
240    for (i = ncols(Ip); i > 0; i--) {
241        if (reduce(Ip[i], Gp, 1) != 0) {
242            setring(br);
243            return(0);
244        }
245    }
246
247    /* compute command(args) */
248    execute("Ip = "+command+"(Ip);");
249
250    /* test if Gp is in Ip */
251    for (i = ncols(Gp); i > 0; i--) {
252        if (reduce(Gp[i], Ip, 1) != 0) {
253            setring(br);
254            return(0);
255        }
256    }
257    setring(br);
258    return(1);
259}
260
261/* test if 'result' is a GB of the input ideal */
262static proc finalTest_std(string command, alias list args, ideal result)
263{
264    /* test if args[1] is in result */
265    attrib(result, "isSB", 1);
266    int i;
267    for (i = ncols(args[1]); i > 0; i--) {
268        if (reduce(args[1][i], result, 1) != 0) {
269            return(0);
270        }
271    }
272
273    /* test if result is a GB */
274    ideal G = std(result);
275    if (reduce_parallel(G, result)) {
276        return(0);
277    }
278    return(1);
279}
280
281/* return 1, if I_reduce is _not_ in G_reduce,
282 *        0, otherwise
283 * (same as size(reduce(I_reduce, G_reduce))).
284 * Uses parallelization. */
285static proc reduce_parallel(ideal I_reduce, ideal G_reduce)
286{
287    exportto(Modstd, I_reduce);
288    exportto(Modstd, G_reduce);
289    int size_I = ncols(I_reduce);
290    int chunks = Modular::par_range(size_I);
291    intvec range;
292    int i;
293    for (i = chunks; i > 0; i--) {
294        range = Modular::par_range(size_I, i);
295        task t(i) = "Modstd::reduce_task", list(range);
296    }
297    startTasks(t(1..chunks));
298    waitAllTasks(t(1..chunks));
299    int result = 0;
300    for (i = chunks; i > 0; i--) {
301        if (getResult(t(i))) {
302            result = 1;
303            break;
304        }
305    }
306    kill I_reduce;
307    kill G_reduce;
308    return(result);
309}
310
311/* compute a chunk of reductions for reduce_parallel */
312static proc reduce_task(intvec range)
313{
314    int result = 0;
315    int i;
316    for (i = range[1]; i <= range[2]; i++) {
317        if (reduce(I_reduce[i], G_reduce, 1) != 0) {
318            result = 1;
319            break;
320        }
321    }
322    return(result);
323}
324
325
326////////////////////////////// further examples ////////////////////////////////
327
328/*
329ring r = 0, (x,y,z), lp;
330poly s1 = 5x3y2z+3y3x2z+7xy2z2;
331poly s2 = 3xy2z2+x5+11y2z2;
332poly s3 = 4xyz+7x3+12y3+1;
333poly s4 = 3x3-4y3+yz2;
334ideal i =  s1, s2, s3, s4;
335
336ring r = 0, (x,y,z), lp;
337poly s1 = 2xy4z2+x3y2z-x2y3z+2xyz2+7y3+7;
338poly s2 = 2x2y4z+x2yz2-xy2z2+2x2yz-12x+12y;
339poly s3 = 2y5z+x2y2z-xy3z-xy3+y4+2y2z;
340poly s4 = 3xy4z3+x2y2z-xy3z+4y3z2+3xyz3+4z2-x+y;
341ideal i =  s1, s2, s3, s4;
342
343ring r = 0, (x,y,z), lp;
344poly s1 = 8x2y2 + 5xy3 + 3x3z + x2yz;
345poly s2 = x5 + 2y3z2 + 13y2z3 + 5yz4;
346poly s3 = 8x3 + 12y3 + xz2 + 3;
347poly s4 = 7x2y4 + 18xy3z2 +  y3z3;
348ideal i = s1, s2, s3, s4;
349
350int n = 6;
351ring r = 0,(x(1..n)),lp;
352ideal i = cyclic(n);
353ring s = 0, (x(1..n),t), lp;
354ideal i = imap(r,i);
355i = homog(i,t);
356
357ring r = 0, (x(1..4),s), (dp(4),dp);
358poly s1 = 1 + s^2*x(1)*x(3) + s^8*x(2)*x(3) + s^19*x(1)*x(2)*x(4);
359poly s2 = x(1) + s^8 *x(1)* x(2)* x(3) + s^19* x(2)* x(4);
360poly s3 = x(2) + s^10*x(3)*x(4) + s^11*x(1)*x(4);
361poly s4 = x(3) + s^4*x(1)*x(2) + s^19*x(1)*x(3)*x(4) +s^24*x(2)*x(3)*x(4);
362poly s5 = x(4) + s^31* x(1)* x(2)* x(3)* x(4);
363ideal i =  s1, s2, s3, s4, s5;
364
365ring r = 0, (x,y,z), ds;
366int a = 16;
367int b = 15;
368int c = 4;
369int t = 1;
370poly f = x^a+y^b+z^(3*c)+x^(c+2)*y^(c-1)+x^(c-1)*y^(c-1)*z3
371         +x^(c-2)*y^c*(y2+t*x)^2;
372ideal i = jacob(f);
373
374ring r = 0, (x,y,z), ds;
375int a = 25;
376int b = 25;
377int c = 5;
378int t = 1;
379poly f = x^a+y^b+z^(3*c)+x^(c+2)*y^(c-1)+x^(c-1)*y^(c-1)*z3
380         +x^(c-2)*y^c*(y2+t*x)^2;
381ideal i = jacob(f),f;
382
383ring r = 0, (x,y,z), ds;
384int a = 10;
385poly f = xyz*(x+y+z)^2 +(x+y+z)^3 +x^a+y^a+z^a;
386ideal i = jacob(f);
387
388ring r = 0, (x,y,z), ds;
389int a = 6;
390int b = 8;
391int c = 10;
392int alpha = 5;
393int beta = 5;
394int t = 1;
395poly f = x^a+y^b+z^c+x^alpha*y^(beta-5)+x^(alpha-2)*y^(beta-3)
396         +x^(alpha-3)*y^(beta-4)*z^2+x^(alpha-4)*y^(beta-4)*(y^2+t*x)^2;
397ideal i = jacob(f);
398*/
399
Note: See TracBrowser for help on using the repository browser.