source: git/Singular/LIB/algemodstd.lib @ ae537b

fieker-DuValspielwiese
Last change on this file since ae537b was ae537b, checked in by Hans Schoenemann <hannes@…>, 10 years ago
format
  • Property mode set to 100644
File size: 11.4 KB
Line 
1////////////////////////////////////////////////////////////////////////////////
2version="version algemodstd.lib 4.0.1.0 Sep_2014 ";  // $Id$
3category="Commutative Algebra";
4info="
5
6LIBRARY:   algemodstd.lib  Groebner bases of ideals in polynomial rings
7                           over algebraic number fields
8AUTHORS:   D.K. Boku       boku@mathematik.uni-kl.de
9@*         W. Decker       decker@mathematik.uni-kl.de
10@*         C. Fieker       fieker@mathematik.uni-kl.de
11
12OVERVIEW:
13  A library for computing the Groebner basis of an ideal in the polynomial
14  ring over an algebraic number field Q(t) using the modular methods, where t is
15  algebraic over the field of rational numbers Q. For the case Q(t) = Q, the procedure
16  is inspired by Arnold [1]. This idea is then extended
17  to the case t not in Q using factorization as follows:
18  Let f be the minimal polynomial of t.
19  For I, I' ideals in Q(t)[X], Q[X,t]/<f> respectively, we map I to I' via the map sending
20  t to t + <f>.
21  We first choose a prime p such that f has at least two factors in characteristic p and
22  add each factor f_i to I' to obtain the ideal J'_i = I' + <f_i>.
23  We then compute a standard basis G'_i of J'_i for each i and combine the G'_i to G_p
24  (a standard basis of I'_p) using chinese remaindering for polynomials. The procedure is
25  repeated for many primes p, where we compute the G_p in parallel until the
26  number of primes is sufficiently large to recover the correct standard basis G' of I'.
27  Finally, by mapping G' back to Q(t)[X], a standard basis G of I is obtained.
28
29REFERENCES:
30  [1] E. A. Arnold: Modular algorithms for computing Groebner bases.
31      J. Symb. Comp. 35, 403-419 (2003).
32
33PROCEDURES:
34  chinrempoly(l,m);       chinese remaindering for polynomials
35  algemodStd(I);          standard basis of I over algebraic number field using modular methods
36";
37
38LIB "modstd.lib";
39
40////////////////////////////////////////////////////////////////////////////////
41
42static proc testPrime(int p, ideal I)
43{
44    /*
45     * test whether a prime p divides the denominator(s)
46     * and leading coefficients of generating set of ideal
47     */
48    int i,j;
49    poly f;
50    number num;
51    bigint d1,d2,d3;
52    for(i = 1; i <= size(I); i++)
53    {
54        f = cleardenom(I[i]);
55        if(f == 0)
56        {
57            return(0);
58        }
59        num = leadcoef(I[i])/leadcoef(f);
60        d1 = bigint(numerator(num));
61        d2 = bigint(denominator(num));
62        if( (d1 mod p) == 0)
63        {
64            return(0);
65        }
66        if((d2 mod p) == 0)
67        {
68            return(0);
69        }
70        for(j = size(f); j > 0; j--)
71        {
72            d3 = bigint(leadcoef(f[j]));
73            if( (d3 mod p) == 0)
74            {
75                return(0);
76            }
77        }
78    }
79    return(1);
80}
81
82////////////////////////////////////////////////////////////////////////////////
83/* return 1 if the number of factors are in the required bound , 0 else */
84
85static proc minpolyTask(poly f,int p)
86{
87    /*
88     * bound for irreducible factor(s) of (f mod p)
89     * see testfact()
90     */
91    int nr,k,ur;
92    ur=deg(f);
93    list L=factmodp(f,p);
94    if(degtest(L[2])==1)
95    {
96        // now each factor is squarefree
97        if(ur<=3)
98        {
99            return(1);
100        }
101        else
102        {
103            nr = testfact(ur);
104            k=ncols(L[1]);
105            if(nr < k && k < (ur-nr))// set bound for k
106            {
107                return(1);
108            }
109        }
110    }
111    return(0);
112}
113
114////////////////////////////////////////////////////////////////////////////////
115/* return 1 if both testPrime(p,J) and minpolyTask(f,p) is true, 0 else */
116
117static proc PrimeTestTask(int p, list L)
118{
119    /* L=list(I), I=J,f; J ideal , f minpoly */
120    int sz,nr,dg;
121    ideal J=L[1];
122    sz=ncols(J);
123    poly f=J[sz];
124    dg=deg(f);
125    if(!testPrime(p,J) or !minpolyTask(f,p))
126    {
127        return(0);
128    }
129    return(1);
130}
131
132////////////////////////////////////////////////////////////////////////////////
133/* compute factors of f mod p with multiplicity */
134
135static proc factmodp(poly f, int p)
136{
137    def R=basering;
138    list l=ringlist(R);
139    l[1]=p;
140    def S=ring(l);
141    setring S;
142    list L=factorize(imap(R,f),2);
143    ideal J=L[1];
144    intvec v=L[2];
145    list scx=J,v;
146    setring R;
147    return(imap(S,scx));
148    kill S;
149}
150
151////////////////////////////////////////////////////////////////////////////////
152/* set a bound for number of factors w.r.t degree nr*/
153
154static proc testfact(int nr)
155{
156    // nr must be greater than 3
157    int i;
158    if(nr>3 and nr<=5)
159    {
160        i=1;
161    }
162    if(nr>5 and nr<=10)
163    {
164        i=2;
165    }
166    if(nr>10 and nr<=15)
167    {
168        i=3;
169    }
170    if(nr>15 and nr<=20)
171    {
172        i=4;
173    }
174    if(nr>20 and nr<=25)
175    {
176        i=5;
177    }
178    if(nr>25 and nr<=30)
179    {
180        i=6;
181    }
182    if(nr>30)
183    {
184        i=10;
185    }
186    return(i);
187}
188
189///////////////////////////////////////////////////////////////////////////////
190// return 1 if v[i]>1 , 0 else
191
192static proc degtest(intvec v)
193{
194    for(int j=1;j<=nrows(v);j++)
195    {
196        if(v[j]>1)
197        {
198            return(0);
199        }
200    }
201    return(1);
202}
203
204////////////////////////////////////////////////////////////////////////////////
205
206static proc chinRm(list m, list ll, list lk,list l1,int uz)
207{
208    poly ff,c;
209
210    for(int i=1;i<=uz;i++)
211    {
212        c = division(l1[i]*ll[i],m[i])[2][1];
213        ff = ff + c*lk[i];
214    }
215    return(ff);
216}
217
218////////////////////////////////////////////////////////////////////////////////
219
220proc chinrempoly(list l,list m)
221"USAGE:  chinrempoly(l, m); l list, m list
222RETURN:  a polynomial (resp. ideal) which is congruent to l[i] modulo m[i] for all i
223NOTE: The procedure applies chinese remaindering to the first argument w.r.t. the
224      moduli given in the second. The elements in the first list must be of same type
225      which can be polynomial or ideal. The moduli must be of type polynomial. Elements
226      in the second list must be distinct and co-prime.
227SEE ALSO: chinrem
228EXAMPLE: example chinrempoly; shows an example
229"
230{
231    int i,j,sz,uz;
232    uz = size(l);
233    sz = ncols(ideal(l[1]));
234    poly f=1;
235    for(i=1;i<=uz;i++)
236    {
237        f=f*m[i];
238    }
239
240    ideal I,J;
241    list l1,ll,lk,l2;
242    poly c,ff;
243    for(j=1;j<=uz;j++)
244    {
245        lk[j]=f/m[j];
246        ll[j]=extgcd(lk[j],m[j])[2];
247    }
248
249    for(i=1;i<=sz;i++)
250    {
251        for(j=1;j<=uz;j++)
252        {
253            I = l[j];
254            l1[j] = I[i];
255        }
256        J[i] = chinRm(m,ll,lk,l1,uz);
257    }
258    return(J);
259}
260example
261{ "EXAMPLE:"; echo = 2;
262    ring rr=97,x,dp;
263    poly f=x^7-7*x + 3;
264    ideal J=factorize(f,1);
265    J;
266    list m=J[1..ncols(J)];
267    list l= x^2+2*x+3, x^2+5, x^2+7;
268    ideal I=chinrempoly(l,m);
269    I;
270    ring s=0,x,dp;
271    list m= x^2+2*x+3, x^3+5, x^4+x^3+7;
272    list l=x^3 + 2, x^4 + 7, x^5 + 11;
273    ideal I=chinrempoly(l,m);
274    I;
275    int p=prime(536546513);
276    ring r = p, (x,y,a), (dp(2),dp(1));
277    poly minpolynomial = a^2+1;
278    ideal kf=factorize(minpolynomial,1);//return factors without multiplicity
279    kf;
280    ideal k=(a+1)*x2+y, 3x-ay+ a+2;
281    option(redSB);
282    ideal k1=k,kf[1];
283    ideal k2 =k,kf[2];
284    k1=std(k1);
285    k2=std(k2);
286    list l=k1,k2;
287    list m=kf[1..ncols(kf)];
288    ideal I=chinrempoly(l,m);
289    I=simplify(I,2);
290    I;
291}
292
293////////////////////////////////////////////////////////////////////////////////
294
295static proc LiftPolyCRT(ideal I)
296{
297    /*
298     * compute std for each factor and combine this result
299     * to modulo minpoly via CRT for poly over char p>0
300     */
301    int u,in,j;
302    list LL,Lk;
303    ideal J,K,II;
304    poly f;
305    u=ncols(I);
306    J=I[1..u-1];
307    f=I[u];
308    K=factorize(f,1);
309    in=ncols(K);
310    for(j=1;j<=in;j++)
311    {
312        LL[j]=K[j];
313        ideal I(j)=J,K[j];
314        I(j)=std(I(j));
315        if(size(I(j))==1)
316        {
317            Lk[j]=I(j);
318        }
319        else
320        {
321            I(j)[1]=0;
322            I(j)=simplify(I(j), 2);
323            Lk[j]=I(j);
324        }
325    }
326    // apply CRT for polynomials
327    II =chinrempoly(Lk,LL),f;
328    return(II);
329}
330
331////////////////////////////////////////////////////////////////////////////////
332
333static proc PtestStd(string command, list args, ideal result, int p)
334{
335    /*
336     * let G be std of I which is not yet known whether it is the correct
337     *  standard basis or not. So this procedure does the first test
338     */
339    def br = basering;
340    list lbr = ringlist(br);
341    if (typeof(lbr[1]) == "int")
342    {
343        lbr[1] = p;
344    }
345    else
346    {
347        lbr[1][1] = p;
348    }
349    def rp = ring(lbr);
350    setring(rp);
351    ideal Ip = fetch(br, args)[1];
352    ideal Gp = fetch(br, result);
353    attrib(Gp, "isSB", 1);
354    int i;
355    for (i = ncols(Ip); i > 0; i--)
356    {
357        if (reduce(Ip[i], Gp, 1) != 0)
358        {
359            setring(br);
360            return(0);
361        }
362    }
363    Ip = LiftPolyCRT(Ip);
364    attrib(Ip,"isSB",1);
365    for (i = ncols(Gp); i > 0; i--)
366    {
367        if (reduce(Gp[i], Ip, 1) != 0)
368        {
369            setring(br);
370            return(0);
371        }
372    }
373    setring(br);
374    return(1);
375}
376
377////////////////////////////////////////////////////////////////////////////////
378
379static proc cleardenomIdeal(ideal I)
380{
381    int t=ncols(I);
382    if(size(I)==0)
383    {
384        return(I);
385    }
386    else
387    {
388        for(int i=1;i<=t;i++)
389        {
390            I[i]=cleardenom(I[i]);
391        }
392    }
393    return(I);
394}
395
396////////////////////////////////////////////////////////////////////////////////
397
398static proc modStdparallelized(ideal I)
399{
400    // apply modular.lib
401    /* save options */
402    intvec opt = option(get);
403    option(redSB);
404    I = modular("Algemodstd::LiftPolyCRT", list(I), PrimeTestTask, Modstd::deleteUnluckyPrimes_std,
405              PtestStd, Modstd::finalTest_std,536870909);
406    attrib(I, "isSB", 1);
407    option(set,opt);
408    return(I);
409}
410
411////////////////////////////////////////////////////////////////////////////////
412/* main procedure */
413proc algemodStd(ideal I, list #)
414"USAGE:  algemodStd(I, #); I ideal, # optional parameters
415RETURN:  standard basis of I over algebraic number field
416NOTE: The procedure passes to @ref{modStd} if the ground field has no
417      parameter. In this case, the optional parameters # (if given)
418      are directly passed to @ref{modStd}.
419SEE ALSO: modStd
420EXAMPLE: example algemodStd; shows an example
421"
422{
423    list L=#;
424    def Rbs=basering;
425    poly f;
426    ideal J;
427    int n=nvars(Rbs);
428    if(size(I)==0)
429    {
430        return(ideal(0));
431    }
432    if(npars(Rbs)==0)
433    {
434        J=modStd(I,L);//if algebraic number is in Q
435        if(size(#)>0)
436        {
437            return(cleardenomIdeal(J));
438        }
439        return(J);
440    }
441    list rl=ringlist(Rbs);
442    f=rl[1][4][1];
443    rl[2][n+1]=rl[1][2][1];
444    rl[1]=rl[1][1];
445    rl[3][size(rl[3])+1]=rl[3][size(rl[3])];
446    rl[3][size(rl[3])-1]=list("dp",1);
447    def S=ring(rl);
448    setring S;
449    poly f=imap(Rbs,f);
450    ideal I=imap(Rbs,I);
451    I = simplify(I,2);// eraze the zero generatos
452    ideal J;
453    if(f==0)
454    {
455        ERROR("minpoly must be non-zero");
456    }
457    I=I,f;
458    J=modStdparallelized(I);
459    setring Rbs;
460    J=imap(S,J);
461    J=simplify(J,2);
462    if(size(#)>0)
463    {
464        return(cleardenomIdeal(J));
465    }
466    return(J);
467}
468example
469{ "EXAMPLE:"; echo = 2;
470    ring r1 =(0,a),(x,y),dp;
471    minpoly =a^2+1;
472    ideal k=(a/2+1)*x^2+2/3y, 3*x-a*y+ a/7+2;
473    ideal I=algemodStd(k);
474    I;
475    ring r2 =(0,a),(x,y,z),dp;
476    minpoly =a^3 +2;
477    ideal k=(a^2+a/2)*x^2+(a^2 -2/3*a)*yz, (3*a^2+1)*zx-(a+4/7)*y+ a+2/5;
478    ideal IJ=algemodStd(k);
479    IJ;
480    ring r3=0,(x,y),dp;// ring without parameter
481    ideal I = x2 + y, xy - 7y + 2x;
482    I=algemodStd(I);
483    I;
484}
Note: See TracBrowser for help on using the repository browser.