Ticket #1173: trac_1173-move_call.patch

File trac_1173-move_call.patch, 5.4 KB (added by burcin, 6 years ago)
  • sage/symbolic/function.pyx

    # HG changeset patch
    # User Burcin Erocal <burcin@erocal.org>
    # Date 1319973071 -3600
    # Node ID ea60adae7e78a92592fd03fb707908e2c851de69
    # Parent  d740726a92bc0eef8e372e0a59c37b6cdf0a84b0
    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  
    689689
    690690        g_foptions_assign(g_registered_functions().index(self._serial), opt)
    691691
    692     def __call__(self, *args, coerce=True, hold=False,
    693             dont_call_method_on_arg=False):
    694         """
    695         Evaluate this function on the given arguments and return the result.
    696 
    697         EXAMPLES::
    698 
    699             sage: exp(5)
    700             e^5
    701             sage: gamma(15)
    702             87178291200
    703         """
    704         # we want to convert the result to the original parent if the input
    705         # is not exact, so we store the parent here
    706         org_parent = parent_c(args[0])
    707        
    708         # if there is only one argument, and the argument has an attribute
    709         # with the same name as this function, try to call it to get the result
    710         # The argument dont_call_method_on_arg is used to prevent infinite loops
    711         # when .exp(), .log(), etc. methods call this symbolic function on
    712         # themselves
    713         if len(args) == 1 and not hold and not dont_call_method_on_arg and \
    714                 hasattr(args[0], self._name):
    715             return getattr(args[0], self._name)()
    716 
    717         res = super(GinacFunction, self).__call__(*args, coerce=coerce,
    718                 hold=hold)
    719 
    720         # convert the result back to the original parent previously stored
    721         # otherwise we end up with
    722         #     sage: arctan(RR(1))
    723         #     1/4*pi
    724         # which is surprising, to say the least...
    725         if org_parent is not SR and \
    726                 (org_parent is float or org_parent is complex or \
    727                 (PY_TYPE_CHECK(org_parent, Parent) and \
    728                     not org_parent.is_exact())):
    729             try:
    730                 return org_parent(res)
    731             except (TypeError, ValueError):
    732                 pass
    733 
    734             # conversion to the original parent failed
    735             # we try if it works with the corresponding complex domain
    736             if org_parent is float:
    737                 try:
    738                     return complex(res)
    739                 except (TypeError, ValueError):
    740                     pass
    741             elif hasattr(org_parent, 'complex_field'):
    742                 try:
    743                     return org_parent.complex_field()(res)
    744                 except (TypeError, ValueError):
    745                     pass
    746 
    747         return res
    748692
    749693
    750694cdef class BuiltinFunction(Function):
     
    831775            # we should never end up here
    832776            raise ValueError, "cannot read pickle"
    833777
     778    def __call__(self, *args, coerce=True, hold=False,
     779            dont_call_method_on_arg=False):
     780        """
     781        Evaluate this function on the given arguments and return the result.
     782
     783        EXAMPLES::
     784
     785            sage: exp(5)
     786            e^5
     787            sage: gamma(15)
     788            87178291200
     789        """
     790        # we want to convert the result to the original parent if the input
     791        # is not exact, so we store the parent here
     792        org_parent = parent_c(args[0])
     793
     794        # if there is only one argument, and the argument has an attribute
     795        # with the same name as this function, try to call it to get the result
     796        # The argument dont_call_method_on_arg is used to prevent infinite loops
     797        # when .exp(), .log(), etc. methods call this symbolic function on
     798        # themselves
     799        if len(args) == 1 and not hold and not dont_call_method_on_arg:
     800            try:
     801                return getattr(args[0], self._name)()
     802            except AttributeError:
     803                pass
     804
     805        res = super(BuiltinFunction, self).__call__(*args, coerce=coerce,
     806                hold=hold)
     807
     808        # convert the result back to the original parent previously stored
     809        # otherwise we end up with
     810        #     sage: arctan(RR(1))
     811        #     1/4*pi
     812        # which is surprising, to say the least...
     813        if org_parent is not SR and \
     814                (org_parent is float or org_parent is complex or \
     815                (PY_TYPE_CHECK(org_parent, Parent) and \
     816                    not org_parent.is_exact())):
     817            try:
     818                return org_parent(res)
     819            except (TypeError, ValueError):
     820                pass
     821
     822            # conversion to the original parent failed
     823            # we try if it works with the corresponding complex domain
     824            if org_parent is float:
     825                try:
     826                    return complex(res)
     827                except (TypeError, ValueError):
     828                    pass
     829            elif hasattr(org_parent, 'complex_field'):
     830                try:
     831                    return org_parent.complex_field()(res)
     832                except (TypeError, ValueError):
     833                    pass
     834
     835        return res
    834836
    835837cdef class SymbolicFunction(Function):
    836838    """