Ticket #1833: trac-1833.patch

File trac-1833.patch, 7.9 KB (added by was, 12 years ago)
  • sage/plot/plot3d/all.py

    # HG changeset patch
    # User William Stein <wstein@gmail.com>
    # Date 1200673284 28800
    # Node ID b9a91aae0cef44760155acd7580732ed07174650
    # Parent  ed92b4e4e4ea6f35cd7fa529c5a242df3cf4b373
    trac #1833 and #1737 -- 3d plot optimizations
    
    diff -r ed92b4e4e4ea -r b9a91aae0cef sage/plot/plot3d/all.py
    a b  
    11
    2 from plot3d            import plot3d, plot3d_adaptive
     2from plot3d            import plot3d
    33from parametric_plot3d import parametric_plot3d
    44from list_plot3d       import list_plot3d
    55
  • sage/plot/plot3d/parametric_plot3d.py

    diff -r ed92b4e4e4ea -r b9a91aae0cef sage/plot/plot3d/parametric_plot3d.py
    a b def parametric_plot3d(f, urange, vrange= 
    3030    INPUT:
    3131        f -- a 3-tuple of functions or expressions
    3232        urange -- a 2-tuple (u_min, u_max) or a 3-tuple (u, u_min, u_max)
    33         vrange -- (optional -- only used for surfaces) a 2-tuple (u_min, u_max)
    34                   or a 3-tuple (u, u_min, u_max)       
     33        vrange -- (optional -- only used for surfaces) a 2-tuple (v_min, v_max)
     34                  or a 3-tuple (v, v_min, v_max)       
    3535        plot_points -- (default: "automatic", which is 75 for curves and
    3636                       [15,15] for surfaces) initial number of sample
    3737                       points in each parameter; an integer for a curve,
    def parametric_plot3d_curve(f, urange, p 
    179179    u, vals = var_and_list_of_values(urange, plot_points)
    180180    w = []
    181181    fail = 0
    182    
     182
     183    if u is None:
     184        try:
     185            f, u, v = adapt_if_symbolic(f)
     186        except TypeError:
     187            pass
     188
    183189    if u is None:
    184190        f_x, f_y, f_z = f
    185191        for t in vals:
    def parametric_plot3d_surface(f, urange, 
    212218    u, u_vals = var_and_list_of_values(urange, int(points0))
    213219    v, v_vals = var_and_list_of_values(vrange, int(points1))
    214220
     221    if u is None and v is None:
     222        try:
     223            f, u, v = adapt_if_symbolic(f)
     224        except TypeError:
     225            pass
     226           
    215227    if u is None:
    216228        if not v is None:
    217229            raise ValueError, "both ranges must specify a variable or neither must"
    def parametric_plot3d_surface(f, urange, 
    233245        return (float(f_x(x,y)), float(f_y(x,y)), float(f_z(x,y)))
    234246
    235247    return ParametricSurface(g, (u_vals, v_vals), **kwds)
     248
     249
     250
     251def adapt_if_symbolic(f):
     252    """
     253    If f is symbolic find the variables u, v to substitute into f.
     254    Otherwise raise a TypeError.
     255
     256    This function is used internally by the plot commands for
     257    efficiency reasons only.
     258    """
     259    from sage.calculus.calculus import is_SymbolicExpression, SR
     260    if sum([is_SymbolicExpression(a) for a in f]) > 0:
     261        g = [SR(a) for a in f]
     262        vars = list(set(sum([list(a.variables()) for a in g], [])))
     263        vars.sort()
     264        if len(vars) > 0:
     265            u = vars[0]
     266            if len(vars) > 1:
     267                v = vars[1]
     268            else:
     269                v = None
     270            return g, u, v
     271        else:
     272            g = [lambda x: float(a) for a in g]
     273            return g, None, None
     274       
  • sage/plot/plot3d/plot3d.py

    diff -r ed92b4e4e4ea -r b9a91aae0cef sage/plot/plot3d/plot3d.py
    a b r""" 
    11r"""
    22Plotting Functions.
    33
    4 EXAMPLES: 
     4EXAMPLES:
    55    sage: def f(x,y):
    66    ...       return math.sin(y*y+x*x)/math.sqrt(x*x+y*y+.0001)
    77    ...
    8     sage: P = plot3d_adaptive(f,(-3,3),(-3,3), color=rainbow(60, 'rgbtuple'), max_bend=.1, max_depth=15)
     8    sage: P = plot3d(f,(-3,3),(-3,3), adaptive=True, color=rainbow(60, 'rgbtuple'), max_bend=.1, max_depth=15)
    99    sage: P.show()
    1010
    1111    sage: def f(x,y):
    1212    ...       return math.exp(x/5)*math.sin(y)
    1313    ...
    14     sage: P = plot3d_adaptive(f,(-5,5),(-5,5), color=['red','yellow'])
     14    sage: P = plot3d(f,(-5,5),(-5,5), adaptive=True, color=['red','yellow'])
    1515    sage: from sage.plot.plot3d.plot3d import axes
    1616    sage: S = P + axes(6, color='black')
    1717    sage: S.show()
    We plot "cape man": 
    2626    sage: S += sphere((.45, .1,.15),size=.1, color='white') + sphere((.51, .1,.17), size=.05, color='black')
    2727    sage: S += sphere((.5,0,-.2),size=.1, color='yellow')
    2828    sage: def f(x,y): return math.exp(x/5)*math.cos(y)
    29     sage: P = plot3d_adaptive(f,(-5,5),(-5,5), ['red','yellow'], max_depth=10)
     29    sage: P = plot3d(f,(-5,5),(-5,5), adaptive=True, color=['red','yellow'], max_depth=10)
    3030    sage: cape_man = P.scale(.2) + S.translate(1,0,0)
    31     sage: cape_man
     31    sage: cape_man.show(aspect_ratio=[1,1,1])
    3232
    3333AUTHOR:
    3434    -- Tom Boothby: adaptive refinement triangles
    class TrivialTriangleFactory: 
    7171        return [a,b,c]
    7272
    7373import parametric_plot3d
    74 def plot3d(f, urange, vrange, **kwds):
     74def plot3d(f, urange, vrange, adaptive=False, **kwds):
    7575    """
     76    INPUT:
     77        f -- a symbolic expression or function of 2 variables
     78        urange -- a 2-tuple (u_min, u_max) or a 3-tuple (u, u_min, u_max)
     79        vrange -- a 2-tuple (v_min, v_max) or a 3-tuple (v, v_min, v_max)
     80        adaptive -- (default: False) whether to use adaptive refinement
     81                    to draw the plot (slower, but may look better)
     82   
    7683    EXAMPLES:
    7784    We plot a 3d function defined as a Python function:
    7885        sage: plot3d(lambda x, y: x^2 + y^2, (-2,2), (-2,2))
     86
     87    We plot the same 3d function but using adaptive refinement:
     88        sage: plot3d(lambda x, y: x^2 + y^2, (-2,2), (-2,2), adaptive=True)
     89
     90    Adaptive refinement but with more points:
     91        sage: plot3d(lambda x, y: x^2 + y^2, (-2,2), (-2,2), adaptive=True, initial_depth=5)
    7992
    8093    We plot some 3d symbolic functions:
    8194        sage: x, y = var('x,y')
    def plot3d(f, urange, vrange, **kwds): 
    8497
    8598    Two wobby translucent planes:
    8699        sage: x,y = var('x,y')
    87         sage: P = plot3d(x+y+sin(x*y), (x,-10,10),(y,-10,10), opacity=0.87)
     100        sage: P = plot3d(x+y+sin(x*y), (x,-10,10),(y,-10,10), opacity=0.87, color='blue')
    88101        sage: Q = plot3d(x-2*y-cos(x*y),(x,-10,10),(y,-10,10),opacity=0.3,color='red')
    89102        sage: P + Q
    90103
    def plot3d(f, urange, vrange, **kwds): 
    95108        sage: L + P + Q
    96109    """
    97110    if len(urange) == 2:
    98         w = (lambda u,v: u, lambda u,v: v, f)
     111        from parametric_plot3d import adapt_if_symbolic
     112        try:
     113            f, u,v = adapt_if_symbolic((f,1,1))
     114            f = f[0]
     115            w = (u, v, f)
     116            urange = (u, urange[0], urange[1])
     117            vrange = (v, vrange[0], vrange[1])           
     118        except TypeError:
     119            w = (lambda u,v: u, lambda u,v: v, f)
    99120    else:
    100121        u = urange[0]
    101122        v = vrange[0]
    102123        w = (u, v, f)
    103     P = parametric_plot3d.parametric_plot3d(w, urange, vrange, **kwds)
     124
     125    if adaptive:
     126        P = plot3d_adaptive(f, urange, vrange, **kwds)
     127    else:
     128        P = parametric_plot3d.parametric_plot3d(w, urange, vrange, **kwds)
    104129    P.frame_aspect_ratio([1.0,1.0,0.5])
    105130    return P
    106131
    107132def plot3d_adaptive(f, x_range, y_range, color="automatic",
    108133                    grad_f=None,
    109134                    max_bend=.5, max_depth=5, initial_depth=4, num_colors=128, **kwds):
    110     """
     135    r"""
    111136    Adaptive 3d plotting of a function of two variables.
     137
     138    This is used internally by the plot3d command when the option
     139    \code{adaptive=True} is given.
    112140
    113141    INPUT:
    114142        f -- a symbolic function or a Python function of 3 variables.
    def plot3d_adaptive(f, x_range, y_range, 
    123151        **kwds -- standard graphics parameters
    124152   
    125153    EXAMPLES:
    126     We plot sin(xy):
     154    We plot $\sin(xy)$:
     155        sage: from sage.plot.plot3d.plot3d import plot3d_adaptive
    127156        sage: x,y=var('x,y'); plot3d_adaptive(sin(x*y), (x,-pi,pi), (y,-pi,pi), initial_depth=5)
    128157
    129158    """