Ticket #13933: trac_13933-move_call.patch

File trac_13933-move_call.patch, 5.4 KB (added by Burcin Erocal, 10 years ago)
  • sage/symbolic/function.pyx

    # HG changeset patch
    # User Burcin Erocal <burcin@erocal.org>
    # Date 1319973071 -3600
    # Node ID 590885bf61de248ba009dd33b9c34cfee92d1e01
    # Parent  751a1a82948213d97027ffcb8ee7204989b44ade
    Create fast numeric evaluation path for special functions.
    
    Most Sage types define methods for numeric special function evaluation. The
    GinacFunction class defines a __call__() method to utilize these methods when
    they exists. Moving the definition of this __call__() method up one level in
    the inheritance diagram to BuiltinFunction allows more symbolic functions to
    take advantage of this optimization.
    
    diff --git a/sage/symbolic/function.pyx b/sage/symbolic/function.pyx
    a b  
    721721
    722722        g_foptions_assign(g_registered_functions().index(self._serial), opt)
    723723
    724     def __call__(self, *args, coerce=True, hold=False,
    725             dont_call_method_on_arg=False):
    726         """
    727         Evaluate this function on the given arguments and return the result.
    728 
    729         EXAMPLES::
    730 
    731             sage: exp(5)
    732             e^5
    733             sage: gamma(15)
    734             87178291200
    735         """
    736         # we want to convert the result to the original parent if the input
    737         # is not exact, so we store the parent here
    738         org_parent = parent_c(args[0])
    739        
    740         # if there is only one argument, and the argument has an attribute
    741         # with the same name as this function, try to call it to get the result
    742         # The argument dont_call_method_on_arg is used to prevent infinite loops
    743         # when .exp(), .log(), etc. methods call this symbolic function on
    744         # themselves
    745         if len(args) == 1 and not hold and not dont_call_method_on_arg and \
    746                 hasattr(args[0], self._name):
    747             return getattr(args[0], self._name)()
    748 
    749         res = super(GinacFunction, self).__call__(*args, coerce=coerce,
    750                 hold=hold)
    751 
    752         # convert the result back to the original parent previously stored
    753         # otherwise we end up with
    754         #     sage: arctan(RR(1))
    755         #     1/4*pi
    756         # which is surprising, to say the least...
    757         if org_parent is not SR and \
    758                 (org_parent is float or org_parent is complex or \
    759                 (PY_TYPE_CHECK(org_parent, Parent) and \
    760                     not org_parent.is_exact())):
    761             try:
    762                 return org_parent(res)
    763             except (TypeError, ValueError):
    764                 pass
    765 
    766             # conversion to the original parent failed
    767             # we try if it works with the corresponding complex domain
    768             if org_parent is float:
    769                 try:
    770                     return complex(res)
    771                 except (TypeError, ValueError):
    772                     pass
    773             elif hasattr(org_parent, 'complex_field'):
    774                 try:
    775                     return org_parent.complex_field()(res)
    776                 except (TypeError, ValueError):
    777                     pass
    778 
    779         return res
    780724
    781725
    782726cdef class BuiltinFunction(Function):
     
    883827            # we should never end up here
    884828            raise ValueError, "cannot read pickle"
    885829
     830    def __call__(self, *args, coerce=True, hold=False,
     831            dont_call_method_on_arg=False):
     832        """
     833        Evaluate this function on the given arguments and return the result.
     834
     835        EXAMPLES::
     836
     837            sage: exp(5)
     838            e^5
     839            sage: gamma(15)
     840            87178291200
     841        """
     842        # we want to convert the result to the original parent if the input
     843        # is not exact, so we store the parent here
     844        org_parent = parent_c(args[0])
     845
     846        # if there is only one argument, and the argument has an attribute
     847        # with the same name as this function, try to call it to get the result
     848        # The argument dont_call_method_on_arg is used to prevent infinite loops
     849        # when .exp(), .log(), etc. methods call this symbolic function on
     850        # themselves
     851        if len(args) == 1 and not hold and not dont_call_method_on_arg:
     852            try:
     853                return getattr(args[0], self._name)()
     854            except AttributeError:
     855                pass
     856
     857        res = super(BuiltinFunction, self).__call__(*args, coerce=coerce,
     858                hold=hold)
     859
     860        # convert the result back to the original parent previously stored
     861        # otherwise we end up with
     862        #     sage: arctan(RR(1))
     863        #     1/4*pi
     864        # which is surprising, to say the least...
     865        if org_parent is not SR and \
     866                (org_parent is float or org_parent is complex or \
     867                (PY_TYPE_CHECK(org_parent, Parent) and \
     868                    not org_parent.is_exact())):
     869            try:
     870                return org_parent(res)
     871            except (TypeError, ValueError):
     872                pass
     873
     874            # conversion to the original parent failed
     875            # we try if it works with the corresponding complex domain
     876            if org_parent is float:
     877                try:
     878                    return complex(res)
     879                except (TypeError, ValueError):
     880                    pass
     881            elif hasattr(org_parent, 'complex_field'):
     882                try:
     883                    return org_parent.complex_field()(res)
     884                except (TypeError, ValueError):
     885                    pass
     886
     887        return res
    886888
    887889cdef class SymbolicFunction(Function):
    888890    """