Ticket #6407: trac_6407_added_double-and-add_algo_to_EllipticCurveFormalGroup.patch

File trac_6407_added_double-and-add_algo_to_EllipticCurveFormalGroup.patch, 2.8 KB (added by hlaw, 8 months ago)
  • sage/schemes/elliptic_curves/formal_group.py

    # HG changeset patch
    # User Hamish Ivey-Law <hlaw@iml.univ-mrs.fr>
    # Date 1247428027 -7200
    # Node ID b40a8d85dfc7817ecc2675cf4ac34efb4ec8b84f
    # Parent  ca1f31d6f6bf7b1f8da0cb8973c838ab19921c29
    Modified the mult_by_n() method in the EllipticCurveFormalGroup class so that it uses a (right to left) double-and-add algorithm.
    
    diff -r ca1f31d6f6bf -r b40a8d85dfc7 sage/schemes/elliptic_curves/formal_group.py
    a b  
    565565 
    566566        - David Harvey (2007-03): faster algorithm for char 0 field 
    567567          case 
     568 
     569        - Hamish Ivey-Law (2009-06): double-and-add algorithm for 
     570          non char 0 field case. 
    568571         
    569572        EXAMPLES:: 
    570573         
     
    589592            sage: E = EllipticCurve("37a"); F = E.formal_group() 
    590593            sage: F.mult_by_n(100, 20) 
    591594            100*t - 49999950*t^4 + 3999999960*t^5 + 14285614285800*t^7 - 2999989920000150*t^8 + 133333325333333400*t^9 - 3571378571674999800*t^10 + 1402585362624965454000*t^11 - 146666057066712847999500*t^12 + 5336978000014213190385000*t^13 - 519472790950932256570002000*t^14 + 93851927683683567270392002800*t^15 - 6673787211563812368630730325175*t^16 + 320129060335050875009191524993000*t^17 - 45670288869783478472872833214986000*t^18 + 5302464956134111125466184947310391600*t^19 + O(t^20) 
     595 
     596        TESTS:: 
     597 
     598            sage: F = EllipticCurve(GF(17), [1, 1]).formal_group() 
     599            sage: F.mult_by_n(10, 50) 
     600            10*t + 5*t^5 + 7*t^7 + 13*t^9 + t^11 + 16*t^13 + 13*t^15 + 9*t^17 + 16*t^19 + 15*t^23 + 15*t^25 + 2*t^27 + 10*t^29 + 8*t^31 + 15*t^33 + 6*t^35 + 7*t^37 + 9*t^39 + 10*t^41 + 5*t^43 + 4*t^45 + 6*t^47 + 13*t^49 + O(t^50) 
     601 
     602            sage: F = EllipticCurve(GF(101), [1, 1]).formal_group() 
     603            sage: F.mult_by_n(100, 20) 
     604            100*t + O(t^20) 
    592605        """ 
    593606        if self.curve().base_ring().is_field() and self.curve().base_ring().characteristic() == 0 and n != 0: 
    594607            # The following algorithm only works over a field of 
     
    634647            return R(F.add_bigoh(orig_prec)) 
    635648        F = self.group_law(prec) 
    636649        g = F.parent().base_ring().gen() 
    637         for m in range(2,n+1): 
    638             g = F(g)         
    639         return R(g.add_bigoh(orig_prec)) 
     650 
     651        # Double and add is faster than the naive method when n >= 4. 
     652        if n < 4: 
     653            for m in range(2,n+1): 
     654                g = F(g)         
     655            return R(g.add_bigoh(orig_prec)) 
     656 
     657        result = F.parent().base_ring()(0) 
     658        while n > 0: 
     659            if n & 1: 
     660                result = F(result, g) 
     661            g = F(g, g) 
     662            n = n >> 1 
     663 
     664        return R(result.add_bigoh(orig_prec)) 
    640665 
    641666    def sigma(self, prec=10): 
    642667        """