Ignore:
Timestamp:
09/15/06 18:22:37 (7 years ago)
Author:
dmharvey@…
Branch:
default
Message:

[project @ Integer.exact_log -- adds Integer.exact_log() method, which computes log(n, m) without precision problems]

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sage/ext/integer.pyx

    r1205 r1206  
    99    -- William Stein (2006-04-14): added GMP factorial method (since it's 
    1010                                   now very fast). 
    11     -- David Harvey (2006-09-15): added nth_root 
     11    -- David Harvey (2006-09-15): added nth_root, exact_log 
    1212""" 
    1313 
     
    5252import sage.libs.pari.all 
    5353import mpfr 
     54import sage.misc.functional 
    5455 
    5556cdef mpz_t mpz_tmp 
     
    721722            return x 
    722723 
     724    def exact_log(self, m): 
     725        r""" 
     726        Returns the largest integer $k$ such that $m^k \leq \text{self}$. 
     727 
     728        This is guaranteed to return the correct answer even when the usual 
     729        log function doesn't have sufficient precision. 
     730 
     731        INPUT: 
     732            m -- integer >= 2 
     733 
     734        AUTHOR: 
     735           -- David Harvey (2006-09-15) 
     736 
     737        TODO: 
     738           -- Currently this is extremely stupid code (although it should 
     739           always work). Someone needs to think about doing this properly 
     740           by estimating errors in the log function etc. 
     741 
     742        EXAMPLES: 
     743           sage: Integer(125).exact_log(5) 
     744           3 
     745           sage: Integer(124).exact_log(5) 
     746           2 
     747           sage: Integer(126).exact_log(5) 
     748           3 
     749           sage: Integer(3).exact_log(5) 
     750           0 
     751           sage: Integer(1).exact_log(5) 
     752           0 
     753 
     754        This is why you don't want to use log(n, m): 
     755           sage: x = 3**10000000 
     756           sage: log(x, 3) 
     757           9999999.9999999981 
     758           sage: log(x + 100000, 3) 
     759           9999999.9999999981 
     760 
     761           sage: x.exact_log(3) 
     762           10000000 
     763           sage: (x+1).exact_log(3) 
     764           10000000 
     765           sage: (x-1).exact_log(3) 
     766           9999999 
     767            
     768        """ 
     769        if self <= 0: 
     770            raise ValueError, "self must be positive" 
     771        if m < 2: 
     772            raise ValueError, "m must be at least 2" 
     773 
     774        guess = int(sage.misc.functional.log(self, m)) 
     775        power = m ** guess 
     776 
     777        while power > self: 
     778            power = power / m 
     779            guess = guess - 1 
     780 
     781        if power == self: 
     782            return guess 
     783 
     784        while power < self: 
     785            power = power * m 
     786            guess = guess + 1 
     787 
     788        if power == self: 
     789            return guess 
     790        else: 
     791            return guess - 1 
     792         
     793 
    723794    def __pos__(self): 
    724795        """ 
Note: See TracChangeset for help on using the changeset viewer.