Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download

san diego talk

Views: 983

Some Examples

Example: Linear Algebra

  • Define a matrix with rational number entries

  • Compute the reduced row echelon form

  • But also compute its kernel as a vector space!

  • And ask questions about that vector space.

A = matrix(QQ, 3, 3, [1/3,2/3,4, 4,5,6, 13,17,30]) show(A)
(13234456131730)\displaystyle \left(\begin{array}{rrr} \frac{1}{3} & \frac{2}{3} & 4 \\ 4 & 5 & 6 \\ 13 & 17 & 30 \end{array}\right)
B = A.rref() show(B)
(10−160114000)\displaystyle \left(\begin{array}{rrr} 1 & 0 & -16 \\ 0 & 1 & 14 \\ 0 & 0 & 0 \end{array}\right)
V = A.right_kernel(); V
Vector space of degree 3 and dimension 1 over Rational Field Basis matrix: [ 1 -7/8 1/16]
w = V.basis()[0] A * w
(0, 0, 0)
w in V [0,0,1] in V
True False
f = A.characteristic_polynomial() show(f)
x3−1063x2+5x\displaystyle x^{3} - \frac{106}{3} x^{2} + 5 x
# Cayley-Hamilton f(A)
[0 0 0] [0 0 0] [0 0 0]
A.
# Type A.[tab key] A.plot()
/ext/sage/sage-8.1/local/lib/python2.7/site-packages/matplotlib/font_manager.py:273: UserWarning: Matplotlib is building the font cache using fc-list. This may take a moment. warnings.warn('Matplotlib is building the font cache using fc-list. This may take a moment.')

Define two subspaces of a 4-dimensional space and intersect and add them.

  • Instead of the tedium of "echelon forms", etc., you work directly with the ideas.

V = span(QQ, [[1,2,3,4], [2,5,3,7], [1,1,1,1], [2,2,2,2]]); V
Vector space of degree 4 and dimension 3 over Rational Field Basis matrix: [ 1 0 0 -6/5] [ 0 1 0 7/5] [ 0 0 1 4/5]
W = span(QQ, [[0,1,2,7], [3,4,2,1]]); W
Vector space of degree 4 and dimension 2 over Rational Field Basis matrix: [ 1 0 -2 -9] [ 0 1 2 7]
V.intersection(W)
Vector space of degree 4 and dimension 1 over Rational Field Basis matrix: [ 1 31/20 11/10 37/20]
V+W
Vector space of degree 4 and dimension 4 over Rational Field Basis matrix: [1 0 0 0] [0 1 0 0] [0 0 1 0] [0 0 0 1]

But Sage is used heavily for research mathematics, so this also works!

A = random_matrix(QQ, 200) # random 200x200 matrix over the rational numbers %time A.det() # compute its determinant
27974860592823300832522626189665347576901620313869267539702268968355795664566562177879117697123641082797808606489468868061087193747492936902319011358868902142757376126947531001073596886146198586499781121460586898034294973793061004953366731736685331730063/200867255532373784442745261542645325315275374222849104412672 CPU time: 0.08 s, Wall time: 0.08 s
# Solve A*z=v v = random_vector(QQ,200) %time z = A.solve_right(v) z[0] # every entry of z is huge...
CPU time: 1.58 s, Wall time: 1.62 s 6643084757699519206872533277703406550827484990636570896818713597021705734201569911019452790307318343588069856078099333606311213588704180559998547449050724639770443932593240024888384423403920472310056821869445888163940163528778159125181617701890699375608332134375363/125733139297442799919982153514636163616160653846839013849453110063358848307042183027186713685448335163661477109624535432465058176829688881425725226107830933939833832560292530240491492368176615396592527473771804080331580588042304511099890206382736582012756946039360

Example: Working with numbers modulo nn

In elementary number theory, you start by working in the ring of integers modulo nn: Z/nZ={0,1,…,n−1} \ZZ / n \ZZ = \{0, 1, \ldots, n-1\}

R = IntegerModRing(12) R
Ring of integers modulo 12
R.list()
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
a = R(5); a
5
a.parent()
Ring of integers modulo 12
b = R(8) a + b
1
a*b
4
R.multiplication_table()
* a b c d e f g h i j k l +------------------------ a| a a a a a a a a a a a a b| a b c d e f g h i j k l c| a c e g i k a c e g i k d| a d g j a d g j a d g j e| a e i a e i a e i a e i f| a f k d i b g l e j c h g| a g a g a g a g a g a g h| a h c j e l g b i d k f i| a i e a i e a i e a i e j| a j g d a j g d a j g d k| a k i g e c a k i g e c l| a l k j i h g f e d c b

Illustrate Fermat's Little Theorem, that aφ(n)≡1(modn) a^{\varphi(n)} \equiv 1 \pmod{n}

@interact def fermat(n=12): R = IntegerModRing(n) phi = euler_phi(n) for a in R: if gcd(a,n) == 1: print a, a^phi
Interact: please open in CoCalc

But Sage is also for research, so you can work with large numbers efficiently.

For example, here we construct from scratch and use a 4096-bit RSA public-key cryptosystem in a few seconds.

%time p = next_prime(ZZ.random_element(2^2048), proof=False) q = next_prime(ZZ.random_element(2^2048), proof=False) n = p*q phi_n = (p-1)*(q-1) R = IntegerModRing(n) while True: e = ZZ.random_element(n) if gcd(e, phi_n) == 1: break d = (Mod(e, phi_n)^(-1)).lift() message = 3132018 encrypt = R(message) ^ e
CPU time: 1.12 s, Wall time: 1.14 s
encrypt
37577048733628913855026862029121553467830861047034584720487547846963118517482112260622746474320541398097868842390583735290124310111107119885713436912723789210488248842110214266402701797950519190101024466007478094439812574831626574794265293025829450140036055847928743295731298599939208981766459864836088203506114620707048488491407490334189508084103345899824246864529391612252851914033535759819888248386047379558429797889988931446331481181664149220742749058904212136516116311041286054502357040285087019093078271662617862973949584518683475187487960664238949475106342937908036168326629195851545582596393399358896690556302382233873150420888387374965189168075727475260506291374122478781557133756353679133684992349586350979680935932081793057035683389323800704974749741088041760953599013822406736664906378860949662629344919763959537901336010330735365836502891019716197308756102602653649718105967675277893295833410626339805632878654153512517384570632360220332270311840178127139462461206801068786732696010566549735229086840109530249173876577952757307962217952235163443228016646382914526623447975259064678113922597828735816529502161271890161878434080957457755311127640066249830218833086816557836224323468242237939905038586086027025131109574866
encrypt ^ d
3132018

Example: Plotting Functions

You can plot things easily...

plot(x * sin(x^2), (x, -2, 10), color='red')
plot?
File: /ext/sage/sage-8.1/local/lib/python2.7/site-packages/sage/misc/decorators.py Signature : plot(funcs, exclude=None, fillalpha=0.5, detect_poles=False, plot_points=200, thickness=1, adaptive_tolerance=0.01, fillcolor='automatic', adaptive_recursion=5, aspect_ratio='automatic', alpha=1, legend_label=None, fill=False, *args, **kwds) Docstring : Use plot by writing "plot(X, ...)" where X is a Sage object (or list of Sage objects) that either is callable and returns numbers that can be coerced to floats, or has a plot method that returns a "GraphicPrimitive" object. There are many other specialized 2D plot commands available in Sage, such as "plot_slope_field", as well as various graphics primitives like "Arrow"; type "sage.plot.plot?" for a current list. Type "plot.options" for a dictionary of the default options for plots. You can change this to change the defaults for all future plots. Use "plot.reset()" to reset to the default options. PLOT OPTIONS: * "plot_points" - (default: 200) the minimal number of plot points. * "adaptive_recursion" - (default: 5) how many levels of recursion to go before giving up when doing adaptive refinement. Setting this to 0 disables adaptive refinement. * "adaptive_tolerance" - (default: 0.01) how large a difference should be before the adaptive refinement code considers it significant. See the documentation further below for more information, starting at "the algorithm used to insert". * "base" - (default: 10) the base of the logarithm if a logarithmic scale is set. This must be greater than 1. The base can be also given as a list or tuple "(basex, basey)". "basex" sets the base of the logarithm along the horizontal axis and "basey" sets the base along the vertical axis. * "scale" -- (default: ""linear"") string. The scale of the axes. Possible values are ""linear"", ""loglog"", ""semilogx"", ""semilogy"". The scale can be also be given as single argument that is a list or tuple "(scale, base)" or "(scale, basex, basey)". The ""loglog"" scale sets both the horizontal and vertical axes to logarithmic scale. The ""semilogx"" scale sets the horizontal axis to logarithmic scale. The ""semilogy"" scale sets the vertical axis to logarithmic scale. The ""linear"" scale is the default value when "Graphics" is initialized. * "xmin" - starting x value in the rendered figure. This parameter is passed directly to the "show" procedure and it could be overwritten. * "xmax" - ending x value in the rendered figure. This parameter is passed directly to the "show" procedure and it could be overwritten. * "ymin" - starting y value in the rendered figure. This parameter is passed directly to the "show" procedure and it could be overwritten. * "ymax" - ending y value in the rendered figure. This parameter is passed directly to the "show" procedure and it could be overwritten. * "detect_poles" - (Default: False) If set to True poles are detected. If set to "show" vertical asymptotes are drawn. * "legend_label" - a (TeX) string serving as the label for X in the legend. If X is a list, then this option can be a single string, or a list or dictionary with strings as entries/values. If a dictionary, then keys are taken from "range(len(X))". Note: * If the "scale" is ""linear"", then irrespective of what "base" is set to, it will default to 10 and will remain unused. * If you want to limit the plot along the horizontal axis in the final rendered figure, then pass the "xmin" and "xmax" keywords to the "show()" method. To limit the plot along the vertical axis, "ymin" and "ymax" keywords can be provided to either this "plot" command or to the "show" command. * This function does NOT simply sample equally spaced points between xmin and xmax. Instead it computes equally spaced points and adds small perturbations to them. This reduces the possibility of, e.g., sampling sin only at multiples of 2pi, which would yield a very misleading graph. * If there is a range of consecutive points where the function has no value, then those points will be excluded from the plot. See the example below on automatic exclusion of points. * For the other keyword options that the "plot" function can take, refer to the method "show()" and the further options below. COLOR OPTIONS: * "color" - (Default: 'blue') One of: * an RGB tuple (r,g,b) with each of r,g,b between 0 and 1. * a color name as a string (e.g., 'purple'). * an HTML color such as '#aaff0b'. * a list or dictionary of colors (valid only if X is a list): if a dictionary, keys are taken from "range(len(X))"; the entries/values of the list/dictionary may be any of the options above. * 'automatic' -- maps to default ('blue') if X is a single Sage object; and maps to a fixed sequence of regularly spaced colors if X is a list. * "legend_color" - the color of the text for X (or each item in X) in the legend. Default color is 'black'. Options are as in "color" above, except that the choice 'automatic' maps to 'black' if X is a single Sage object. * "fillcolor" - The color of the fill for the plot of X (or each item in X). Default color is 'gray' if X is a single Sage object or if "color" is a single color. Otherwise, options are as in "color" above. APPEARANCE OPTIONS: The following options affect the appearance of the line through the points on the graph of X (these are the same as for the line function): INPUT: * "alpha" - How transparent the line is * "thickness" - How thick the line is * "rgbcolor" - The color as an RGB tuple * "hue" - The color given as a hue LINE OPTIONS: Any MATPLOTLIB line option may also be passed in. E.g., * "linestyle" - (default: "-") The style of the line, which is one of * ""-"" or ""solid"" * ""--"" or ""dashed"" * ""-."" or ""dash dot"" * "":"" or ""dotted"" * ""None"" or "" "" or """" (nothing) * a list or dictionary (see below) The linestyle can also be prefixed with a drawing style (e.g., ""steps--"") * ""default"" (connect the points with straight lines) * ""steps"" or ""steps-pre"" (step function; horizontal line is to the left of point) * ""steps-mid"" (step function; points are in the middle of horizontal lines) * ""steps-post"" (step function; horizontal line is to the right of point) If X is a list, then "linestyle" may be a list (with entries taken from the strings above) or a dictionary (with keys in "range(len(X))" and values taken from the strings above). * "marker" - The style of the markers, which is one of * ""None"" or "" "" or """" (nothing) -- default * "","" (pixel), ""."" (point) * ""_"" (horizontal line), ""|"" (vertical line) * ""o"" (circle), ""p"" (pentagon), ""s"" (square), ""x"" (x), ""+"" (plus), ""*"" (star) * ""D"" (diamond), ""d"" (thin diamond) * ""H"" (hexagon), ""h"" (alternative hexagon) * ""<"" (triangle left), "">"" (triangle right), ""^"" (triangle up), ""v"" (triangle down) * ""1"" (tri down), ""2"" (tri up), ""3"" (tri left), ""4"" (tri right) * "0" (tick left), "1" (tick right), "2" (tick up), "3" (tick down) * "4" (caret left), "5" (caret right), "6" (caret up), "7" (caret down), "8" (octagon) * ""$...$"" (math TeX string) * "(numsides, style, angle)" to create a custom, regular symbol * "numsides" -- the number of sides * "style" -- "0" (regular polygon), "1" (star shape), "2" (asterisk), "3" (circle) * "angle" -- the angular rotation in degrees * "markersize" - the size of the marker in points * "markeredgecolor" -- the color of the marker edge * "markerfacecolor" -- the color of the marker face * "markeredgewidth" - the size of the marker edge in points * "exclude" - (Default: None) values which are excluded from the plot range. Either a list of real numbers, or an equation in one variable. FILLING OPTIONS: * "fill" - (Default: False) One of: * "axis" or True: Fill the area between the function and the x-axis. * "min": Fill the area between the function and its minimal value. * "max": Fill the area between the function and its maximal value. * a number c: Fill the area between the function and the horizontal line y = c. * a function g: Fill the area between the function that is plotted and g. * a dictionary "d" (only if a list of functions are plotted): The keys of the dictionary should be integers. The value of "d[i]" specifies the fill options for the i-th function in the list. If "d[i] == [j]": Fill the area between the i-th and the j-th function in the list. (But if "d[i] == j": Fill the area between the i-th function in the list and the horizontal line y = j.) * "fillalpha" - (default: 0.5) How transparent the fill is. A number between 0 and 1. EXAMPLES: We plot the sin function: sage: P = plot(sin, (0,10)); print(P) Graphics object consisting of 1 graphics primitive sage: len(P) # number of graphics primitives 1 sage: len(P[0]) # how many points were computed (random) 225 sage: P # render Graphics object consisting of 1 graphics primitive sage: P = plot(sin, (0,10), plot_points=10); print(P) Graphics object consisting of 1 graphics primitive sage: len(P[0]) # random output 32 sage: P # render Graphics object consisting of 1 graphics primitive We plot with "randomize=False", which makes the initial sample points evenly spaced (hence always the same). Adaptive plotting might insert other points, however, unless "adaptive_recursion=0". sage: p=plot(1, (x,0,3), plot_points=4, randomize=False, adaptive_recursion=0) sage: list(p[0]) [(0.0, 1.0), (1.0, 1.0), (2.0, 1.0), (3.0, 1.0)] Some colored functions: sage: plot(sin, 0, 10, color='purple') Graphics object consisting of 1 graphics primitive sage: plot(sin, 0, 10, color='#ff00ff') Graphics object consisting of 1 graphics primitive We plot several functions together by passing a list of functions as input: sage: plot([x*exp(-n*x^2)/.4 for n in [1..5]], (0, 2), aspect_ratio=.8) Graphics object consisting of 5 graphics primitives By default, color will change from one primitive to the next. This may be controlled by modifying "color" option: sage: g1 = plot([x*exp(-n*x^2)/.4 for n in [1..3]], (0, 2), color='blue', aspect_ratio=.8); g1 Graphics object consisting of 3 graphics primitives sage: g2 = plot([x*exp(-n*x^2)/.4 for n in [1..3]], (0, 2), color=['red','red','green'], linestyle=['-','--','-.'], aspect_ratio=.8); g2 Graphics object consisting of 3 graphics primitives We can also build a plot step by step from an empty plot: sage: a = plot([]); a # passing an empty list returns an empty plot (Graphics() object) Graphics object consisting of 0 graphics primitives sage: a += plot(x**2); a # append another plot Graphics object consisting of 1 graphics primitive sage: a += plot(x**3); a # append yet another plot Graphics object consisting of 2 graphics primitives The function sin(1/x) wiggles wildly near 0. Sage adapts to this and plots extra points near the origin. sage: plot(sin(1/x), (x, -1, 1)) Graphics object consisting of 1 graphics primitive Via the matplotlib library, Sage makes it easy to tell whether a graph is on both sides of both axes, as the axes only cross if the origin is actually part of the viewing area: sage: plot(x^3,(x,0,2)) # this one has the origin Graphics object consisting of 1 graphics primitive sage: plot(x^3,(x,1,2)) # this one does not Graphics object consisting of 1 graphics primitive Another thing to be aware of with axis labeling is that when the labels have quite different orders of magnitude or are very large, scientific notation (the e notation for powers of ten) is used: sage: plot(x^2,(x,480,500)) # this one has no scientific notation Graphics object consisting of 1 graphics primitive sage: plot(x^2,(x,300,500)) # this one has scientific notation on y-axis Graphics object consisting of 1 graphics primitive You can put a legend with "legend_label" (the legend is only put once in the case of multiple functions): sage: plot(exp(x), 0, 2, legend_label='$e^x$') Graphics object consisting of 1 graphics primitive Sage understands TeX, so these all are slightly different, and you can choose one based on your needs: sage: plot(sin, legend_label='sin') Graphics object consisting of 1 graphics primitive sage: plot(sin, legend_label='$sin$') Graphics object consisting of 1 graphics primitive sage: plot(sin, legend_label='$sin$') Graphics object consisting of 1 graphics primitive It is possible to use a different color for the text of each label: sage: p1 = plot(sin, legend_label='sin', legend_color='red') sage: p2 = plot(cos, legend_label='cos', legend_color='green') sage: p1 + p2 Graphics object consisting of 2 graphics primitives Prior to https://trac.sagemath.org/19485, legends by default had a shadowless gray background. This behavior can be recovered by setting the legend options on your plot object: sage: p = plot(sin(x), legend_label='$sin(x)$') sage: p.set_legend_options(back_color=(0.9,0.9,0.9), shadow=False) If X is a list of Sage objects and "legend_label" is 'automatic', then Sage will create labels for each function according to their internal representation: sage: plot([sin(x), tan(x), 1-x^2], legend_label='automatic') Graphics object consisting of 3 graphics primitives If "legend_label" is any single string other than 'automatic', then it is repeated for all members of X: sage: plot([sin(x), tan(x)], color='blue', legend_label='trig') Graphics object consisting of 2 graphics primitives Note that the independent variable may be omitted if there is no ambiguity: sage: plot(sin(1.0/x), (-1, 1)) Graphics object consisting of 1 graphics primitive Plotting in logarithmic scale is possible for 2D plots. There are two different syntaxes supported: sage: plot(exp, (1, 10), scale='semilogy') # log axis on vertical Graphics object consisting of 1 graphics primitive sage: plot_semilogy(exp, (1, 10)) # same thing Graphics object consisting of 1 graphics primitive sage: plot_loglog(exp, (1, 10)) # both axes are log Graphics object consisting of 1 graphics primitive sage: plot(exp, (1, 10), scale='loglog', base=2) # long time # base of log is 2 Graphics object consisting of 1 graphics primitive We can also change the scale of the axes in the graphics just before displaying: sage: G = plot(exp, 1, 10) # long time sage: G.show(scale=('semilogy', 2)) # long time The algorithm used to insert extra points is actually pretty simple. On the picture drawn by the lines below: sage: p = plot(x^2, (-0.5, 1.4)) + line([(0,0), (1,1)], color='green') sage: p += line([(0.5, 0.5), (0.5, 0.5^2)], color='purple') sage: p += point(((0, 0), (0.5, 0.5), (0.5, 0.5^2), (1, 1)), color='red', pointsize=20) sage: p += text('A', (-0.05, 0.1), color='red') sage: p += text('B', (1.01, 1.1), color='red') sage: p += text('C', (0.48, 0.57), color='red') sage: p += text('D', (0.53, 0.18), color='red') sage: p.show(axes=False, xmin=-0.5, xmax=1.4, ymin=0, ymax=2) You have the function (in blue) and its approximation (in green) passing through the points A and B. The algorithm finds the midpoint C of AB and computes the distance between C and D. If that distance exceeds the "adaptive_tolerance" threshold (*relative* to the size of the initial plot subintervals), the point D is added to the curve. If D is added to the curve, then the algorithm is applied recursively to the points A and D, and D and B. It is repeated "adaptive_recursion" times (5, by default). The actual sample points are slightly randomized, so the above plots may look slightly different each time you draw them. We draw the graph of an elliptic curve as the union of graphs of 2 functions. sage: def h1(x): return abs(sqrt(x^3 - 1)) sage: def h2(x): return -abs(sqrt(x^3 - 1)) sage: P = plot([h1, h2], 1,4) sage: P # show the result Graphics object consisting of 2 graphics primitives It is important to mention that when we draw several graphs at the same time, parameters "xmin", "xmax", "ymin" and "ymax" are just passed directly to the "show" procedure. In fact, these parameters would be overwritten: sage: p=plot(x^3, x, xmin=-1, xmax=1,ymin=-1, ymax=1) sage: q=plot(exp(x), x, xmin=-2, xmax=2, ymin=0, ymax=4) sage: (p+q).show() As a workaround, we can perform the trick: sage: p1 = line([(a,b) for a,b in zip(p[0].xdata,p[0].ydata) if (b>=-1 and b<=1)]) sage: q1 = line([(a,b) for a,b in zip(q[0].xdata,q[0].ydata) if (b>=0 and b<=4)]) sage: (p1+q1).show() We can also directly plot the elliptic curve: sage: E = EllipticCurve([0,-1]) sage: plot(E, (1, 4), color=hue(0.6)) Graphics object consisting of 1 graphics primitive We can change the line style as well: sage: plot(sin(x), (x, 0, 10), linestyle='-.') Graphics object consisting of 1 graphics primitive If we have an empty linestyle and specify a marker, we can see the points that are actually being plotted: sage: plot(sin(x), (x,0,10), plot_points=20, linestyle='', marker='.') Graphics object consisting of 1 graphics primitive The marker can be a TeX symbol as well: sage: plot(sin(x), (x,0,10), plot_points=20, linestyle='', marker=r'$checkmark$') Graphics object consisting of 1 graphics primitive Sage currently ignores points that cannot be evaluated sage: set_verbose(-1) sage: plot(-x*log(x), (x,0,1)) # this works fine since the failed endpoint is just skipped. Graphics object consisting of 1 graphics primitive sage: set_verbose(0) This prints out a warning and plots where it can (we turn off the warning by setting the verbose mode temporarily to -1.) sage: set_verbose(-1) sage: plot(x^(1/3), (x,-1,1)) Graphics object consisting of 1 graphics primitive sage: set_verbose(0) Plotting the real cube root function for negative input requires avoiding the complex numbers one would usually get. The easiest way is to use absolute value: sage: plot(sign(x)*abs(x)^(1/3), (x,-1,1)) Graphics object consisting of 1 graphics primitive We can also use the following: sage: plot(sign(x)*(x*sign(x))^(1/3), (x,-4,4)) Graphics object consisting of 1 graphics primitive A way that points to how to plot other functions without symbolic variants is using lambda functions: sage: plot(lambda x : RR(x).nth_root(3), (x,-1, 1)) Graphics object consisting of 1 graphics primitive We can detect the poles of a function: sage: plot(gamma, (-3, 4), detect_poles=True).show(ymin=-5, ymax=5) We draw the Gamma-Function with its poles highlighted: sage: plot(gamma, (-3, 4), detect_poles='show').show(ymin=-5, ymax=5) The basic options for filling a plot: sage: p1 = plot(sin(x), -pi, pi, fill='axis') sage: p2 = plot(sin(x), -pi, pi, fill='min', fillalpha=1) sage: p3 = plot(sin(x), -pi, pi, fill='max') sage: p4 = plot(sin(x), -pi, pi, fill=(1-x)/3, fillcolor='blue', fillalpha=.2) sage: graphics_array([[p1, p2], [p3, p4]]).show(frame=True, axes=False) # long time The basic options for filling a list of plots: sage: (f1, f2) = x*exp(-1*x^2)/.35, x*exp(-2*x^2)/.35 sage: p1 = plot([f1, f2], -pi, pi, fill={1: [0]}, fillcolor='blue', fillalpha=.25, color='blue') sage: p2 = plot([f1, f2], -pi, pi, fill={0: x/3, 1:[0]}, color=['blue']) sage: p3 = plot([f1, f2], -pi, pi, fill=[0, [0]], fillcolor=['orange','red'], fillalpha=1, color={1: 'blue'}) sage: p4 = plot([f1, f2], (x,-pi, pi), fill=[x/3, 0], fillcolor=['grey'], color=['red', 'blue']) sage: graphics_array([[p1, p2], [p3, p4]]).show(frame=True, axes=False) # long time A example about the growth of prime numbers: sage: plot(1.13*log(x), 1, 100, fill=lambda x: nth_prime(x)/floor(x), fillcolor='red') Graphics object consisting of 2 graphics primitives Fill the area between a function and its asymptote: sage: f = (2*x^3+2*x-1)/((x-2)*(x+1)) sage: plot([f, 2*x+2], -7,7, fill={0: [1]}, fillcolor='#ccc').show(ymin=-20, ymax=20) Fill the area between a list of functions and the x-axis: sage: def b(n): return lambda x: bessel_J(n, x) sage: plot([b(n) for n in [1..5]], 0, 20, fill='axis') Graphics object consisting of 10 graphics primitives Note that to fill between the ith and jth functions, you must use the dictionary key-value syntax "i:[j]"; using key-value pairs like "i:j" will fill between the ith function and the line y=j: sage: def b(n): return lambda x: bessel_J(n, x) + 0.5*(n-1) sage: plot([b(c) for c in [1..5]], 0, 20, fill={i:[i-1] for i in [1..4]}, color={i:'blue' for i in [1..5]}, aspect_ratio=3, ymax=3); Graphics object consisting of 9 graphics primitives sage: plot([b(c) for c in [1..5]], 0, 20, fill={i:i-1 for i in [1..4]}, color='blue', aspect_ratio=3) # long time Graphics object consisting of 9 graphics primitives Extra options will get passed on to "show()", as long as they are valid: sage: plot(sin(x^2), (x, -3, 3), title='Plot of $sin(x^2)$', axes_labels=['$x$','$y$']) # These labels will be nicely typeset Graphics object consisting of 1 graphics primitive sage: plot(sin(x^2), (x, -3, 3), title='Plot of sin(x^2)', axes_labels=['x','y']) # These will not Graphics object consisting of 1 graphics primitive sage: plot(sin(x^2), (x, -3, 3), axes_labels=['x','y'], axes_labels_size=2.5) # Large axes labels (w.r.t. the tick marks) Graphics object consisting of 1 graphics primitive sage: plot(sin(x^2), (x, -3, 3), figsize=[8,2]) Graphics object consisting of 1 graphics primitive sage: plot(sin(x^2), (x, -3, 3)).show(figsize=[8,2]) # These are equivalent This includes options for custom ticks and formatting. See documentation for "show()" for more details. sage: plot(sin(pi*x), (x, -8, 8), ticks=[[-7,-3,0,3,7],[-1/2,0,1/2]]) Graphics object consisting of 1 graphics primitive sage: plot(2*x+1,(x,0,5),ticks=[[0,1,e,pi,sqrt(20)],2],tick_formatter="latex") Graphics object consisting of 1 graphics primitive This is particularly useful when setting custom ticks in multiples of pi. sage: plot(sin(x),(x,0,2*pi),ticks=pi/3,tick_formatter=pi) Graphics object consisting of 1 graphics primitive You can even have custom tick labels along with custom positioning. sage: 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$"]]) Graphics object consisting of 1 graphics primitive You can force Type 1 fonts in your figures by providing the relevant option as shown below. This also requires that LaTeX, dvipng and Ghostscript be installed: sage: plot(x, typeset='type1') # optional - latex Graphics object consisting of 1 graphics primitive A example with excluded values: sage: plot(floor(x), (x, 1, 10), exclude=[1..10]) Graphics object consisting of 11 graphics primitives We exclude all points where "PrimePi" makes a jump: sage: jumps = [n for n in [1..100] if prime_pi(n) != prime_pi(n-1)] sage: plot(lambda x: prime_pi(x), (x, 1, 100), exclude=jumps) Graphics object consisting of 26 graphics primitives Excluded points can also be given by an equation: sage: g(x) = x^2-2*x-2 sage: plot(1/g(x), (x, -3, 4), exclude=g(x)==0, ymin=-5, ymax=5) # long time Graphics object consisting of 3 graphics primitives "exclude" and "detect_poles" can be used together: sage: f(x) = (floor(x)+0.5) / (1-(x-0.5)^2) sage: plot(f, (x, -3.5, 3.5), detect_poles='show', exclude=[-3..3], ymin=-5, ymax=5) Graphics object consisting of 12 graphics primitives Regions in which the plot has no values are automatically excluded. The regions thus excluded are in addition to the exclusion points present in the "exclude" keyword argument.: sage: set_verbose(-1) sage: plot(arcsec, (x, -2, 2)) # [-1, 1] is excluded automatically Graphics object consisting of 2 graphics primitives sage: plot(arcsec, (x, -2, 2), exclude=[1.5]) # x=1.5 is also excluded Graphics object consisting of 3 graphics primitives 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 Graphics object consisting of 2 graphics primitives sage: plot(arccsc, -2, 2) # [-1, 1] is excluded automatically Graphics object consisting of 2 graphics primitives sage: set_verbose(0) sage: d = plot([sin(x), cos(x)], 100, 120).get_minmax_data() sage: d['xmin'] 100.0 sage: d['xmax'] 120.0 We check various combinations of tuples and functions, ending with tests that lambda functions work properly with explicit variable declaration, without a tuple. sage: p = plot(lambda x: x,(x,-1,1)) sage: p = plot(lambda x: x,-1,1) sage: p = plot(x,x,-1,1) sage: p = plot(x,-1,1) sage: p = plot(x^2,x,-1,1) sage: p = plot(x^2,xmin=-1,xmax=2) sage: p = plot(lambda x: x,x,-1,1) sage: p = plot(lambda x: x^2,x,-1,1) sage: p = plot(lambda x: 1/x,x,-1,1) sage: f(x) = sin(x+3)-.1*x^3 sage: p = plot(lambda x: f(x),x,-1,1) We check to handle cases where the function gets evaluated at a point which causes an 'inf' or '-inf' result to be produced. sage: p = plot(1/x, 0, 1) sage: p = plot(-1/x, 0, 1) Bad options now give better errors: sage: P = plot(sin(1/x), (x,-1,3), foo=10) Traceback (most recent call last): ... RuntimeError: Error in line(): option 'foo' not valid. sage: P = plot(x, (x,1,1)) # trac ticket #11753 Traceback (most recent call last): ... ValueError: plot start point and end point must be different We test that we can plot f(x)=x (see https://trac.sagemath.org/10246): sage: f(x)=x; f x |--> x sage: plot(f,(x,-1,1)) Graphics object consisting of 1 graphics primitive Check that https://trac.sagemath.org/15030 is fixed: sage: plot(abs(log(x)), x) Graphics object consisting of 1 graphics primitive Check that if excluded points are less than xmin then the exclusion still works for polar and parametric plots. The following should show two excluded points: sage: set_verbose(-1) sage: polar_plot(sin(sqrt(x^2-1)), (x,0,2*pi), exclude=[1/2,2,3]) Graphics object consisting of 3 graphics primitives sage: parametric_plot((sqrt(x^2-1),sqrt(x^2-1/2)), (x,0,5), exclude=[1,2,3]) Graphics object consisting of 3 graphics primitives sage: set_verbose(0) Legends can contain variables with long names, https://trac.sagemath.org/13543: sage: hello = var('hello') sage: label = '$' + latex(hello) + '$' sage: plot(x, x, 0, 1, legend_label=label) Graphics object consisting of 1 graphics primitive Extra keywords should be saved if object has a plot method, https://trac.sagemath.org/20924: sage: G = graphs.PetersenGraph() sage: p = G.plot() sage: p.aspect_ratio() 1.0 sage: pp = plot(G) sage: pp.aspect_ratio() 1.0
%var x y z g = golden_ratio; r = 4.77 p = 2 - (cos(x + g*y) + cos(x - g*y) + cos(y + g*z) + cos(y - g*z) + cos(z - g*x) + cos(z + g*x)) show(implicit_plot3d(p, (x, -r, r), (y, -r, r), (z, -r, r), plot_points=30, color='orange', mesh=1, opacity=.7), spin=1)
3D rendering not yet implemented
plot(prime_pi, 1, 100)

Example: Permutations

s = Permutation('(1,2)(3,4,5)'); s
[2, 1, 4, 5, 3]
s(5)
3
t = Permutation('(1,5)') s*t
[2, 5, 4, 1, 3]
t*s*t
[3, 5, 4, 1, 2]
G = PermutationGroup([s]); G
Permutation Group with generators [(1,2)(3,4,5)]
G.order()
6
G.is_cyclic()
True
G.cayley_graph().plot()
G2 = PermutationGroup([s, t]); G2
Permutation Group with generators [(1,2)(3,4,5), (1,5)]
G2.order() # full S_5
120
G2.normal_subgroups()
[Subgroup of (Permutation Group with generators [(1,2)(3,4,5), (1,5)]) generated by [()], Subgroup of (Permutation Group with generators [(1,2)(3,4,5), (1,5)]) generated by [(2,3,5), (1,4)(2,3), (1,5)(2,3)], Subgroup of (Permutation Group with generators [(1,2)(3,4,5), (1,5)]) generated by [(1,2)(3,4,5), (1,5)]]
G3 = PermutationGroup([s, Permutation('(1,2)(4,5)')]); G3.order()
12
G3.cayley_graph().plot()
G3.is_cyclic()
False
show(G3.character_table())
(1111111−11−11−11−111−11111−1−1−120−1−20120−120−1)\displaystyle \left(\begin{array}{rrrrrr} 1 & 1 & 1 & 1 & 1 & 1 \\ 1 & -1 & 1 & -1 & 1 & -1 \\ 1 & -1 & 1 & 1 & -1 & 1 \\ 1 & 1 & 1 & -1 & -1 & -1 \\ 2 & 0 & -1 & -2 & 0 & 1 \\ 2 & 0 & -1 & 2 & 0 & -1 \end{array}\right)
G3.subgroups()
[Subgroup of (Permutation Group with generators [(1,2)(4,5), (1,2)(3,4,5)]) generated by [()], Subgroup of (Permutation Group with generators [(1,2)(4,5), (1,2)(3,4,5)]) generated by [(4,5)], Subgroup of (Permutation Group with generators [(1,2)(4,5), (1,2)(3,4,5)]) generated by [(3,4)], Subgroup of (Permutation Group with generators [(1,2)(4,5), (1,2)(3,4,5)]) generated by [(3,5)], Subgroup of (Permutation Group with generators [(1,2)(4,5), (1,2)(3,4,5)]) generated by [(1,2)(4,5)], Subgroup of (Permutation Group with generators [(1,2)(4,5), (1,2)(3,4,5)]) generated by [(1,2)(3,4)], Subgroup of (Permutation Group with generators [(1,2)(4,5), (1,2)(3,4,5)]) generated by [(1,2)(3,5)], Subgroup of (Permutation Group with generators [(1,2)(4,5), (1,2)(3,4,5)]) generated by [(1,2)], Subgroup of (Permutation Group with generators [(1,2)(4,5), (1,2)(3,4,5)]) generated by [(3,5,4)], Subgroup of (Permutation Group with generators [(1,2)(4,5), (1,2)(3,4,5)]) generated by [(4,5), (1,2)(4,5)], Subgroup of (Permutation Group with generators [(1,2)(4,5), (1,2)(3,4,5)]) generated by [(3,4), (1,2)(3,4)], Subgroup of (Permutation Group with generators [(1,2)(4,5), (1,2)(3,4,5)]) generated by [(3,5), (1,2)(3,5)], Subgroup of (Permutation Group with generators [(1,2)(4,5), (1,2)(3,4,5)]) generated by [(4,5), (3,5,4)], Subgroup of (Permutation Group with generators [(1,2)(4,5), (1,2)(3,4,5)]) generated by [(3,5,4), (1,2)(4,5)], Subgroup of (Permutation Group with generators [(1,2)(4,5), (1,2)(3,4,5)]) generated by [(3,5,4), (1,2)], Subgroup of (Permutation Group with generators [(1,2)(4,5), (1,2)(3,4,5)]) generated by [(4,5), (3,5,4), (1,2)(4,5)]]
g = graphs.OctahedralGraph()
show(g)
d3-based renderer not yet implemented
g.chromatic_number()
3
g.automorphism_group()
Permutation Group with generators [(2,3), (1,2)(3,4), (0,1)(4,5)]
R.<x,y,z> = PolynomialRing(QQ,3)
(x+y+z)^3
x^3 + 3*x^2*y + 3*x*y^2 + y^3 + 3*x^2*z + 6*x*y*z + 3*y^2*z + 3*x*z^2 + 3*y*z^2 + z^3
%var x,y,z sin(exp(x+y)) * log(z)
log(z)*sin(e^(x + y))
from scipy.fftpack import fft, ifft import numpy as np
x = np.array([1.0, 2.0, 1.0, -1.0, 1.5])
y = fft(x)
y
array([ 4.50000000+0.j , 2.08155948-1.65109876j, -1.83155948+1.60822041j, -1.83155948-1.60822041j, 2.08155948+1.65109876j])