Is this a bug or intended behavior?
Hello, SageMath Community!
I was trying to define the function $\tau(n)=$ "number of divisors of $n$" in Sage, so I tried this:
tau(n) = len(divisors(n))
After pressing ENTER, I get the following traceback:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-1-7aac193e89de> in <module>()
----> 1 __tmp__=var("n"); tau = symbolic_expression(len(divisors(n))).function(n)
/Scientific/SageMath/local/lib/python2.7/site-packages/sage/arith/misc.pyc in divisors(n)
1494 one = parent(n)(1)
1495 output = [one]
-> 1496 for p, e in f:
1497 prev = output[:]
1498 pn = one
TypeError: 'sage.symbolic.expression.Expression' object is not iterable
However, I can use exactly the same definition of the function by means of Python's standard function definition mechanism:
def tau(n):
return len(divisors(n))
I am not completely sure, but the following behaviour seems to be related. An alternative definition of $\tau$ would be:
tau(n) = sigma(n, 0)
However, this produces the following traceback:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-7-016584cdbd3f> in <module>()
----> 1 __tmp__=var("n"); tau = symbolic_expression(sigma(n,Integer(0))).function(n)
/Scientific/SageMath/local/lib/python2.7/site-packages/sage/arith/misc.pyc in __call__(self, n, k)
1595 130
1596 """
-> 1597 n = ZZ(n)
1598 k = ZZ(k)
1599 one = ZZ(1)
/Scientific/SageMath/local/lib/python2.7/site-packages/sage/structure/parent.pyx in sage.structure.parent.Parent.__call__ (build/cythonized/sage/structure/parent.c:9197)()
898 if mor is not None:
899 if no_extra_args:
--> 900 return mor._call_(x)
901 else:
902 return mor._call_with_args(x, args, kwds)
/Scientific/SageMath/local/lib/python2.7/site-packages/sage/structure/coerce_maps.pyx in sage.structure.coerce_maps.NamedConvertMap._call_ (build/cythonized/sage/structure/coerce_maps.c:5942)()
286 raise TypeError("Cannot coerce {} to {}".format(x, C))
287 cdef Map m
--> 288 cdef Element e = method(C)
289 if e is None:
290 raise RuntimeError("BUG in coercion model: {} method of {} returned None".format(self.method_name, type(x)))
/Scientific/SageMath/local/lib/python2.7/site-packages/sage/symbolic/expression.pyx in sage.symbolic.expression.Expression._integer_ (build/cythonized/sage/symbolic/expression.cpp:8690)()
1085 n = self.pyobject()
1086 except TypeError:
-> 1087 raise TypeError("unable to convert %r to an integer" % self)
1088 if isinstance(n, sage.rings.integer.Integer):
1089 return n
TypeError: unable to convert n to an integer
However, I can do:
def tau(n):
return sigma(n, 0)
Of course, it is possible to evaluate the formulas len(divisors(n))
and sigma(n, 0)
, when $n$ has a particular value---n=50, for example.
OS: Ubuntu 18.04.2 LTS
SageMath version: 8.8, dated 2019-06-26
Python version: 2.7.15
Possible explanation: SageMath seems to be trying to evaluate part of the body of the function during compile-time, instead of defering it to execution-time, as Python does.