Ticket #13355: plot_with_complex_intermediates.patch

File plot_with_complex_intermediates.patch, 5.3 KB (added by tkluck, 7 years ago)
  • sage/ext/fast_callable.pyx

    # HG changeset patch
    # User Timo Kluck <tkluck@infty.nl>
    # Date 1344514850 -7200
    # Node ID d683f2edd6b10f1e8b770dec7ebd761492c4a176
    # Parent  5528318fe402ade6c066fdea57dee958819c8494
    Fix plotting with complex intermediates
    
    diff --git a/sage/ext/fast_callable.pyx b/sage/ext/fast_callable.pyx
    a b  
    383383        sage: fc = fast_callable(expr, domain=float)
    384384        sage: fc(5, 7)
    385385        0.5514266812416906
     386
     387    Check that fast_callable also works for symbolic functions with evaluation
     388    functions:
     389
     390        sage: def evalf_func(self, x, y, parent): return parent(x*y)
     391        sage: x,y = var('x,y')
     392        sage: f = function('f', evalf_func=evalf_func)
     393        sage: fc = fast_callable(f(x,y), vars=[x,y])
     394        sage: fc(3,4)
     395        12.0
    386396    """
    387397    cdef Expression et
    388398    if isinstance(x, Expression):
  • sage/symbolic/expression.pyx

    diff --git a/sage/symbolic/expression.pyx b/sage/symbolic/expression.pyx
    a b  
    86928692        from sage.symbolic.expression_conversions import fast_float
    86938693        return fast_float(self, *vars)
    86948694
     8695
    86958696    def _fast_callable_(self, etb):
    86968697        """
    86978698        Given an ExpressionTreeBuilder *etb*, return an Expression representing
     
    88368837            sage: abs((I*10+1)^4)
    88378838            10201
    88388839            sage: plot(s)
     8840
     8841        Check that this also works when we plot a function that implicitely
     8842        takes complex values:
     8843
     8844            sage: f = function('f', evalf_func=lambda self,x,parent: I*x)
     8845            sage: plot(abs(f(x)), 0,5)
    88398846        """
    88408847        try:
    88418848            # First we try fast float.  However, this doesn't work on some
  • sage/symbolic/expression_conversions.py

    diff --git a/sage/symbolic/expression_conversions.py b/sage/symbolic/expression_conversions.py
    a b  
    12381238            1.41421356237309...
    12391239        """
    12401240        f = operator
     1241        if f.range_for_domain(float) != float:
     1242            raise TypeError("Cannot use fast_float to calculate a function with complex intermediates")
    12411243        g = map(self, ex.operands())
    12421244        try:
    12431245            return f(*g)
     
    14051407            sin(sqrt(add(v_0, v_1)))
    14061408            sage: arctan2(x,y)._fast_callable_(etb)
    14071409            {arctan2}(v_0, v_1)
     1410            sage: def evalf_func(self, x, y, parent): return parent(x*y)
     1411            sage: f = function('f', evalf_func=evalf_func)
     1412            sage: f(x,y)._fast_callable_(etb)
     1413            {evalf_func}(v_0, v_1, <type 'float'>)
    14081414        """
    1409         return self.etb.call(function, *ex.operands())
     1415        try:
     1416            domain = self.etb._domain
     1417            if domain == None:
     1418                domain = float
     1419            return self.etb.call(function._evalf_, *(ex.operands() + [domain]))
     1420        except AttributeError:
     1421            return self.etb.call(function, *ex.operands())
    14101422
    14111423
    14121424def fast_callable(ex, etb):
  • sage/symbolic/function.pyx

    diff --git a/sage/symbolic/function.pyx b/sage/symbolic/function.pyx
    a b  
    634634        """
    635635        raise NotImplementedError("The Function %s does not support numpy arrays as arguments" % self.name())
    636636
     637    def range_for_domain(self, domain):
     638        """
     639        Return the parent of self(x) when x is an element of domain
     640
     641        It is very common for functions to return real values when given a real value
     642        and complex values when given a complex value. Such functions can specify that
     643        by overriding this function, which will enable certain optimizations.
     644
     645        The default implementation returns the complex field corresponding to domain,
     646        and `complex` if it cannot find one.
     647
     648        Default behaviour:
     649
     650            sage: f = function('f')
     651            sage: f.range_for_domain(float)
     652            <type 'complex'>
     653            sage: f.range_for_domain(RR)
     654            Complex Field with 53 bits of precision
     655
     656        Common behaviour:
     657
     658            sage: sin.range_for_domain(float)
     659            <type 'float'>
     660            sage: sin.range_for_domain(RR)
     661            Real Field with 53 bits of precision
     662            sage: sin.range_for_domain(CC)
     663            Complex Field with 53 bits of precision
     664        """
     665
     666        try:
     667            return domain.complex_field()
     668        except AttributeError:
     669            return complex
     670
    637671cdef class GinacFunction(BuiltinFunction):
    638672    """
    639673    This class provides a wrapper around symbolic functions already defined in
     
    863897            # we should never end up here
    864898            raise ValueError, "cannot read pickle"
    865899
     900    def range_for_domain(self, domain):
     901        """
     902        Return the parent of self(x) when x is an element of domain
     903
     904        All builtin functions return real values when given a real value
     905        and complex values when given a complex value. We specify that
     906        in this override.
     907
     908        Behaviour for builtin functions:
     909
     910            sage: sin.range_for_domain(float)
     911            <type 'float'>
     912            sage: sin.range_for_domain(RR)
     913            Real Field with 53 bits of precision
     914            sage: sin.range_for_domain(CC)
     915            Complex Field with 53 bits of precision
     916        """
     917        return domain
     918
    866919
    867920cdef class SymbolicFunction(Function):
    868921    """