Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit c8c26e1

Browse files
committed
Convert Ginac function results to the correct parent
1 parent a486db2 commit c8c26e1

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

src/sage/symbolic/function.pyx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Classes for symbolic functions
1515

1616
from ginac cimport *
1717

18+
from sage.rings.integer cimport smallInteger
1819
from sage.structure.sage_object cimport SageObject
1920
from expression cimport new_Expression_from_GEx, Expression
2021
from ring import SR
@@ -809,6 +810,46 @@ cdef class GinacFunction(BuiltinFunction):
809810
BuiltinFunction.__init__(self, name, nargs, latex_name, conversions,
810811
evalf_params_first=evalf_params_first)
811812

813+
def __call__(self, *args, **kwds):
814+
"""
815+
Wrapper around ``BuiltinFunction.__call__()`` which converts
816+
Python ``int``s which are returned by Ginac to Sage Integers.
817+
818+
This is needed to fix :trac:`10133`, where Ginac evaluates
819+
``sin(0)`` to the Python int ``0``::
820+
821+
sage: from sage.symbolic.function import BuiltinFunction
822+
sage: out = BuiltinFunction.__call__(sin, 0)
823+
sage: out, parent(out)
824+
(0, <type 'int'>)
825+
826+
With this wrapper we have::
827+
828+
sage: out = sin(0)
829+
sage: out, parent(out)
830+
(0, Integer Ring)
831+
832+
However, if all inputs are Python types, we do not convert::
833+
834+
sage: out = sin(int(0))
835+
sage: (out, parent(out))
836+
(0, <type 'int'>)
837+
sage: out = arctan2(int(0), float(1))
838+
sage: (out, parent(out))
839+
(0, <type 'int'>)
840+
sage: out = arctan2(int(0), RR(1))
841+
sage: (out, parent(out))
842+
(0, Integer Ring)
843+
"""
844+
res = super(GinacFunction, self).__call__(*args, **kwds)
845+
846+
# Convert to Integer if the output was of type "int" and any of
847+
# the inputs was a Sage Element
848+
if isinstance(res, int) and any(isinstance(x, Element) for x in args):
849+
return smallInteger(res)
850+
else:
851+
return res
852+
812853
cdef _is_registered(self):
813854
# Since this is function is defined in C++, it is already in
814855
# ginac's function registry

0 commit comments

Comments
 (0)