Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

The implemented method log tries to guess the intention, and sometimes this intention is not clear. In the given case we are mixing the following two things: - log is a sage-specific function, it is not the native python log-function, which is implemented as math.log after importing math. Going the python way, this should work. - x = int(mynumber) insures that x is an instance of the python class int, which comes with its obvious, wanted arithmetic limitations when used.

Mixing sage and python is in general not a good idea. And while working with the sage interpreter it is so simple to stay in the sage world. Doing so there is no problem:

sage: x = 21743271936
sage: log(x, 2).n()
34.3398500028846
sage: type(x)
<class 'sage.rings.integer.Integer'>

But making x intentionally an int instance makes the sage log switch to a guessing path.

I've typed for instance ??log into the sage interpreter, and this gives the whole information to the log function. At the end:

    base = kwds.pop('base', None)
    if base is not None:
        args = args + (base,)
    if not args:
        raise TypeError("log takes at least 1 arguments (0 given)")
    if len(args) == 1:
        from sage.functions.log import ln
        return ln(args[0], **kwds)
    if len(args) > 2:
        raise TypeError("log takes at most 2 arguments (%s given)" % (len(args) + 1 - (base is not None)))
    try:
        return args[0].log(args[1])
    except ValueError as ex:
        if ex.args[0].startswith("no logarithm"):
            raise
    except (AttributeError, TypeError):
        pass
    from sage.functions.log import logb
    return logb(args[0], args[1])
File:      /usr/lib/python3.13/site-packages/sage/misc/functional.py
Type:      function

And the road log(21743271936, 2).n() is not taken. But which is the road taken. We start by setting the base two. We have two arguments, so we are trying to evaluate x.log(2), and probably sage took a lot of time to insure log is a present method for all classes that may somehow make sense to be joined with a log method. For instance:

sage: 21743271936.log(2)
log(21743271936)/log(2)
sage: _.n()
34.3398500028846
sage: type(21743271936)
<class 'sage.rings.integer.Integer'>

(In particular, the last mentioned class comes with a log.)

But our int-instance is an instance of a basic (arithmetically and mathematically poor) class. So we go into the final default case, we import logb, and ask for logb applied on our int-object w.r.t. the base two. What is logb? After ??logb we see that the code goes into a GinacFunction.

Note that inside /usr/lib/python3.13/site-packages/sage/functions/log.py we have the line logb = Function_log2(). So we obtain the information to the class Function_log2.

Signature:      logb(self, coerce=True, hold=False, dont_call_method_on_arg=False, *args)
Type:           Function_log2
String form:    log
File:           /usr/lib/python3.13/site-packages/sage/functions/log.py
Source:
class Function_log2(GinacFunction):
    """
    Return the logarithm of x to the given base.

    See :meth:`log() <sage.functions.log.log>` for extensive documentation.

    EXAMPLES::

        sage: from sage.functions.log import logb
        sage: logb(1000, 10)                                                            # needs sage.symbolic
        3

    TESTS::

        sage: logb(7, 2)                                                                # needs sage.symbolic
        log(7)/log(2)
        sage: logb(int(7), 2)                                                           # needs sage.symbolic
        log(7)/log(2)
    """
    def __init__(self):
        """
        TESTS::

            sage: from sage.functions.log import logb
            sage: loads(dumps(logb))
            log
        """
        GinacFunction.__init__(self, 'log', ginac_name='logb', nargs=2,
                               latex_name=r'\log',
                               conversions=dict(maxima='log'))

And indeed, we reproduce the error.

sage: logb(x, 2)
28

What happens inside this class? Hard to say, it there is a pxd function file only:

[dan@k9 ~]$ ll /usr/lib/python3.13/site-packages/sage/symbolic/function*
-rwxr-xr-x 1 root root 281K 25. Aug 11:53 /usr/lib/python3.13/site-packages/sage/symbolic/function.cpython-313-x86_64-linux-gnu.so*
-rw-r--r-- 1 root root  13K 25. Aug 11:53 /usr/lib/python3.13/site-packages/sage/symbolic/function_factory.py
-rw-r--r-- 1 root root  793 25. Aug 11:53 /usr/lib/python3.13/site-packages/sage/symbolic/function.pxd

So the error is in the black box.