Skip to content

Commit b195a14

Browse files
committed
Speed up binomial
1 parent 871ba9d commit b195a14

File tree

5 files changed

+25
-7
lines changed

5 files changed

+25
-7
lines changed

src/sage/arith/misc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3959,7 +3959,7 @@ def binomial(x, m, **kwds):
39593959
P = parent(x)
39603960
x = py_scalar_to_element(x)
39613961

3962-
# case 1: native binomial implemented on x
3962+
# case 1: native binomial implemented on x (see also dont_call_method_on_arg)
39633963
try:
39643964
return P(x.binomial(m, **kwds))
39653965
except (AttributeError, TypeError):

src/sage/functions/other.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1715,6 +1715,17 @@ def _binomial_sym(self, n, k):
17151715
from sage.misc.misc_c import prod
17161716
return prod(n - i for i in range(k)) / factorial(k)
17171717

1718+
def _method_arguments(self, n, k):
1719+
"""
1720+
See :meth:`sage.symbolic.function.BuiltinFunction._method_arguments`.
1721+
1722+
TESTS::
1723+
1724+
sage: binomial._method_arguments(10, 5)
1725+
(10, 5)
1726+
"""
1727+
return (n, k)
1728+
17181729
def _eval_(self, n, k):
17191730
"""
17201731
EXAMPLES::

src/sage/functions/transcendental.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ def _evalf_(self, n, x, parent=None, algorithm=None):
390390
"""
391391
return _mpmath_utils_call(_mpmath_zeta, x, 1, n, parent=parent)
392392

393-
def _method_arguments(self, k, x, **args):
393+
def _method_arguments(self, k, x):
394394
r"""
395395
TESTS::
396396

src/sage/symbolic/function.pxd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ cdef class Function(SageObject):
1212
cdef _register_function(self)
1313

1414
cdef class BuiltinFunction(Function):
15-
cdef object _preserved_arg
15+
cdef int _preserved_arg # 0 if none, otherwise in [1.._nargs], see function.pyx
1616
cdef _is_registered(self)
1717

1818
cdef class GinacFunction(BuiltinFunction):

src/sage/symbolic/function.pyx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -886,7 +886,7 @@ cdef class BuiltinFunction(Function):
886886
sage: c(pi/2) # needs sage.symbolic
887887
0
888888
"""
889-
self._preserved_arg = preserved_arg
889+
self._preserved_arg = 0 if preserved_arg is None else preserved_arg
890890
if preserved_arg and (preserved_arg < 1 or preserved_arg > nargs):
891891
raise ValueError("preserved_arg must be between 1 and nargs")
892892

@@ -913,6 +913,13 @@ cdef class BuiltinFunction(Function):
913913
univariate functions. Multivariate symbolic functions should override
914914
it as appropriate.
915915
916+
Note that it is mandatory for multivariate symbolic functions to
917+
override this function in order to allow delegating to the method
918+
implemented on the element.
919+
For example, ``binomial(n, k)`` tries to call ``n.binomial(k)``
920+
because :meth:`sage.functions.other.Function_binomial._method_arguments`
921+
is implemented.
922+
916923
EXAMPLES::
917924
918925
sage: zeta._method_arguments(1)
@@ -983,7 +990,7 @@ cdef class BuiltinFunction(Function):
983990
'foo'
984991
"""
985992
res = None
986-
if args and not hold:
993+
if args and not hold and not all(isinstance(arg, Element) for arg in args):
987994
# try calling the relevant math, cmath, mpmath or numpy function.
988995
# And as a fallback try the custom self._eval_numpy_ or
989996
# self._eval_mpmath_
@@ -1046,8 +1053,6 @@ cdef class BuiltinFunction(Function):
10461053
res = super().__call__(
10471054
*args, coerce=coerce, hold=hold)
10481055

1049-
# Convert the output back to the corresponding
1050-
# Python type if possible.
10511056
if any(isinstance(x, Element) for x in args):
10521057
if (self._preserved_arg
10531058
and isinstance(args[self._preserved_arg-1], Element)):
@@ -1072,6 +1077,8 @@ cdef class BuiltinFunction(Function):
10721077
if not isinstance(res, Element):
10731078
return res
10741079

1080+
# Convert the output back to the corresponding
1081+
# Python type if possible.
10751082
p = res.parent()
10761083
from sage.rings.complex_double import CDF
10771084
from sage.rings.integer_ring import ZZ

0 commit comments

Comments
 (0)