diff --git a/src/sage/doctest/sources.py b/src/sage/doctest/sources.py index 8c7b29bf1d4..cae09766f5d 100644 --- a/src/sage/doctest/sources.py +++ b/src/sage/doctest/sources.py @@ -238,7 +238,7 @@ def _process_doc(self, doctests, doc, namespace, start): # Line number refers to the end of the docstring sigon = doctest.Example(sig_on_count_doc_doctest, "0\n", lineno=docstring.count("\n")) sigon.sage_source = sig_on_count_doc_doctest - sigon.optional_tags = frozenset() + sigon.optional_tags = frozenset(self.file_optional_tags) sigon.probed_tags = frozenset() dt.examples.append(sigon) doctests.append(dt) diff --git a/src/sage/libs/ntl/ntl_ZZ_pEX_linkage.pxi b/src/sage/libs/ntl/ntl_ZZ_pEX_linkage.pxi index 22d15b71b45..36c87c75efa 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pEX_linkage.pxi +++ b/src/sage/libs/ntl/ntl_ZZ_pEX_linkage.pxi @@ -332,7 +332,7 @@ cdef inline int celement_pow(ZZ_pEX_c* res, ZZ_pEX_c* x, long e, ZZ_pEX_c *modul sage: (x+1)^(-2) 1/(x^2 + 2*x + 1) sage: f = x+(a+1) - sage: f**50 == sum(binomial(50,i)*(a+1)**i*x**(50-i) for i in range(51)) + sage: f**50 == sum(binomial(50,i)*(a+1)**i*x**(50-i) for i in range(51)) # needs sage.symbolic True TESTS: diff --git a/src/sage/misc/converting_dict.py b/src/sage/misc/converting_dict.py index 472e5c2b663..0cd7a47916e 100644 --- a/src/sage/misc/converting_dict.py +++ b/src/sage/misc/converting_dict.py @@ -25,7 +25,7 @@ This is used e.g. in the result of a variety, to allow access to the result no matter how a generator is identified:: - sage: # needs sage.rings.number_field + sage: # needs sage.libs.singular sage.rings.number_field sage: K. = QQ[] sage: I = ideal([x^2 + 2*y - 5, x + y + 3]) sage: V = sorted(I.variety(AA), key=str) diff --git a/src/sage/misc/replace_dot_all.py b/src/sage/misc/replace_dot_all.py index 3415ea83058..4f872f2691b 100644 --- a/src/sage/misc/replace_dot_all.py +++ b/src/sage/misc/replace_dot_all.py @@ -298,7 +298,7 @@ def process_line(location, line, replacements, row_index, verbose=False): sage: from sage.misc.replace_dot_all import * sage: location = os.path.join(sage.env.SAGE_SRC, 'sage/plot/arc.py') sage: replacements = find_replacements(location, package_regex='sage[.]plot[.]all', verbose=True); replacements - [[476, 24, 'from sage.plot.graphics import Graphics']] + [[477, 24, 'from sage.plot.graphics import Graphics']] sage: with open(location, "r") as file: ....: lines = file.readlines() sage: row_index, col_number, *_ = replacements[0] diff --git a/src/sage/misc/table.py b/src/sage/misc/table.py index 34410b103d2..b682bbbd440 100644 --- a/src/sage/misc/table.py +++ b/src/sage/misc/table.py @@ -293,7 +293,7 @@ def __eq__(self, other): EXAMPLES:: - sage: # needs sage.modules sage.plot + sage: # needs sage.modules sage.plot sage.symbolic sage: rows = [['a', 'b', 'c'], [1,plot(sin(x)),3], [4,5,identity_matrix(2)]] sage: T = table(rows, header_row=True) sage: T2 = table(rows, header_row=True) diff --git a/src/sage/plot/animate.py b/src/sage/plot/animate.py index c917452e2be..0ce77981f34 100644 --- a/src/sage/plot/animate.py +++ b/src/sage/plot/animate.py @@ -453,7 +453,8 @@ def make_image(self, frame, filename, **kwds): ....: floor(G.ymin()), ceil(G.ymax())) ....: G.save_image(filename, **kwds) - sage: B = MyAnimation([graphs.CompleteGraph(n) for n in range(7,11)], figsize=5) + sage: B = MyAnimation([graphs.CompleteGraph(n) + ....: for n in range(7,11)], figsize=5) sage: d = B.png() sage: v = os.listdir(d); v.sort(); v ['00000000.png', '00000001.png', '00000002.png', '00000003.png'] diff --git a/src/sage/plot/arc.py b/src/sage/plot/arc.py index 84a62554118..8da333ee12b 100644 --- a/src/sage/plot/arc.py +++ b/src/sage/plot/arc.py @@ -56,6 +56,7 @@ def __init__(self, x, y, r1, r2, angle, s1, s2, options): EXAMPLES:: + sage: # needs sage.symbolic sage: A = arc((2,3),1,1,pi/4,(0,pi)) sage: A[0].x == 2 True diff --git a/src/sage/plot/colors.py b/src/sage/plot/colors.py index bd538fa57b4..5eeddc373fd 100644 --- a/src/sage/plot/colors.py +++ b/src/sage/plot/colors.py @@ -215,7 +215,7 @@ def mod_one(x): 0.0 sage: mod_one(-11/7) 0.4285714285714286 - sage: mod_one(pi) + mod_one(-pi) + sage: mod_one(pi) + mod_one(-pi) # needs sage.symbolic 1.0 """ x = float(x) @@ -1146,9 +1146,10 @@ def hue(h, s=1, v=1): This function makes it easy to sample a broad range of colors for graphics:: + sage: # needs sage.symbolic sage: p = Graphics() sage: for phi in xsrange(0, 2 * pi, 1 / pi): - ....: p += plot(sin(x + phi), (x, -7, 7), rgbcolor = hue(phi)) + ....: p += plot(sin(x + phi), (x, -7, 7), rgbcolor=hue(phi)) sage: p Graphics object consisting of 20 graphics primitives diff --git a/src/sage/plot/ellipse.py b/src/sage/plot/ellipse.py index 821906ecf0a..788db0fd76b 100644 --- a/src/sage/plot/ellipse.py +++ b/src/sage/plot/ellipse.py @@ -220,7 +220,7 @@ def plot3d(self): TESTS:: sage: from sage.plot.ellipse import Ellipse - sage: Ellipse(0,0,2,1,pi/4,{}).plot3d() + sage: Ellipse(0,0,2,1,pi/4,{}).plot3d() # needs sage.symbolic Traceback (most recent call last): ... NotImplementedError diff --git a/src/sage/plot/graphics.py b/src/sage/plot/graphics.py index e00aae735b3..b6465b8f9a9 100644 --- a/src/sage/plot/graphics.py +++ b/src/sage/plot/graphics.py @@ -64,7 +64,7 @@ def is_Graphics(x): sage: from sage.plot.graphics import is_Graphics sage: is_Graphics(1) False - sage: is_Graphics(disk((0.0, 0.0), 1, (0, pi/2))) + sage: is_Graphics(disk((0.0, 0.0), 1, (0, pi/2))) # needs sage.symbolic True """ return isinstance(x, Graphics) @@ -1359,6 +1359,7 @@ def _set_scale(self, subplot, scale=None, base=None): EXAMPLES:: + sage: # needs sage.symbolic sage: p = plot(x, 1, 10) sage: fig = p.matplotlib() sage: ax = fig.get_axes()[0] @@ -1373,6 +1374,7 @@ def _set_scale(self, subplot, scale=None, base=None): TESTS:: + sage: # needs sage.symbolic sage: p._set_scale(ax, 'log') Traceback (most recent call last): ... @@ -1797,7 +1799,7 @@ def show(self, **kwds): :: - sage: G.show(scale='semilogy', base=(3,2)) # base ignored for x-axis # needs sage.symbolic + sage: G.show(scale='semilogy', base=(3,2)) # base ignored for x-axis # needs sage.symbolic The scale can be also given as a 2-tuple or a 3-tuple.:: diff --git a/src/sage/plot/histogram.py b/src/sage/plot/histogram.py index 388c2d1391d..e10229417fc 100644 --- a/src/sage/plot/histogram.py +++ b/src/sage/plot/histogram.py @@ -274,8 +274,8 @@ def histogram(datalist, **options): sage: nv = normalvariate sage: H = histogram([nv(0, 1) for _ in range(1000)], bins=20, density=True, range=[-5, 5]) - sage: P = plot(1/sqrt(2*pi)*e^(-x^2/2), (x, -5, 5), color='red', linestyle='--') - sage: H+P + sage: P = plot(1/sqrt(2*pi)*e^(-x^2/2), (x, -5, 5), color='red', linestyle='--') # needs sage.symbolic + sage: H + P # needs sage.symbolic Graphics object consisting of 2 graphics primitives .. PLOT:: diff --git a/src/sage/plot/line.py b/src/sage/plot/line.py index c945946484a..8e9cb97891f 100644 --- a/src/sage/plot/line.py +++ b/src/sage/plot/line.py @@ -559,6 +559,7 @@ def line2d(points, **options): A purple plot of the Riemann zeta function `\zeta(1/2 + it)`, `0 < t < 30`:: + sage: # needs sage.libs.pari sage.rings.complex_double sage: i = CDF.gen() sage: v = [zeta(0.5 + n/10 * i) for n in range(300)] sage: L = [(z.real(), z.imag()) for z in v] @@ -590,6 +591,7 @@ def line2d(points, **options): A red, blue, and green "cool cat":: + sage: # needs sage.symbolic sage: G = plot(-cos(x), -2, 2, thickness=5, rgbcolor=(0.5,1,0.5)) sage: P = polygon([[1,2], [5,6], [5,0]], rgbcolor=(1,0,0)) sage: Q = polygon([(-x,y) for x,y in P[0]], rgbcolor=(0,0,1)) diff --git a/src/sage/plot/matrix_plot.py b/src/sage/plot/matrix_plot.py index f113f5aaa62..abaeb3e6fc4 100644 --- a/src/sage/plot/matrix_plot.py +++ b/src/sage/plot/matrix_plot.py @@ -535,7 +535,7 @@ def matrix_plot(mat, xrange=None, yrange=None, **options): :: - sage: matrix_plot([[sin(x), cos(x)], [1, 0]]) + sage: matrix_plot([[sin(x), cos(x)], [1, 0]]) # needs sage.symbolic Traceback (most recent call last): ... TypeError: mat must be a Matrix or a two dimensional array diff --git a/src/sage/plot/plot.py b/src/sage/plot/plot.py index b614b2ef3db..b25ba785326 100644 --- a/src/sage/plot/plot.py +++ b/src/sage/plot/plot.py @@ -1763,7 +1763,7 @@ def b(n): return lambda x: bessel_J(n, x) + 0.5*(n-1) .. PLOT:: - g = plot(sin(pi*x), (x, -8, 8), ticks=[[-7,-3,0,3,7],[-1/2,0,1/2]]) + g = plot(sin(pi*x), (x, -8, 8), ticks=[[-7,-3,0,3,7], [-1/2,0,1/2]]) sphinx_plot(g) :: @@ -1799,7 +1799,7 @@ def b(n): return lambda x: bessel_J(n, x) + 0.5*(n-1) .. PLOT:: - g = plot(x**2, (x,0,3), ticks=[[1,2.5],[0.5,1,2]], tick_formatter=[["$x_1$","$x_2$"],["$y_1$","$y_2$","$y_3$"]]) + g = plot(x**2, (x,0,3), ticks=[[1,2.5],[0.5,1,2]], tick_formatter=[["$x_1$","$x_2$"], ["$y_1$","$y_2$","$y_3$"]]) sphinx_plot(g) You can force Type 1 fonts in your figures by providing the relevant @@ -1891,7 +1891,7 @@ def f(x): return (floor(x)+0.5) / (1-(x-0.5)**2) sage: plot(arcsec(x/2), -2, 2) # plot should be empty; no valid points Graphics object consisting of 0 graphics primitives - sage: plot(sqrt(x^2-1), -2, 2) # [-1, 1] is excluded automatically + sage: plot(sqrt(x^2 - 1), -2, 2) # [-1, 1] is excluded automatically Graphics object consisting of 2 graphics primitives .. PLOT:: @@ -2573,7 +2573,7 @@ def parametric_plot(funcs, *args, **kwargs): is 1, so that circles look like circles. :: sage: t = var('t') - sage: parametric_plot( (cos(t), sin(t)), (t, 0, 2*pi)) + sage: parametric_plot((cos(t), sin(t)), (t, 0, 2*pi)) Graphics object consisting of 1 graphics primitive .. PLOT:: @@ -2613,23 +2613,25 @@ def parametric_plot(funcs, *args, **kwargs): .. PLOT:: - t =var('t') + t = var('t') g = parametric_plot((t, t**2), (t, -4, 4), fill=True) sphinx_plot(g) A filled Hypotrochoid:: - sage: parametric_plot([cos(x) + 2 * cos(x/4), sin(x) - 2 * sin(x/4)], (x,0, 8*pi), fill=True) + sage: parametric_plot([cos(x) + 2 * cos(x/4), sin(x) - 2 * sin(x/4)], + ....: (x, 0, 8*pi), fill=True) Graphics object consisting of 2 graphics primitives .. PLOT:: - g = parametric_plot([cos(x) + 2 * cos(x/4), sin(x) - 2 * sin(x/4)], (x,0, 8*pi), fill=True) + g = parametric_plot([cos(x) + 2 * cos(x/4), sin(x) - 2 * sin(x/4)], (x, 0, 8*pi), fill=True) sphinx_plot(g) :: - sage: parametric_plot( (5*cos(x), 5*sin(x), x), (x,-12, 12), plot_points=150, color="red") # long time + sage: parametric_plot((5*cos(x), 5*sin(x), x), (x, -12, 12), # long time + ....: plot_points=150, color="red") Graphics3d Object .. PLOT:: @@ -2829,7 +2831,8 @@ def polar_plot(funcs, *args, **kwds): Fill the area between two functions:: - sage: polar_plot(cos(4*x) + 1.5, 0, 2*pi, fill=0.5 * cos(4*x) + 2.5, fillcolor='orange') + sage: polar_plot(cos(4*x) + 1.5, 0, 2*pi, fill=0.5 * cos(4*x) + 2.5, + ....: fillcolor='orange') Graphics object consisting of 2 graphics primitives .. PLOT:: @@ -2839,7 +2842,8 @@ def polar_plot(funcs, *args, **kwds): Fill the area between several spirals:: - sage: polar_plot([(1.2+k*0.2)*log(x) for k in range(6)], 1, 3 * pi, fill={0: [1], 2: [3], 4: [5]}) + sage: polar_plot([(1.2+k*0.2)*log(x) for k in range(6)], 1, 3 * pi, + ....: fill={0: [1], 2: [3], 4: [5]}) Graphics object consisting of 9 graphics primitives .. PLOT:: @@ -2895,7 +2899,7 @@ def list_plot(data, plotjoined=False, **kwargs): EXAMPLES:: - sage: list_plot([i^2 for i in range(5)]) # long time + sage: list_plot([i^2 for i in range(5)]) # long time Graphics object consisting of 1 graphics primitive .. PLOT:: @@ -3008,7 +3012,9 @@ def list_plot(data, plotjoined=False, **kwargs): sage: list_plot(x_coords, y_coords) Traceback (most recent call last): ... - TypeError: The second argument 'plotjoined' should be boolean (True or False). If you meant to plot two lists 'x' and 'y' against each other, use 'list_plot(list(zip(x,y)))'. + TypeError: The second argument 'plotjoined' should be boolean (True or False). + If you meant to plot two lists 'x' and 'y' against each other, + use 'list_plot(list(zip(x,y)))'. Dictionaries with numeric keys and values can be plotted:: @@ -3055,12 +3061,12 @@ def list_plot(data, plotjoined=False, **kwargs): Instead this will work. We drop the point `(0,1)`.:: - sage: list_plot(list(zip(range(1,len(yl)), yl[1:])), scale='loglog') # long time + sage: list_plot(list(zip(range(1,len(yl)), yl[1:])), scale='loglog') # long time Graphics object consisting of 1 graphics primitive We use :func:`list_plot_loglog` and plot in a different base.:: - sage: list_plot_loglog(list(zip(range(1,len(yl)), yl[1:])), base=2) # long time + sage: list_plot_loglog(list(zip(range(1,len(yl)), yl[1:])), base=2) # long time Graphics object consisting of 1 graphics primitive .. PLOT:: @@ -3267,22 +3273,22 @@ def plot_semilogy(funcs, *args, **kwds): EXAMPLES:: - sage: plot_semilogy(exp, (1,10)) # long time # plot in semilogy scale, base 10 + sage: plot_semilogy(exp, (1, 10)) # long time # plot in semilogy scale, base 10 Graphics object consisting of 1 graphics primitive .. PLOT:: - g = plot_semilogy(exp, (1,10)) # long time # plot in semilogy scale, base 10 + g = plot_semilogy(exp, (1,10)) # long time # plot in semilogy scale, base 10 sphinx_plot(g) :: - sage: plot_semilogy(exp, (1,10), base=2) # long time # with base 2 + sage: plot_semilogy(exp, (1, 10), base=2) # long time # with base 2 Graphics object consisting of 1 graphics primitive .. PLOT:: - g = plot_semilogy(exp, (1,10), base=2) # long time # with base 2 + g = plot_semilogy(exp, (1,10), base=2) # long time # with base 2 sphinx_plot(g) """ @@ -3505,13 +3511,14 @@ def reshape(v, n, m): :: - sage: M = [[plot(sin(k*x),(x,-pi,pi)) for k in range(3)],[plot(cos(j*x),(x,-pi,pi)) for j in [3..5]]] + sage: M = [[plot(sin(k*x), (x,-pi,pi)) for k in range(3)], + ....: [plot(cos(j*x), (x,-pi,pi)) for j in [3..5]]] sage: graphics_array(M,6,1) # long time (up to 4s on sage.math, 2012) Graphics Array of size 6 x 1 TESTS:: - sage: L = [plot(sin(k*x),(x,-pi,pi)) for k in [1..3]] + sage: L = [plot(sin(k*x), (x,-pi,pi)) for k in [1..3]] sage: graphics_array(L,0,-1) # indirect doctest Traceback (most recent call last): ... @@ -3620,6 +3627,7 @@ def h(x): return sin(4*x) It is possible to use ``figsize`` to change the size of the plot as a whole:: + sage: x = var('x') sage: L = [plot(sin(k*x), (x,-pi,pi)) for k in [1..3]] sage: ga = graphics_array(L) sage: ga.show(figsize=[5,3]) # smallish and compact @@ -3860,7 +3868,8 @@ def adaptive_refinement(f, p1, p2, adaptive_tolerance=0.01, TESTS:: sage: from sage.plot.plot import adaptive_refinement - sage: adaptive_refinement(sin, (0,0), (pi,0), adaptive_tolerance=0.01, adaptive_recursion=0) + sage: adaptive_refinement(sin, (0,0), (pi,0), adaptive_tolerance=0.01, + ....: adaptive_recursion=0) [] sage: adaptive_refinement(sin, (0,0), (pi,0), adaptive_tolerance=0.01) [(0.125*pi, 0.3826834323650898), (0.1875*pi, 0.5555702330196022), @@ -3881,7 +3890,8 @@ def adaptive_refinement(f, p1, p2, adaptive_tolerance=0.01, sage: f(x) = sin(1/x) sage: n1 = len(adaptive_refinement(f, (0,0), (pi,0), adaptive_tolerance=0.01)); n1 15 - sage: n2 = len(adaptive_refinement(f, (0,0), (pi,0), adaptive_recursion=10, adaptive_tolerance=0.01)); n2 + sage: n2 = len(adaptive_refinement(f, (0,0), (pi,0), adaptive_recursion=10, + ....: adaptive_tolerance=0.01)); n2 79 sage: n3 = len(adaptive_refinement(f, (0,0), (pi,0), adaptive_tolerance=0.001)); n3 26 diff --git a/src/sage/plot/plot3d/base.pyx b/src/sage/plot/plot3d/base.pyx index 8f69ed49725..b9dc7b310ca 100644 --- a/src/sage/plot/plot3d/base.pyx +++ b/src/sage/plot/plot3d/base.pyx @@ -1998,9 +1998,10 @@ end_scene""".format( This works when faces have more then 3 sides:: - sage: P = polytopes.dodecahedron() # needs sage.geometry.polyhedron - sage: Q = P.plot().all[-1] # needs sage.geometry.polyhedron - sage: print(Q.stl_binary()[:40].decode('ascii')) # needs sage.geometry.polyhedron + sage: # needs sage.geometry.polyhedron sage.groups + sage: P = polytopes.dodecahedron() + sage: Q = P.plot().all[-1] + sage: print(Q.stl_binary()[:40].decode('ascii')) STL binary file / made by SageMath / ### """ import struct @@ -2060,9 +2061,10 @@ end_scene""".format( Now works when faces have more then 3 sides:: - sage: P = polytopes.dodecahedron() # needs sage.geometry.polyhedron - sage: Q = P.plot().all[-1] # needs sage.geometry.polyhedron - sage: print(Q.stl_ascii_string().splitlines()[:7]) # needs sage.geometry.polyhedron + sage: # needs sage.geometry.polyhedron sage.groups + sage: P = polytopes.dodecahedron() + sage: Q = P.plot().all[-1] + sage: print(Q.stl_ascii_string().splitlines()[:7]) ['solid surface', 'facet normal 0.0 0.5257311121191338 0.8506508083520399', ' outer loop', diff --git a/src/sage/plot/plot3d/list_plot3d.py b/src/sage/plot/plot3d/list_plot3d.py index b8e4ddffce6..825c140f8ea 100644 --- a/src/sage/plot/plot3d/list_plot3d.py +++ b/src/sage/plot/plot3d/list_plot3d.py @@ -530,7 +530,8 @@ def list_plot3d_tuples(v, interpolation_type, **kwds): .. PLOT:: - sphinx_plot(list_plot3d([[1, 1, 1], [1, 2, 1], [0, 1, 3], [1, 0, 4]], point_list=True)) + sphinx_plot(list_plot3d([[1, 1, 1], [1, 2, 1], [0, 1, 3], [1, 0, 4]], + point_list=True)) :: diff --git a/src/sage/plot/plot3d/revolution_plot3d.py b/src/sage/plot/plot3d/revolution_plot3d.py index b140c463c29..f3220dcd1a3 100644 --- a/src/sage/plot/plot3d/revolution_plot3d.py +++ b/src/sage/plot/plot3d/revolution_plot3d.py @@ -1,4 +1,4 @@ -# sage.doctest: needs sage.plot +# sage.doctest: needs sage.plot sage.symbolic """ Surfaces of revolution diff --git a/src/sage/plot/plot3d/transform.pyx b/src/sage/plot/plot3d/transform.pyx index fefbb26dede..b6d8a2f643b 100644 --- a/src/sage/plot/plot3d/transform.pyx +++ b/src/sage/plot/plot3d/transform.pyx @@ -174,11 +174,11 @@ def rotate_arbitrary(v, double theta): sage: rotate_arbitrary((1,2,3), -1).det() 1.0000000000000002 - sage: rotate_arbitrary((1,1,1), 2*pi/3) * vector(RDF, (1,2,3)) # rel tol 2e-15 + sage: rotate_arbitrary((1,1,1), 2*pi/3) * vector(RDF, (1,2,3)) # rel tol 2e-15 # needs sage.symbolic (1.9999999999999996, 2.9999999999999996, 0.9999999999999999) sage: rotate_arbitrary((1,2,3), 5) * vector(RDF, (1,2,3)) # rel tol 2e-15 (1.0000000000000002, 2.0, 3.000000000000001) - sage: rotate_arbitrary((1,1,1), pi/7)^7 # rel tol 2e-15 + sage: rotate_arbitrary((1,1,1), pi/7)^7 # rel tol 2e-15 # needs sage.symbolic [-0.33333333333333337 0.6666666666666671 0.6666666666666665] [ 0.6666666666666665 -0.33333333333333337 0.6666666666666671] [ 0.6666666666666671 0.6666666666666667 -0.33333333333333326] @@ -194,7 +194,7 @@ def rotate_arbitrary(v, double theta): Setup some variables:: - sage: vx,vy,vz,theta = var('x y z theta') + sage: vx,vy,vz,theta = var('x y z theta') # needs sage.symbolic Symbolic rotation matrices about X and Y axis:: @@ -205,37 +205,37 @@ def rotate_arbitrary(v, double theta): way to tell Maxima that `x^2+y^2+z^2=1` which would make for a much cleaner calculation:: - sage: vy = sqrt(1-vx^2-vz^2) + sage: vy = sqrt(1-vx^2-vz^2) # needs sage.symbolic Now we rotate about the `x`-axis so `v` is in the `xy`-plane:: - sage: t = arctan(vy/vz)+pi/2 - sage: m = rotX(t) - sage: new_y = vy*cos(t) - vz*sin(t) + sage: t = arctan(vy/vz)+pi/2 # needs sage.symbolic + sage: m = rotX(t) # needs sage.symbolic + sage: new_y = vy*cos(t) - vz*sin(t) # needs sage.symbolic And rotate about the `z` axis so `v` lies on the `x` axis:: - sage: s = arctan(vx/new_y) + pi/2 - sage: m = rotZ(s) * m + sage: s = arctan(vx/new_y) + pi/2 # needs sage.symbolic + sage: m = rotZ(s) * m # needs sage.symbolic Rotating about `v` in our old system is the same as rotating about the `x`-axis in the new:: - sage: m = rotX(theta) * m + sage: m = rotX(theta) * m # needs sage.symbolic Do some simplifying here to avoid blow-up:: - sage: m = m.simplify_rational() + sage: m = m.simplify_rational() # needs sage.symbolic Now go back to the original coordinate system:: - sage: m = rotZ(-s) * m - sage: m = rotX(-t) * m + sage: m = rotZ(-s) * m # needs sage.symbolic + sage: m = rotX(-t) * m # needs sage.symbolic And simplify every single entry (which is more effective that simplify the whole matrix like above):: - sage: m.parent()([x.simplify_full() for x in m._list()]) # long time; random + sage: m.parent()([x.simplify_full() for x in m._list()]) # random # long time, needs sage.symbolic [ -(cos(theta) - 1)*x^2 + cos(theta) -(cos(theta) - 1)*sqrt(-x^2 - z^2 + 1)*x + sin(theta)*abs(z) -((cos(theta) - 1)*x*z^2 + sqrt(-x^2 - z^2 + 1)*sin(theta)*abs(z))/z] [ -(cos(theta) - 1)*sqrt(-x^2 - z^2 + 1)*x - sin(theta)*abs(z) (cos(theta) - 1)*x^2 + (cos(theta) - 1)*z^2 + 1 -((cos(theta) - 1)*sqrt(-x^2 - z^2 + 1)*z*abs(z) - x*z*sin(theta))/abs(z)] [ -((cos(theta) - 1)*x*z^2 - sqrt(-x^2 - z^2 + 1)*sin(theta)*abs(z))/z -((cos(theta) - 1)*sqrt(-x^2 - z^2 + 1)*z*abs(z) + x*z*sin(theta))/abs(z) -(cos(theta) - 1)*z^2 + cos(theta)]