Ticket #10136: trac_10136-log_operator.patch

File trac_10136-log_operator.patch, 8.7 KB (added by burcin, 8 years ago)
  • sage/functions/log.py

    # HG changeset patch
    # User Burcin Erocal <burcin@erocal.org>
    # Date 1372662121 -7200
    #      Mon Jul 01 09:02:01 2013 +0200
    # Node ID 81e53510706bcdbb99171dd55628018c6fc8cb16
    # Parent  09f5a70a5e4ee377647a92282941dcf3e318591c
    trac 10136: Unify top level log and ln functions.
    
    Having different functions for log and ln creates confusion. We now have:
    
        sage: log(x).operator() is log
        True
        sage: log(x).operator() is ln
        True
    
    diff --git a/sage/functions/log.py b/sage/functions/log.py
    a b  
    170170            sage: ln(complex(-1))
    171171            3.141592653589793j
    172172
    173         We do not currently support a ``hold`` parameter in functional
    174         notation::
     173        The ``hold`` parameter can be used to prevent automatic evaluation::
    175174
    176             sage: log(SR(-1),hold=True)
    177             Traceback (most recent call last):
    178             ...
    179             TypeError: log() got an unexpected keyword argument 'hold'
    180 
    181         This is possible with method notation::
    182 
     175            sage: log(-1,hold=True)
     176            log(-1)
     177            sage: log(-1)
     178            I*pi
    183179            sage: I.log(hold=True)
    184180            log(I)
    185181            sage: I.log(hold=True).simplify()
     
    223219            3.141592653589793j
    224220        """
    225221        GinacFunction.__init__(self, 'log', latex_name=r'\log',
    226                                    conversions=dict(maxima='log'))
     222                               conversions=dict(maxima='log'))
    227223
    228 ln = function_log = Function_log()
     224    def __call__(self, *args, **kwds):
     225        """
     226        Return the logarithm of x to the given base.
    229227
    230 def log(x, base=None):
    231     """
    232     Return the logarithm of x to the given base.
    233    
    234     Calls the ``log`` method of the object x when computing
    235     the logarithm, thus allowing use of logarithm on any object
    236     containing a ``log`` method. In other words, log works
    237     on more than just real numbers.
    238    
    239     EXAMPLES::
    240    
    241         sage: log(e^2)
    242         2
    243        
    244     To change the base of the logarithm, add a second parameter::
     228        Calls the ``log`` method of the object x when computing
     229        the logarithm, thus allowing use of logarithm on any object
     230        containing a ``log`` method. In other words, log works
     231        on more than just real numbers.
    245232
    246         sage: log(1000,10)
    247         3
     233        EXAMPLES::
    248234
    249     You can use :class:`RDF<sage.rings.real_double.RealDoubleField_class>`,
    250     :class:`~sage.rings.real_mpfr.RealField` or ``n`` to get a numerical real
    251     approximation::
     235            sage: log(e^2)
     236            2
    252237
    253         sage: log(1024, 2)
    254         10
    255         sage: RDF(log(1024, 2))
    256         10.0
    257         sage: log(10, 4)
    258         log(10)/log(4)
    259         sage: RDF(log(10, 4))
    260         1.66096404744
    261         sage: log(10, 2)
    262         log(10)/log(2)
    263         sage: n(log(10, 2))
    264         3.32192809488736
    265         sage: log(10, e)
    266         log(10)
    267         sage: n(log(10, e))
    268         2.30258509299405
    269    
    270     The log function works for negative numbers, complex
    271     numbers, and symbolic numbers too, picking the branch
    272     with angle between `-pi` and `pi`::
     238        To change the base of the logarithm, add a second parameter::
    273239
    274         sage: log(-1+0*I)
    275         I*pi
    276         sage: log(CC(-1))
    277         3.14159265358979*I
    278         sage: log(-1.0)
    279         3.14159265358979*I
     240            sage: log(1000,10)
     241            3
    280242
    281     For input zero, the following behavior occurs::
     243        You can use
     244        :class:`RDF<sage.rings.real_double.RealDoubleField_class>`,
     245        :class:`~sage.rings.real_mpfr.RealField` or ``n`` to get a
     246        numerical real approximation::
    282247
    283         sage: log(0)
    284         -Infinity
    285         sage: log(CC(0))
    286         -infinity
    287         sage: log(0.0)
    288         -infinity
     248            sage: log(1024, 2)
     249            10
     250            sage: RDF(log(1024, 2))
     251            10.0
     252            sage: log(10, 4)
     253            log(10)/log(4)
     254            sage: RDF(log(10, 4))
     255            1.66096404744
     256            sage: log(10, 2)
     257            log(10)/log(2)
     258            sage: n(log(10, 2))
     259            3.32192809488736
     260            sage: log(10, e)
     261            log(10)
     262            sage: n(log(10, e))
     263            2.30258509299405
    289264
    290     The log function also works in finite fields as long as the argument lies
    291     in the multiplicative group generated by the base::
    292    
    293         sage: F = GF(13); g = F.multiplicative_generator(); g
    294         2
    295         sage: a = F(8)
    296         sage: log(a,g); g^log(a,g)
    297         3
    298         8
    299         sage: log(a,3)
    300         Traceback (most recent call last):
    301         ...
    302         ValueError: No discrete log of 8 found to base 3
    303         sage: log(F(9), 3)
    304         2
     265        The log function works for negative numbers, complex
     266        numbers, and symbolic numbers too, picking the branch
     267        with angle between `-pi` and `pi`::
    305268
    306     The log function also works for p-adics (see documentation for
    307     p-adics for more information)::
    308    
    309         sage: R = Zp(5); R
    310         5-adic Ring with capped relative precision 20
    311         sage: a = R(16); a
    312         1 + 3*5 + O(5^20)
    313         sage: log(a)
    314         3*5 + 3*5^2 + 3*5^4 + 3*5^5 + 3*5^6 + 4*5^7 + 2*5^8 + 5^9 + 5^11 + 2*5^12 + 5^13 + 3*5^15 + 2*5^16 + 4*5^17 + 3*5^18 + 3*5^19 + O(5^20)
    315     """
    316     if base is None:
     269            sage: log(-1+0*I)
     270            I*pi
     271            sage: log(CC(-1))
     272            3.14159265358979*I
     273            sage: log(-1.0)
     274            3.14159265358979*I
     275
     276        For input zero, the following behavior occurs::
     277
     278            sage: log(0)
     279            -Infinity
     280            sage: log(CC(0))
     281            -infinity
     282            sage: log(0.0)
     283            -infinity
     284
     285        The log function also works in finite fields as long as the
     286        argument lies in the multiplicative group generated by the base::
     287
     288            sage: F = GF(13); g = F.multiplicative_generator(); g
     289            2
     290            sage: a = F(8)
     291            sage: log(a,g); g^log(a,g)
     292            3
     293            8
     294            sage: log(a,3)
     295            Traceback (most recent call last):
     296            ...
     297            ValueError: No discrete log of 8 found to base 3
     298            sage: log(F(9), 3)
     299            2
     300
     301        The log function also works for p-adics (see documentation for
     302        p-adics for more information)::
     303
     304            sage: R = Zp(5); R
     305            5-adic Ring with capped relative precision 20
     306            sage: a = R(16); a
     307            1 + 3*5 + O(5^20)
     308            sage: log(a)
     309            3*5 + 3*5^2 + 3*5^4 + 3*5^5 + 3*5^6 + 4*5^7 + 2*5^8 + 5^9 +
     310            5^11 + 2*5^12 + 5^13 + 3*5^15 + 2*5^16 + 4*5^17 + 3*5^18 +
     311            3*5^19 + O(5^20)
     312
     313
     314        TESTS:
     315
     316        Check if :trac:`10136` is fixed::
     317
     318            sage: log(x).operator() is log
     319            True
     320            sage: log(x).operator() is ln
     321            True
     322
     323            sage: log(1000, 10, base=5)
     324            Traceback (most recent call last):
     325            ...
     326            TypeError: Symbolic function log must be called as log(x),
     327            log(x, base=b) or log(x, b)
     328        """
     329        base = kwds.pop('base', None)
     330        if base is None:
     331            if len(args) == 1:
     332                return GinacFunction.__call__(self, *args, **kwds)
     333            # second argument is base
     334            base = args[1]
     335            args = args[:1]
     336
     337        if len(args) != 1:
     338            raise TypeError("Symbolic function log must be called as "
     339                    "log(x), log(x, base=b) or log(x, b)")
     340
    317341        try:
    318             return x.log()
    319         except AttributeError:
    320             return ln(x)
    321     else:
    322         try:
    323             return x.log(base)
     342            return args[0].log(base)
    324343        except (AttributeError, TypeError):
    325             return log(x) / log(base)
     344            return GinacFunction.__call__(self, *args, **kwds) / \
     345                GinacFunction.__call__(self, base, **kwds)
     346
     347ln = log = function_log = Function_log()
    326348
    327349
    328350class Function_polylog(GinacFunction):
  • sage/symbolic/expression.pyx

    diff --git a/sage/symbolic/expression.pyx b/sage/symbolic/expression.pyx
    a b  
    69616961            sage: a = I.log(hold=True); a.simplify()
    69626962            1/2*I*pi
    69636963
    6964         We do not currently support a ``hold`` parameter in functional
    6965         notation::
    6966 
    6967             sage: log(SR(-1),hold=True)
    6968             Traceback (most recent call last):
    6969             ...
    6970             TypeError: log() got an unexpected keyword argument 'hold'
     6964        The ``hold`` parameter also works in functional notation::
     6965
     6966            sage: log(-1,hold=True)
     6967            log(-1)
     6968            sage: log(-1)
     6969            I*pi
    69716970
    69726971        TESTS::
    69736972