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.
Welcome to Ask Sage!