def Gsmall_fast_float(r, MAX=20): from sage.ext.fast_eval import fast_float_arg, fast_float_constant, fast_float_func x = fast_float_arg(0) return Pr_poly(r, RDF) (-log(x)) + CG(r,x)
def plot3d(f, urange, vrange, adaptive=False, transformation=None, **kwds): """ INPUT: - ``f`` - a symbolic expression or function of 2 variables - ``urange`` - a 2-tuple (u_min, u_max) or a 3-tuple (u, u_min, u_max) - ``vrange`` - a 2-tuple (v_min, v_max) or a 3-tuple (v, v_min, v_max) - ``adaptive`` - (default: False) whether to use adaptive refinement to draw the plot (slower, but may look better). This option does NOT work in conjuction with a transformation (see below). - ``mesh`` - bool (default: False) whether to display mesh grid lines - ``dots`` - bool (default: False) whether to display dots at mesh grid points - ``plot_points`` - (default: "automatic") initial number of sample points in each direction; an integer or a pair of integers - ``transformation`` - (default: None) a transformation to apply. May be a 3 or 4-tuple (x_func, y_func, z_func, independent_vars) where the first 3 items indicate a transformation to Cartesian coordinates (from your coordinate system) in terms of u, v, and the function variable fvar (for which the value of f will be substituted). If a 3-tuple is specified, the independent variables are chosen from the range variables. If a 4-tuple is specified, the 4th element is a list of independent variables. ``transformation`` may also be a predefined coordinate system transformation like Spherical or Cylindrical. .. note:: ``mesh`` and ``dots`` are not supported when using the Tachyon raytracer renderer. EXAMPLES: We plot a 3d function defined as a Python function:: sage: plot3d(lambda x, y: x^2 + y^2, (-2,2), (-2,2)) Graphics3d Object .. PLOT:: sphinx_plot(plot3d(lambda x, y: x**2 + y**2, (-2,2), (-2,2))) We plot the same 3d function but using adaptive refinement:: sage: plot3d(lambda x, y: x^2 + y^2, (-2,2), (-2,2), adaptive=True) Graphics3d Object .. PLOT:: sphinx_plot(plot3d(lambda x, y: x**2 + y**2, (-2,2), (-2,2), adaptive=True)) Adaptive refinement but with more points:: sage: plot3d(lambda x, y: x^2 + y^2, (-2,2), (-2,2), adaptive=True, initial_depth=5) Graphics3d Object .. PLOT:: sphinx_plot(plot3d(lambda x, y: x**2 + y**2, (-2,2), (-2,2), adaptive=True, initial_depth=5)) We plot some 3d symbolic functions:: sage: var('x,y') (x, y) sage: plot3d(x^2 + y^2, (x,-2,2), (y,-2,2)) Graphics3d Object .. PLOT:: var('x y') sphinx_plot(plot3d(x**2 + y**2, (x,-2,2), (y,-2,2))) :: sage: plot3d(sin(x*y), (x, -pi, pi), (y, -pi, pi)) Graphics3d Object .. PLOT:: var('x y') sphinx_plot(plot3d(sin(x*y), (x, -pi, pi), (y, -pi, pi))) We give a plot with extra sample points:: sage: var('x,y') (x, y) sage: plot3d(sin(x^2+y^2),(x,-5,5),(y,-5,5), plot_points=200) Graphics3d Object .. PLOT:: var('x y') sphinx_plot(plot3d(sin(x**2+y**2),(x,-5,5),(y,-5,5), plot_points=200)) :: sage: plot3d(sin(x^2+y^2),(x,-5,5),(y,-5,5), plot_points=[10,100]) Graphics3d Object .. PLOT:: var('x y') sphinx_plot(plot3d(sin(x**2+y**2),(x,-5,5),(y,-5,5), plot_points=[10,100])) A 3d plot with a mesh:: sage: var('x,y') (x, y) sage: plot3d(sin(x-y)*y*cos(x),(x,-3,3),(y,-3,3), mesh=True) Graphics3d Object .. PLOT:: var('x y') sphinx_plot(plot3d(sin(x-y)*y*cos(x),(x,-3,3),(y,-3,3), mesh=True)) Two wobby translucent planes:: sage: x,y = var('x,y') sage: P = plot3d(x+y+sin(x*y), (x,-10,10),(y,-10,10), opacity=0.87, color='blue') sage: Q = plot3d(x-2*y-cos(x*y),(x,-10,10),(y,-10,10),opacity=0.3,color='red') sage: P + Q Graphics3d Object .. PLOT:: x,y=var('x y') P = plot3d(x+y+sin(x*y), (x,-10,10),(y,-10,10), opacity=0.87, color='blue') Q = plot3d(x-2*y-cos(x*y),(x,-10,10),(y,-10,10),opacity=0.3,color='red') sphinx_plot(P+Q) We draw two parametric surfaces and a transparent plane:: sage: L = plot3d(lambda x,y: 0, (-5,5), (-5,5), color="lightblue", opacity=0.8) sage: P = plot3d(lambda x,y: 4 - x^3 - y^2, (-2,2), (-2,2), color='green') sage: Q = plot3d(lambda x,y: x^3 + y^2 - 4, (-2,2), (-2,2), color='orange') sage: L + P + Q Graphics3d Object .. PLOT:: L = plot3d(lambda x,y: 0, (-5,5), (-5,5), color="lightblue", opacity=0.8) P = plot3d(lambda x,y: 4 - x**3 - y**2, (-2,2), (-2,2), color='green') Q = plot3d(lambda x,y: x**3 + y**2 - 4, (-2,2), (-2,2), color='orange') sphinx_plot(L+P+Q) We draw the "Sinus" function (water ripple-like surface):: sage: x, y = var('x y') sage: plot3d(sin(pi*(x^2+y^2))/2,(x,-1,1),(y,-1,1)) Graphics3d Object .. PLOT:: x, y = var('x y') sphinx_plot(plot3d(sin(pi*(x**2+y**2))/2,(x,-1,1),(y,-1,1))) Hill and valley (flat surface with a bump and a dent):: sage: x, y = var('x y') sage: plot3d( 4*x*exp(-x^2-y^2), (x,-2,2), (y,-2,2)) Graphics3d Object .. PLOT:: x, y = var('x y') sphinx_plot(plot3d( 4*x*exp(-x**2-y**2), (x,-2,2), (y,-2,2))) An example of a transformation:: sage: r, phi, z = var('r phi z') sage: trans=(r*cos(phi),r*sin(phi),z) sage: plot3d(cos(r),(r,0,17*pi/2),(phi,0,2*pi),transformation=trans,opacity=0.87).show(aspect_ratio=(1,1,2),frame=False) .. PLOT:: r, phi, z = var('r phi z') trans = (r*cos(phi),r*sin(phi),z) P = plot3d(cos(r),(r,0,17*pi/2),(phi,0,2*pi),transformation=trans,opacity=0.87) P.aspect_ratio([1,1,2]) sphinx_plot(P) An example of a transformation with symbolic vector:: sage: cylindrical(r,theta,z)=[r*cos(theta),r*sin(theta),z] sage: plot3d(3,(theta,0,pi/2),(z,0,pi/2),transformation=cylindrical) Graphics3d Object .. PLOT:: r, theta, z = var('r theta z') cylindrical=(r*cos(theta),r*sin(theta),z) P = plot3d(z-z+3,(theta,0,pi/2),(z,0,pi/2),transformation=cylindrical) sphinx_plot(P) Many more examples of transformations:: sage: u, v, w = var('u v w') sage: rectangular=(u,v,w) sage: spherical=(w*cos(u)*sin(v),w*sin(u)*sin(v),w*cos(v)) sage: cylindric_radial=(w*cos(u),w*sin(u),v) sage: cylindric_axial=(v*cos(u),v*sin(u),w) sage: parabolic_cylindrical=(w*v,(v^2-w^2)/2,u) Plot a constant function of each of these to get an idea of what it does:: sage: A = plot3d(2,(u,-pi,pi),(v,0,pi),transformation=rectangular,plot_points=[100,100]) sage: B = plot3d(2,(u,-pi,pi),(v,0,pi),transformation=spherical,plot_points=[100,100]) sage: C = plot3d(2,(u,-pi,pi),(v,0,pi),transformation=cylindric_radial,plot_points=[100,100]) sage: D = plot3d(2,(u,-pi,pi),(v,0,pi),transformation=cylindric_axial,plot_points=[100,100]) sage: E = plot3d(2,(u,-pi,pi),(v,-pi,pi),transformation=parabolic_cylindrical,plot_points=[100,100]) sage: @interact ... def _(which_plot=[A,B,C,D,E]): ... show(which_plot) <html>... Now plot a function:: sage: g=3+sin(4*u)/2+cos(4*v)/2 sage: F = plot3d(g,(u,-pi,pi),(v,0,pi),transformation=rectangular,plot_points=[100,100]) sage: G = plot3d(g,(u,-pi,pi),(v,0,pi),transformation=spherical,plot_points=[100,100]) sage: H = plot3d(g,(u,-pi,pi),(v,0,pi),transformation=cylindric_radial,plot_points=[100,100]) sage: I = plot3d(g,(u,-pi,pi),(v,0,pi),transformation=cylindric_axial,plot_points=[100,100]) sage: J = plot3d(g,(u,-pi,pi),(v,0,pi),transformation=parabolic_cylindrical,plot_points=[100,100]) sage: @interact ... def _(which_plot=[F, G, H, I, J]): ... show(which_plot) <html>... TESTS: Make sure the transformation plots work:: sage: show(A + B + C + D + E) sage: show(F + G + H + I + J) Listing the same plot variable twice gives an error:: sage: x, y = var('x y') sage: plot3d( 4*x*exp(-x^2-y^2), (x,-2,2), (x,-2,2)) Traceback (most recent call last): ... ValueError: range variables should be distinct, but there are duplicates """ if transformation is not None: params=None from sage.symbolic.callable import is_CallableSymbolicExpression # First, determine the parameters for f (from the first item of urange # and vrange, preferably). if len(urange) == 3 and len(vrange) == 3: params = (urange[0], vrange[0]) elif is_CallableSymbolicExpression(f): params = f.variables() from sage.modules.vector_callable_symbolic_dense import Vector_callable_symbolic_dense if isinstance(transformation, (tuple, list,Vector_callable_symbolic_dense)): if len(transformation)==3: if params is None: raise ValueError("must specify independent variable names in the ranges when using generic transformation") indep_vars = params elif len(transformation)==4: indep_vars = transformation[3] transformation = transformation[0:3] else: raise ValueError("unknown transformation type") # find out which variable is the function variable by # eliminating the parameter variables. all_vars = set(sum([list(s.variables()) for s in transformation],[])) dep_var=all_vars - set(indep_vars) if len(dep_var)==1: dep_var = dep_var.pop() transformation = _ArbitraryCoordinates(transformation, dep_var, indep_vars) else: raise ValueError("unable to determine the function variable in the transform") if isinstance(transformation, _Coordinates): R = transformation.to_cartesian(f, params) return parametric_plot3d.parametric_plot3d(R, urange, vrange, **kwds) else: raise ValueError('unknown transformation type') elif adaptive: P = plot3d_adaptive(f, urange, vrange, **kwds) else: u=fast_float_arg(0) v=fast_float_arg(1) P=parametric_plot3d.parametric_plot3d((u,v,f), urange, vrange, **kwds) P.frame_aspect_ratio([1.0,1.0,0.5]) return P
def plot3d(f, urange, vrange, adaptive=False, transformation=None, **kwds): """ Plots a function in 3d. INPUT: - ``f`` - a symbolic expression or function of 2 variables - ``urange`` - a 2-tuple (u_min, u_max) or a 3-tuple (u, u_min, u_max) - ``vrange`` - a 2-tuple (v_min, v_max) or a 3-tuple (v, v_min, v_max) - ``adaptive`` - (default: False) whether to use adaptive refinement to draw the plot (slower, but may look better). This option does NOT work in conjunction with a transformation (see below). - ``mesh`` - bool (default: False) whether to display mesh grid lines - ``dots`` - bool (default: False) whether to display dots at mesh grid points - ``plot_points`` - (default: "automatic") initial number of sample points in each direction; an integer or a pair of integers - ``transformation`` - (default: None) a transformation to apply. May be a 3 or 4-tuple (x_func, y_func, z_func, independent_vars) where the first 3 items indicate a transformation to Cartesian coordinates (from your coordinate system) in terms of u, v, and the function variable fvar (for which the value of f will be substituted). If a 3-tuple is specified, the independent variables are chosen from the range variables. If a 4-tuple is specified, the 4th element is a list of independent variables. ``transformation`` may also be a predefined coordinate system transformation like Spherical or Cylindrical. .. note:: ``mesh`` and ``dots`` are not supported when using the Tachyon raytracer renderer. EXAMPLES: We plot a 3d function defined as a Python function:: sage: plot3d(lambda x, y: x^2 + y^2, (-2,2), (-2,2)) Graphics3d Object .. PLOT:: sphinx_plot(plot3d(lambda x, y: x**2 + y**2, (-2,2), (-2,2))) We plot the same 3d function but using adaptive refinement:: sage: plot3d(lambda x, y: x^2 + y^2, (-2,2), (-2,2), adaptive=True) Graphics3d Object .. PLOT:: sphinx_plot(plot3d(lambda x, y: x**2 + y**2, (-2,2), (-2,2), adaptive=True)) Adaptive refinement but with more points:: sage: plot3d(lambda x, y: x^2 + y^2, (-2,2), (-2,2), adaptive=True, initial_depth=5) Graphics3d Object .. PLOT:: sphinx_plot(plot3d(lambda x, y: x**2 + y**2, (-2,2), (-2,2), adaptive=True, initial_depth=5)) We plot some 3d symbolic functions:: sage: var('x,y') (x, y) sage: plot3d(x^2 + y^2, (x,-2,2), (y,-2,2)) Graphics3d Object .. PLOT:: var('x y') sphinx_plot(plot3d(x**2 + y**2, (x,-2,2), (y,-2,2))) :: sage: plot3d(sin(x*y), (x, -pi, pi), (y, -pi, pi)) Graphics3d Object .. PLOT:: var('x y') sphinx_plot(plot3d(sin(x*y), (x, -pi, pi), (y, -pi, pi))) We give a plot with extra sample points:: sage: var('x,y') (x, y) sage: plot3d(sin(x^2+y^2),(x,-5,5),(y,-5,5), plot_points=200) Graphics3d Object .. PLOT:: var('x y') sphinx_plot(plot3d(sin(x**2+y**2),(x,-5,5),(y,-5,5), plot_points=200)) :: sage: plot3d(sin(x^2+y^2),(x,-5,5),(y,-5,5), plot_points=[10,100]) Graphics3d Object .. PLOT:: var('x y') sphinx_plot(plot3d(sin(x**2+y**2),(x,-5,5),(y,-5,5), plot_points=[10,100])) A 3d plot with a mesh:: sage: var('x,y') (x, y) sage: plot3d(sin(x-y)*y*cos(x),(x,-3,3),(y,-3,3), mesh=True) Graphics3d Object .. PLOT:: var('x y') sphinx_plot(plot3d(sin(x-y)*y*cos(x),(x,-3,3),(y,-3,3), mesh=True)) Two wobby translucent planes:: sage: x,y = var('x,y') sage: P = plot3d(x+y+sin(x*y), (x,-10,10),(y,-10,10), opacity=0.87, color='blue') sage: Q = plot3d(x-2*y-cos(x*y),(x,-10,10),(y,-10,10),opacity=0.3,color='red') sage: P + Q Graphics3d Object .. PLOT:: x,y=var('x y') P = plot3d(x+y+sin(x*y), (x,-10,10),(y,-10,10), opacity=0.87, color='blue') Q = plot3d(x-2*y-cos(x*y),(x,-10,10),(y,-10,10),opacity=0.3,color='red') sphinx_plot(P+Q) We draw two parametric surfaces and a transparent plane:: sage: L = plot3d(lambda x,y: 0, (-5,5), (-5,5), color="lightblue", opacity=0.8) sage: P = plot3d(lambda x,y: 4 - x^3 - y^2, (-2,2), (-2,2), color='green') sage: Q = plot3d(lambda x,y: x^3 + y^2 - 4, (-2,2), (-2,2), color='orange') sage: L + P + Q Graphics3d Object .. PLOT:: L = plot3d(lambda x,y: 0, (-5,5), (-5,5), color="lightblue", opacity=0.8) P = plot3d(lambda x,y: 4 - x**3 - y**2, (-2,2), (-2,2), color='green') Q = plot3d(lambda x,y: x**3 + y**2 - 4, (-2,2), (-2,2), color='orange') sphinx_plot(L+P+Q) We draw the "Sinus" function (water ripple-like surface):: sage: x, y = var('x y') sage: plot3d(sin(pi*(x^2+y^2))/2,(x,-1,1),(y,-1,1)) Graphics3d Object .. PLOT:: x, y = var('x y') sphinx_plot(plot3d(sin(pi*(x**2+y**2))/2,(x,-1,1),(y,-1,1))) Hill and valley (flat surface with a bump and a dent):: sage: x, y = var('x y') sage: plot3d( 4*x*exp(-x^2-y^2), (x,-2,2), (y,-2,2)) Graphics3d Object .. PLOT:: x, y = var('x y') sphinx_plot(plot3d( 4*x*exp(-x**2-y**2), (x,-2,2), (y,-2,2))) An example of a transformation:: sage: r, phi, z = var('r phi z') sage: trans=(r*cos(phi),r*sin(phi),z) sage: plot3d(cos(r),(r,0,17*pi/2),(phi,0,2*pi),transformation=trans,opacity=0.87).show(aspect_ratio=(1,1,2),frame=False) .. PLOT:: r, phi, z = var('r phi z') trans = (r*cos(phi),r*sin(phi),z) P = plot3d(cos(r),(r,0,17*pi/2),(phi,0,2*pi),transformation=trans,opacity=0.87) P.aspect_ratio([1,1,2]) sphinx_plot(P) An example of a transformation with symbolic vector:: sage: cylindrical(r,theta,z)=[r*cos(theta),r*sin(theta),z] sage: plot3d(3,(theta,0,pi/2),(z,0,pi/2),transformation=cylindrical) Graphics3d Object .. PLOT:: r, theta, z = var('r theta z') cylindrical=(r*cos(theta),r*sin(theta),z) P = plot3d(z-z+3,(theta,0,pi/2),(z,0,pi/2),transformation=cylindrical) sphinx_plot(P) Many more examples of transformations:: sage: u, v, w = var('u v w') sage: rectangular=(u,v,w) sage: spherical=(w*cos(u)*sin(v),w*sin(u)*sin(v),w*cos(v)) sage: cylindric_radial=(w*cos(u),w*sin(u),v) sage: cylindric_axial=(v*cos(u),v*sin(u),w) sage: parabolic_cylindrical=(w*v,(v^2-w^2)/2,u) Plot a constant function of each of these to get an idea of what it does:: sage: A = plot3d(2,(u,-pi,pi),(v,0,pi),transformation=rectangular,plot_points=[100,100]) sage: B = plot3d(2,(u,-pi,pi),(v,0,pi),transformation=spherical,plot_points=[100,100]) sage: C = plot3d(2,(u,-pi,pi),(v,0,pi),transformation=cylindric_radial,plot_points=[100,100]) sage: D = plot3d(2,(u,-pi,pi),(v,0,pi),transformation=cylindric_axial,plot_points=[100,100]) sage: E = plot3d(2,(u,-pi,pi),(v,-pi,pi),transformation=parabolic_cylindrical,plot_points=[100,100]) sage: @interact ....: def _(which_plot=[A,B,C,D,E]): ....: show(which_plot) <html>... Now plot a function:: sage: g=3+sin(4*u)/2+cos(4*v)/2 sage: F = plot3d(g,(u,-pi,pi),(v,0,pi),transformation=rectangular,plot_points=[100,100]) sage: G = plot3d(g,(u,-pi,pi),(v,0,pi),transformation=spherical,plot_points=[100,100]) sage: H = plot3d(g,(u,-pi,pi),(v,0,pi),transformation=cylindric_radial,plot_points=[100,100]) sage: I = plot3d(g,(u,-pi,pi),(v,0,pi),transformation=cylindric_axial,plot_points=[100,100]) sage: J = plot3d(g,(u,-pi,pi),(v,0,pi),transformation=parabolic_cylindrical,plot_points=[100,100]) sage: @interact ....: def _(which_plot=[F, G, H, I, J]): ....: show(which_plot) <html>... TESTS: Make sure the transformation plots work:: sage: show(A + B + C + D + E) sage: show(F + G + H + I + J) Listing the same plot variable twice gives an error:: sage: x, y = var('x y') sage: plot3d( 4*x*exp(-x^2-y^2), (x,-2,2), (x,-2,2)) Traceback (most recent call last): ... ValueError: range variables should be distinct, but there are duplicates """ if transformation is not None: params = None from sage.symbolic.callable import is_CallableSymbolicExpression # First, determine the parameters for f (from the first item of urange # and vrange, preferably). if len(urange) == 3 and len(vrange) == 3: params = (urange[0], vrange[0]) elif is_CallableSymbolicExpression(f): params = f.variables() from sage.modules.vector_callable_symbolic_dense import Vector_callable_symbolic_dense if isinstance(transformation, (tuple, list, Vector_callable_symbolic_dense)): if len(transformation) == 3: if params is None: raise ValueError( "must specify independent variable names in the ranges when using generic transformation" ) indep_vars = params elif len(transformation) == 4: indep_vars = transformation[3] transformation = transformation[0:3] else: raise ValueError("unknown transformation type") # find out which variable is the function variable by # eliminating the parameter variables. all_vars = set( sum([list(s.variables()) for s in transformation], [])) dep_var = all_vars - set(indep_vars) if len(dep_var) == 1: dep_var = dep_var.pop() transformation = _ArbitraryCoordinates(transformation, dep_var, indep_vars) else: raise ValueError( "unable to determine the function variable in the transform" ) if isinstance(transformation, _Coordinates): R = transformation.to_cartesian(f, params) return parametric_plot3d.parametric_plot3d(R, urange, vrange, **kwds) else: raise ValueError('unknown transformation type') elif adaptive: P = plot3d_adaptive(f, urange, vrange, **kwds) else: u = fast_float_arg(0) v = fast_float_arg(1) P = parametric_plot3d.parametric_plot3d((u, v, f), urange, vrange, **kwds) P.frame_aspect_ratio([1.0, 1.0, 0.5]) return P
def Gr_fast_float(r, MAX=20): from sage.ext.fast_eval import fast_float_arg, fast_float_constant, fast_float_func x = fast_float_arg(0) return Pr_poly(r, RDF) (-log(x)) + Gr_series(r, RDF, MAX=MAX) (x)