Ticket #6509: trac_6509_four_squares.patch

File trac_6509_four_squares.patch, 3.2 KB (added by mhampton, 4 years ago)
  • sage/rings/arith.py

    # HG changeset patch
    # User Marshall Hampton <hamptonio@gmail.com>
    # Date 1247260012 18000
    # Node ID 0039c63e7e3ed69870398baf5ebc933cc9a6028d
    # Parent  bd1e213538a5ff2045f1eca4607382130421d2f4
    Improved attempt at four square sum decomposition.
    
    diff -r bd1e213538a5 -r 0039c63e7e3e sage/rings/arith.py
    a b  
    37733773    else: 
    37743774        raise RuntimeError, "unknown algorithm '%s'"%algorithm 
    37753775 
     3776def _brute_force_four_squares(n): 
     3777    """ 
     3778    Brute force search for decomposition into a sum of four squares, 
     3779    for cases that the main algorithm fails to handle. 
     3780 
     3781    INPUT: a positive integer 
     3782    OUTPUT: a list of four numbers whose squares sum to n 
     3783 
     3784    EXAMPLES:: 
     3785        sage: from sage.rings.arith import _brute_force_four_squares 
     3786        sage: _brute_force_four_squares(567) 
     3787        [1, 1, 6, 23] 
     3788    """ 
     3789    from math import sqrt 
     3790    for i in range(0,int(sqrt(n))+1): 
     3791        for j in range(i,int(sqrt(n-i**2))+1): 
     3792            for k in range(j, int(sqrt(n-i**2-j**2))+1): 
     3793                rem = n-i**2-j**2-k**2 
     3794                if rem >= 0: 
     3795                    l = int(sqrt(rem)) 
     3796                    if rem-l**2==0: 
     3797                        return [i,j,k,l] 
     3798     
     3799def four_squares(n): 
     3800    """ 
     3801    Computes the decomposition into the sum of four squares, 
     3802    using an algorithm described by Peter Schorn at: 
     3803    http://www.schorn.ch/howto.html. 
     3804 
     3805    INPUT: an integer 
     3806 
     3807    OUTPUT: a list of four numbers whose squares sum to n 
     3808 
     3809    EXAMPLES:: 
     3810        sage: four_squares(3) 
     3811        [0, 1, 1, 1] 
     3812        sage: four_squares(130) 
     3813        [0, 0, 3, 11] 
     3814        sage: four_squares(1101011011004) 
     3815        [2, 1049178, 2370, 15196] 
     3816        sage: sum([i-sum([q^2 for q in four_squares(i)]) for i in range(2,10000)]) # long time 
     3817        0 
     3818    """ 
     3819    from sage.rings.integer_mod import mod 
     3820    from math import sqrt 
     3821    from sage.rings.arith import _brute_force_four_squares 
     3822    try:  
     3823        ts = two_squares(n) 
     3824        return [0,0,ts[0],ts[1]] 
     3825    except ValueError: 
     3826        pass 
     3827    m = n 
     3828    v = 0 
     3829    while mod(m,4)==0: 
     3830        v = v +1 
     3831        m = m/4 
     3832    if mod(m,8) == 7: 
     3833        d = 1 
     3834        m = m - 1 
     3835    else: 
     3836        d = 0 
     3837    if mod(m,8)==3: 
     3838        x = int(sqrt(m)) 
     3839        if mod(x,2) == 0: 
     3840            x = x - 1 
     3841        p = (m-x**2)/2 
     3842        while not is_prime(p): 
     3843            x = x - 2 
     3844            p = (m-x**2)/2 
     3845            if x < 0: 
     3846            # fall back to brute force 
     3847                m = m + d 
     3848                return [2**v*q for q in _brute_force_four_squares(m)] 
     3849        y,z = two_squares(p) 
     3850        return [2**v*q for q in [d,x,y+z,abs(y-z)]] 
     3851    x = int(sqrt(m)) 
     3852    p = m - x**2 
     3853    if p == 1: 
     3854        return[2**v*q for q in [d,0,x,1]] 
     3855    while not is_prime(p): 
     3856        x = x - 1 
     3857        p = m - x**2 
     3858        if x < 0: 
     3859            # fall back to brute force 
     3860            m = m + d 
     3861            return [2**v*q for q in _brute_force_four_squares(m)] 
     3862    y,z = two_squares(p) 
     3863    return [2**v*q for q in [d,x,y,z]] 
     3864 
     3865 
    37763866def subfactorial(n): 
    37773867    r""" 
    37783868    Subfactorial or rencontres numbers, or derangements: number of