Changeset 8354:99efc33c8b7f


Ignore:
Timestamp:
11/03/07 10:56:51 (6 years ago)
Author:
jvoight@…
Branch:
default
Message:

Totally real field enumeration, significant changes and upgrades.

Location:
sage
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • sage/combinat/combinat.py

    r6995 r8354  
    193193 
    194194from sage.interfaces.all import gap, maxima 
    195 from sage.rings.all import QQ, RR, ZZ 
     195from sage.rings.all import QQ, ZZ 
    196196from sage.rings.arith import binomial 
    197197from sage.misc.sage_eval import sage_eval 
  • sage/libs/pari/gen.pyx

    r6974 r8354  
    47054705        return n 
    47064706 
     4707    def polsturm_full(self): 
     4708        _sig_on 
     4709        n = sturmpart(self.g, NULL, NULL) 
     4710        _sig_off 
     4711        return n 
     4712 
    47074713    def polsylvestermatrix(self, g): 
    47084714        t0GEN(g) 
  • sage/rings/number_field/all.py

    r8353 r8354  
    1212 
    1313from totallyreal import enumerate_totallyreal_fields 
     14from totallyreal_data import hermite_constant 
     15from totallyreal_dsage import totallyreal_dsage 
  • sage/rings/number_field/totallyreal.py

    r8353 r8354  
    4040from sage.rings.number_field.totallyreal_data import tr_data, int_has_small_square_divisor 
    4141 
    42 def enumerate_totallyreal_fields(n, B, a = [], verbose = False, return_seqs=False): 
     42def enumerate_totallyreal_fields(n, B, a = [], verbose=0, return_seqs=False, phc=False): 
    4343    r""" 
    4444    This function enumerates (primitve) totally real fields of  
     
    4848        $$ a[d]*x^n + ... + a[0]*x^(n-d) $$ 
    4949    if length(a) = d+1, so in particular always a[d] = 1.   
    50     If verbose == True, then print to the screen verbosely; if 
    51     verbose is a string, then print to the file specified by verbose 
    52     verbosely. 
     50    If verbose == 1 (or 2), then print to the screen (really) verbosely; if 
     51    verbose is a string, then print verbosely to the file specified by verbose. 
     52    If return_seqs, then return the polynomials as sequences (for easier 
     53    exporting to a file). 
    5354 
    5455    NOTE:  
     
    158159        # Else, print to screen 
    159160    f_out = [0]*n + [1] 
    160     T.incr(f_out) 
     161    if verbose == 2: 
     162        T.incr(f_out,verbose,phc=phc) 
     163    else: 
     164        T.incr(f_out,phc=phc) 
    161165  
    162166    while f_out[n] <> 0: 
     
    167171        d = nf.poldisc() 
    168172        counts[0] += 1 
    169         if d > 0: 
     173        if d > 0 and nf.polsturm_full() == n: 
    170174            da = int_has_small_square_divisor(Integer(d)) 
    171175            if d > dB or d <= B*da: 
     
    214218                    print "is not totally real" 
    215219 
    216         T.incr(f_out) 
     220        if verbose == 2: 
     221            T.incr(f_out,verbose=verbose,phc=phc) 
     222        else: 
     223            T.incr(f_out,phc=phc) 
    217224 
    218225    # In the application of Smyth's theorem above, we exclude finitely 
     
    241248 
    242249    if return_seqs: 
    243         return [counts,[[s[0],s[1].Vec()] for s in S]] 
     250        return [counts,[[s[0],s[1].reverse().Vec()] for s in S]] 
    244251    else: 
    245252        return S 
     
    324331    """ 
    325332 
    326     ppi = float(pi) 
    327     return ((16./3*ppi)*(g+1))**(2./(3*n))*(2*ppi)**(4./3) 
     333    ppi = 3.1415926535897931 
     334    return ((16./3)*(g+1))**(2./(3*n))*(2*ppi)**(4./3) 
  • sage/rings/number_field/totallyreal_data.pyx

    r8353 r8354  
    3434 
    3535import math, numpy 
     36 
     37# Other global variables 
     38ZZx = PolynomialRing(IntegerRing(), 'x') 
    3639 
    3740#*********************************************************************************************** 
     
    242245    return asq 
    243246 
     247cdef eval_seq_as_poly_int(int *f, int n, int x): 
     248    r""" 
     249    Evaluates the sequence a, thought of as a polynomial with 
     250        $$ f[n]*x^n + f[n-1]*x^(n-1) + ... + f[0]. $$ 
     251    """ 
     252    cdef int s, xp 
     253 
     254    s = f[n] 
     255    for i from n > i >= 0: 
     256        s = s*x+f[i] 
     257    return s 
     258 
     259cdef double eps_abs, phi, sqrt2 
     260eps_abs = 10.**(-12) 
     261phi = 0.618033988749895 
     262sqrt2 = 1.41421356237310 
     263 
    244264cdef easy_is_irreducible(int *a, int n): 
    245265    r""" 
    246     Very often, polynomials have roots in {-2,-1,1,2}, so we rule 
     266    Very often, polynomials have roots in {+/-1, +/-2, +/-phi, sqrt2}, so we rule 
    247267    these out quickly.  Returns 0 if reducible, 1 if inconclusive. 
    248268    """ 
    249     cdef s, sgn 
    250  
    251     # Check if x-1 is a factor. 
    252     s = 0 
    253     for i from 0 <= i <= n: 
    254         s += a[i] 
    255     if s == 0: 
     269    cdef int s, t, st, sgn 
     270 
     271    # Check if a has a root in {1,-1,2,-2}. 
     272    if eval_seq_as_poly_int(a,n,1) == 0 or eval_seq_as_poly_int(a,n,-1) == 0 or eval_seq_as_poly_int(a,n,2) == 0 or eval_seq_as_poly_int(a,n,-2) == 0: 
    256273        return 0 
    257274 
    258     # Check if x+1 is a factor. 
    259     s = 0 
    260     sgn = 1 
    261     for i from 0 <= i <= n: 
    262         s += sgn*a[i] 
    263         sgn *= -1 
    264     if s == 0: 
    265         return 0 
    266  
    267     # Check if x-2 is a factor. 
    268     s = 0 
    269     for i from 0 <= i <= n: 
    270         s += (2**i)*a[i] 
    271     if s == 0: 
    272         return 0 
    273  
    274     # Check if x+2 is a factor. 
    275     s = 0 
    276     sgn = 1 
    277     for i from 0 <= i <= n: 
    278         s += sgn*(2**i)*a[i] 
    279         sgn *= -1 
    280     if s == 0: 
    281         return 0 
     275    # Check if f has factors x^2-x-1, x^2+x-1, x^2-2, respectively. 
     276    # Note we only call the ZZx constructor if we're almost certain to reject. 
     277    if abs(eval_seq_as_poly(a,n,-phi)) < eps_abs: 
     278        s = 2*a[n] 
     279        t = 0 
     280        for i from n > i >= 0: 
     281            st = (s+t)//2 
     282            s = 2*t+st+2*a[i] 
     283            t = st 
     284        if s == 0 and t == 0: 
     285            return 0 
     286    if abs(eval_seq_as_poly(a,n,phi)) < eps_abs: 
     287        s = 2*a[n] 
     288        t = 0 
     289        for i from n > i >= 0: 
     290            st = (s-t)//2 
     291            s = 2*t-st+2*a[i] 
     292            t = st 
     293        if s == 0 and t == 0: 
     294            return 0 
     295    if abs(eval_seq_as_poly(a,n,sqrt2)) < eps_abs: 
     296        s = a[n] 
     297        t = 0 
     298        for i from n > i >= 0: 
     299            st = s 
     300            s = 2*t+a[i] 
     301            t = st 
     302        if s == 0 and t == 0: 
     303            return 0 
    282304 
    283305    return 1 
    284306 
     307def easy_is_irreducible_py(f): 
     308    cdef int a[10] 
     309 
     310    for i from 0 <= i < len(f): 
     311        a[i] = f[i] 
     312    return easy_is_irreducible(a, len(f)-1) 
    285313 
    286314#*********************************************************************************************** 
     
    293321# (which gives trivial bounds on coefficients) nor too small (which 
    294322# spends needless time computing higher precision on the roots). 
     323cdef double eps_global 
    295324eps_global = 10.**(-4) 
    296325 
    297 # Other global variables 
    298 ZZx = PolynomialRing(IntegerRing(), 'x') 
     326from totallyreal_phc import lagrange_bounds_phc 
    299327 
    300328cdef class tr_data: 
     
    363391                self.a[i] = a[i] 
    364392                self.amax[i] = a[i] 
    365             self.a[n-1] = -(n/2) 
     393            self.a[n-1] = -(n//2) 
    366394            self.amax[n-1] = 0 
    367395            self.k = n-2 
     
    382410 
    383411            # Bounds come from an application of Lagrange multipliers in degrees 2,3. 
    384             if k == n-2: 
    385                 self.b_lower = 1./n*(-self.a[n-1] -  
    386                                  (n-1)*sqrt((1.*self.a[n-1])**2 - 2.*(1-1./n)*self.a[n-2])) 
    387                 self.b_upper = -(2.*self.a[n-1]/n + self.b_lower) 
    388             else: 
     412            self.b_lower = 1./n*(-self.a[n-1] -  
     413                             (n-1)*sqrt((1.*self.a[n-1])**2 - 2.*(1-1./n)*self.a[n-2])) 
     414            self.b_upper = -(2.*self.a[n-1]/n + self.b_lower) 
     415            if k < n-2: 
    389416                bminmax = __lagrange_degree_3(n,a[n-1],a[n-2],a[n-3]) 
    390                 self.b_lower = bminmax[0] 
    391                 self.b_upper = bminmax[1] 
     417                self.b_lower = max(bminmax[0],self.b_lower) 
     418                self.b_upper = min(bminmax[1],self.b_upper) 
    392419 
    393420            # Annoying, but must reverse coefficients for numpy. 
     
    419446        sage_free(self.gnk) 
    420447 
    421     def incr(self, f_out, verbose=False, haltk=0): 
     448    def incr(self, f_out, verbose=False, haltk=0, phc=False): 
    422449        r""" 
    423450        This function 'increments' the totally real data to the next value 
     
    437464        haltk -- integer, the level at which to halt the inductive  
    438465            coefficient bounds 
     466        phc -- boolean, if PHCPACK is available, use it when k == n-5 to 
     467            compute an improved Lagrange multiplier bound 
    439468 
    440469        OUTPUT: 
     
    578607                        # New bounds from Lagrange multiplier in degree 3. 
    579608                        bminmax = __lagrange_degree_3(n,self.a[n-1],self.a[n-2],self.a[n-3]) 
    580                         self.b_lower = bminmax[0] 
    581                         self.b_upper = bminmax[1] 
     609                        self.b_lower = max(self.b_lower,bminmax[0]) 
     610                        self.b_upper = min(self.b_upper,bminmax[1]) 
     611                    elif k == n-5 and phc: 
     612                        # New bounds using phc/Lagrange multiplier in degree 4. 
     613                        bminmax = lagrange_bounds_phc(n, 4, [self.a[i] for i from 0 <= i <= n]) 
     614                        if len(bminmax) > 0: 
     615                            self.b_lower = max(self.b_lower,bminmax[0]) 
     616                            self.b_upper = min(self.b_upper,bminmax[1]) 
     617                        else: 
     618                            maxoutflag = 1 
     619                            break 
    582620 
    583621                    if verbose: 
  • sage/rings/number_field/totallyreal_phc.py

    r8352 r8354  
    4848 
    4949import os, math 
     50from sage.combinat.combinat import partitions_list 
    5051 
    51 def lagrange_bounds(n, m, a): 
     52def lagrange_bounds_phc(n, m, a): 
    5253    r""" 
    5354    This function determines the bounds on the roots in 
     
    118119            output_data += [[P, min(crits), max(crits)]] 
    119120 
    120     return output_data 
     121    if len(output_data) > 0: 
     122        return [min([v[1] for v in output_data]), max([v[2] for v in output_data])] 
     123    else: 
     124        return [] 
Note: See TracChangeset for help on using the changeset viewer.