Prep Tutorials
Prep Tutorials
Release 10.5
i
7.7 Sage Quickstart for Number Theory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
7.8 Sage Quickstart for Statistics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
7.9 Sage Interact Quickstart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
ii
PREP Tutorials, Release 10.5
This is a set of tutorials developed for the MAA PREP workshops “Sage: Using Open-Source Mathematics Software with
Undergraduates” (funding provided by the National Science Foundation under grant DUE 0817071) in the summers of
2010-2012. It is licensed under the Creative Commons Attribution-ShareAlike 3.0 license (CC BY-SA).
The original audience for these tutorials was mathematics faculty at undergraduate institutions with little or no experience
with programming or computer mathematics software. Because the computer experience required is quite minimal, this
should be useful to anyone coming with little such experience to Sage.
Although any mathematics the reader is not familiar with can simply be skipped at first, we do assume throughout that
the reader is familiar with the concept of a function and different kinds of numbers. We also make liberal use of basic
examples from calculus, linear algebra, and other areas. In the Quickstart tutorials, we assume familiarity with the topics
at the level of a student who has just completed a course in the subject, or of a faculty member who is about to teach it.
Contents:
CONTENTS 1
PREP Tutorials, Release 10.5
2 CONTENTS
CHAPTER
ONE
This Sage worksheet is from a series of tutorials developed for the MAA PREP Workshop “Sage: Using Open-Source
Mathematics Software with Undergraduates” (funding provided by NSF DUE 0817071). It is licensed under the Creative
Commons Attribution-ShareAlike 3.0 license (CC BY-SA).
This document describes how to get into a Sage worksheet in the first place. If you already feel comfortable with this
process, or at least comfortable enough to see how to actually use Sage, the main content of the tutorials begins with the
introductory tutorial.
There are three main types of worksheets for Sage, all of which have somewhat similar behavior.
• If you are using the Jupyter notebook or starting Sage from the command line, you may see some screens about
exporting. We have basic information about this.
• If you are using the CoCalc SageMath worksheets, you will want to contact them or read some of their documen-
tation for further assistance.
Starting in Sage 8.0, the default is to provide the Jupyter notebook for your worksheet experience via an export screen.
When you start Sage you may see a screen like this.
3
PREP Tutorials, Release 10.5
There are three actions you can take, each of which is highlighted in the next picture. Note that if you have no previous
worksheets, the third option to “export” them will not make sense.
The legacy SageNB has been retired in Sage 9.1. Please use the Jupyter notebook. Jupyter will bring you to a screen that
If you want to start a worksheet, you will look at the upper right corner and ask for a new worksheet:
Note
The Jupyter notebook saves your files locally in your normal filesystem, as normal file names. So if you start the
notebook from a different location than usual, you may have to navigate a bit to find your worksheet.
Jupyter will allow you many types of files to open. To use SageMath directly, just choose the Sage type; this will ensure
that Jupyter runs using Sage and not pure Python or some other language.
You should now have a worksheet that looks more or less like this.
TWO
This Sage document is the first in a series of tutorials developed for the MAA PREP Workshop “Sage: Using Open-Source
Mathematics Software with Undergraduates” (funding provided by NSF DUE 0817071). It is licensed under the Creative
Commons Attribution-ShareAlike 3.0 license (CC BY-SA).
If you are unsure how to log on to a Sage server, start using a local installation, or to create a new worksheet, you might
find the prelude on logging in helpful.
Otherwise, you can continue with this tutorial, which has the following sections:
• Evaluating Sage Commands
– See Evaluating in the Jupyter notebook for the Jupyter notebook
• Functions in Sage
• Help inside Sage
• Annotating with Sage
– See Jupyter Annotation for the Jupyter notebook
This tutorial only introduces the most basic level of functionality. Later tutorials address topics such as calculus, advanced
plotting, and a wide variety of specific mathematical topics.
In a Jupyter worksheet, there are little boxes called input cells or code cells. They should be about the width of your
browser.
7
PREP Tutorials, Release 10.5
• Then, there are two options. A not-very-evident icon that looks like the “play” symbol on a recording device can
be clicked:
Or one can use the keyboard shortcut of holding down the Shift key while you press the Enter key. We call
this Shift + Enter.
Sage prints out its response just below the cell (that’s the 4 below, so Sage confirms that 2 + 2 = 4). Note also that Sage
has automatically made a new cell, and made it active, after you evaluated your first cell.
One has to learn a variety of keyboard shortcuts or click on various menu items to manipulate cells. There is a help menu
to get you started on this; the Jupyter developers also maintain an example notebook which may assist you.
To start out, let’s explore how to define and use functions in Sage.
For a typical mathematical function, it’s pretty straightforward to define it. Below, we define a function.
𝑓 (𝑥) = 𝑥2
sage: f(x)=x^2
Since all we wanted was to create the function 𝑓 (𝑥), Sage just does this and doesn’t print anything out back to us.
We can check the definition by asking Sage what f(x) is:
sage: f(x)
x^2
If we just ask Sage what f is (as opposed to f(x)), Sage prints out the standard mathematical notation for a function
that maps a variable 𝑥 to the value 𝑥2 (with the “maps to” arrow ↦→ as |-->).
sage: f
x |--> x^2
sage: f(3)
9
sage: f(3.1)
9.61000000000000
sage: f(31/10)
961/100
Notice that the output type changes depending on whether the input had a decimal; we’ll see that again below.
Naturally, we are not restricted to 𝑥 as a variable. In the next cell, we define the function 𝑔(𝑦) = 2𝑦 − 1.
sage: g(y)=2*y-1
However, we need to make sure we do define a function if we use a new variable. In the next cell, we see what happens
if we try to use a random input by itself.
sage: z^2
Traceback (most recent call last):
...
NameError: name z is not defined
This is explained in some detail in following tutorials. At this point, it suffices to know using the function notation (like
g(y)) tells Sage you are serious about y being a variable.
One can also do this with the var( z ) notation below.
sage: var( z )
z
sage: z^2
z^2
This also demonstrates that we can put several commands in one cell, each on a separate line. The output of the last
command (if any) is printed as the output of the cell.
Sage knows various common mathematical constants, like 𝜋 (pi) and 𝑒.
sage: f(pi)
pi^2
sage: f(e^-1)
e^(-2)
In order to see a numeric approximation for an expression, just type the expression inside the parentheses of N().
sage: N(f(pi))
9.86960440108936
Another option, often more useful in practice, is having the expression immediately followed by .n() (note the dot).
sage: f(pi).n()
9.86960440108936
For now, we won’t go in great depth explaining the reasons behind this syntax, which may be new to you. For those who
are interested, Sage often uses this type of syntax (known as “object-oriented”) because…
• Sage uses the Python programming language, which uses this syntax, ‘under the hood’, and
sage: pi.n(digits=20)
3.1415926535897932385
√
Sage has lots of common mathematical functions built in, like 𝑥 (sqrt(x)) and ln(𝑥) (ln(x) or log(x)).
sage: log(3)
log(3)
Notice that there is no reason to numerically evaluate log(3), so Sage keeps it symbolic. The same is true in the next cell
- 2 log(3) = log(9), but there isn’t any reason to do that; after all, depending on what you want, log(9) may be simpler or
less simple than you need.
sage: log(3)+log(3)
2*log(3)
sage: log(3).n()
1.09861228866811
Notice again that Sage tries to respect the type of input as much as possible; adding the decimal tells Sage that we have
approximate input and want a more approximate answer. (Full details are a little too complicated for this introduction.)
sage: log(3.)
1.09861228866811
sage: sqrt(2)
sqrt(2)
If we want this to look nicer, we can use the show command. We’ll see more of this sort of thing below.
sage: show(sqrt(2))
√
2
sage: sqrt(2).n()
1.41421356237310
sage: f(sqrt(2))
2
In another tutorial, we will go more in depth with plotting. Here, note that the preferred syntax has the variable and
endpoints for the plotting domain in parentheses, separated by commas.
If you are feeling bold, plot the sqrt function in the next cell between 0 and 100.
There are various ways to get help for doing things in Sage. Here are several common ways to get help as you are working
in a Sage worksheet.
2.3.1 Documentation
Sage includes extensive documentation covering thousands of functions, with many examples, tutorials, and other helps.
• One way to access these is to click the “Help” link at the top right of any worksheet, then click your preferred option
at the top of the help page.
• They are also available any time online at the Sage website, which has many other links, like video introductions.
• The Quick Reference cards are another useful tool once you get more familiar with Sage.
Our main focus in this tutorial, though, is help you can immediately access from within a worksheet, where you don’t have
to do any of those things.
The most useful help available in the notebook is “tab completion”. The idea is that even if you aren’t one hundred percent
sure of the name of a command, the first few letters should still be enough to help find it. Here’s an example.
• Suppose you want to do a specific type of plot - maybe a slope field plot - but aren’t quite sure what will do it.
• Still, it seems reasonable that the command might start with pl.
• Then one can type pl in an input cell, and then press the Tab key to see all the commands that start with the letters
pl.
Try tabbing after the pl in the following cell to see all the commands that start with the letters pl. You should see that
plot_slope_field is one of them.
sage: pl
To pick one, just click on it; to stop viewing them, press the Escape key.
You can also use this to see what you can do to an expression or mathematical object.
• Assuming your expression has a name, type it;
• Then type a period after it,
• Then press tab.
You will see a list pop up of all the things you can do to the expression.
To try this, evaluate the following cell, just to make sure 𝑓 is defined.
sage: f(x)=x^2
Now put your cursor after the period and press your Tab key.
sage: f.
sage: f.integrate(x)
x |--> 1/3*x^3
In the previous example, you might have wondered why I needed to put f.integrate(x) rather than just f.
integrate(), by analogy with sqrt(2).n().
To find out, there is another help tool one can use from right inside the notebook. Almost all documentation in Sage has
extensive examples that can illustrate how to use the function.
• As with tab completion, type the expression, period, and the name of the function.
• Then type a question mark.
• Press tab or evaluate to see the documentation.
To see how this help works, move your cursor after the question mark below and press Tab.
sage: f.integrate?
The examples illustrate that the syntax requires f.integrate(x) and not just f.integrate(). (After all, the
latter could be ambiguous if several variables had already been defined).
To stop viewing the documentation after pressing Tab, you can press the Escape key, just like with the completion of
options.
If you would like the documentation to be visible longer-term, you can evaluate a command with the question mark (like
below) to access the documentation, rather than just tabbing. Then it will stay there until you remove the input cell.
sage: binomial?
There is one more source of help you may find useful in the long run, though perhaps not immediately.
• One can use two question marks after a function name to pull up the documentation and the source code for the
function.
• Again, to see this help, you can either evaluate a cell like below, or just move your cursor after the question mark
and press tab.
The ability to see the code (the underlying instructions to the computer) is one of Sage’s great strengths. You can see all
the code to everything .
This means:
• You can see what Sage is doing.
• Your curious students can see what is going on.
• And if you find a better way to do something, then you can see how to change it!
sage: binomial??
Whether one uses Sage in the classroom or in research, it is usually helpful to describe to the reader what is being done,
such as in the description you are now reading.
• Jupyter Annotation
Thanks to a styling language called Markdown and the TeX rendering engine called MathJax, you can type much more
in Sage than just Sage commands. This math-aware setup makes Sage perfect for annotating computations.
Jupyter notebook can function as a word processor. To use this functionality, we create a Markdown cell (as opposed to
a input cell that contains Sage commands that Sage evaluates).
To do this without the keyboard shortcut, there is a menu for each cell; select “Markdown”.
Now you can type in whatever you want, including mathematics using LaTeX.
Markdown supports a fair amount of basic formatting, such as bold, underline, basic lists, and so forth.
It can be fun to type in fairly complicated math, like this:
∞ ∏︁ (︂ )︂
∑︁ 1 1
𝜁(𝑠) = = .
𝑛=1
𝑛𝑠 𝑝
1 − 𝑝−𝑠
$$\zeta(s)=\sum_{n=1}^{\infty}\frac{1}{n^s}=\prod_p \left(\frac{1}{1-p^{-s}}\right)$$
in a Markdown cell.
Of course, one can do much more, since Sage can execute arbitrary commands in the Python programming language, as
well as output nicely formatted HTML, and so on. If you have enough programming experience to do things like this, go
for it!
2.5 Conclusion
This concludes the introductory tutorial. Our hope is that now you can try finding and using simple commands and
functions in Sage. Remember, help is as close as the notebook, or at the Sage website.
2.5. Conclusion 17
PREP Tutorials, Release 10.5
THREE
This Sage document is one of the tutorials developed for the MAA PREP Workshop “Sage: Using Open-Source Math-
ematics Software with Undergraduates” (funding provided by NSF DUE 0817071). It is licensed under the Creative
Commons Attribution-ShareAlike 3.0 license (CC BY-SA).
This tutorial has the following sections:
• Symbolic Expressions
• Basic 2D Plotting
• Basic 3D Plotting
It assumes that one is familiar with the absolute basics of functions and evaluation in Sage. We provide a (very) brief
refresher.
1. Make sure the syntax below for defining a function and getting a value makes sense.
2. Then evaluate the cell by clicking the “evaluate” link, or by pressing Shift + Enter (hold down Shift while
pressing the Enter key).
sage: f(x)=x^3+1
sage: f(2)
9
In the first tutorial, we defined functions using notation similar to that one would use in (say) a calculus course.
There is a useful variant on this - defining expressions involving variables. This will give us the opportunity to point out
several important, and sometimes subtle, things.
In the cell below, we define an expression 𝐹 𝑉 which is the future value of an investment of $100, compounded contin-
uously. We then substitute in values for 𝑟 and 𝑡 which calculate the future value for 𝑡 = 5 years and 𝑟 = 5% nominal
interest.
sage: var( r,t )
(r, t)
sage: FV=100*e^(r*t)
sage: FV(r=.05,t=5)
128.402541668774
The previous cells point out several things to remember when working with symbolic expressions. Some are fairly standard.
• An asterisk (*) signifies multiplication. This should be how you always do multiplication.
19
PREP Tutorials, Release 10.5
• Although it is possible to allow implicit multiplication, this can easily lead to ambiguity.
• We can access the most important constants; for instance, 𝑒 stands for the constant 2.71828.... Likewise, pi (or
𝜋) and 𝐼 (think complex numbers) are also defined.
• Of course, if you redefine 𝑒 to be something else, all bets are off!
However, two others may be unfamiliar, especially if you have not used much mathematical software before.
• You must tell Sage what the variables are before using them in a symbolic expression.
• We did that above by typing var( r,t ).
• This is automatically done with the 𝑓 (𝑥) notation, but without that it is necessary, so that Sage knows one intends
t (for instance) is a symbolic variable and not a number or something else.
• If you then wish to substitute some values into the expression, you must explicitly tell Sage which variables are
being assigned which values.
• For instance, above we used FV(r=.05,t=5) to indicate the precise values of 𝑟 and 𝑡.
Notice that when we define a function, we don’t need to specify which variable has which value. In the function defined
below, we have already specified an order.
sage: FV2(r,t)=100*e^(r*t)
sage: FV2(.05,5)
128.402541668774
Also remember that when we don’t use function notation, we’ll need to define our variables.
One of the great things we can do with expressions is manipulate them. Let’s make a typical expression.
sage: z = (x+1)^3
In the cells below, you’ll notice something new: the character #. In Sage (and in Python ), anything on a single line after
the number/pound sign (the octothorp ) is ignored. We say that # is a comment character. We use it below to mention
alternative ways to do the same thing.
sage: expand(z) # or z.expand()
x^3 + 3*x^2 + 3*x + 1
sage: y = expand(z)
sage: y.factor() # or factor(y)
(x + 1)^3
In the previous cell, we assigned the expression which is the expansion of 𝑧 to the variable 𝑦 with the first line. After that,
anything we want to do to the expansion of 𝑧 can be done by doing it to 𝑦.
There are more commands like this as well. Notice that 𝑧 will no longer be (𝑥 + 1)3 after this cell is evaluated, since
we’ve assigned 𝑧 to a (much more complex) expression.
sage: z = ((x - 1)^(3/2) - (x + 1)*sqrt(x - 1))/sqrt((x - 1)*(x + 1))
sage: z.simplify_full()
-2*sqrt(x - 1)/sqrt(x^2 - 1)
sage: z.simplify
<built-in method simplify of sage.symbolic.expression.Expression object at ...>
Finally, recall that you can get nicely typeset versions of the output in several ways.
• One option is to click the ‘Typeset’ button at the top.
• Another - which does not require scrolling! - is to use the show command.
sage: show(z.simplify_rational())
√
2 𝑥−1
−√
𝑥2 − 1
Another Sage command that is useful in this context is solve.
Here, we solve the simple equation 𝑥2 = −1.
• In the solve command, one types an equals sign in the equation as two equal signs.
• This is because the single equals sign means assignment to a variable, as we’ve done above, so Sage (along with
Python) uses the double equals sign for symbolic equality.
• We also include the variable we’d like to solve for after the comma.
It’s also possible to solve more than one expression simultaneously.
sage: solve([x^2==1,x^3==1],x)
[[x == 1]]
One of the other basic uses of mathematics software is easy plotting. Here, we include a brief introduction to the sorts
of plotting which will prepare us to use Sage in calculus. (There will be a separate tutorial for more advanced plotting
techniques.)
Recall that we can generate a plot using fairly simple syntax. Here, we define a function of 𝑥 and plot it between −1 and
1.
sage: f(x)=x^3+1
sage: plot(f,(x,-1,1))
Graphics object consisting of 1 graphics primitive
We can give the plot a name, so that if we want to do something with the plot later, we don’t have to type out the entire
plot command. Remember, this is called assigning the plot to the name/variable.
In the next cell, we give the plot the name 𝑃 .
sage: P=plot(f,(x,-1,1))
One plot is nice, but one might want to superimpose plots as well. For instance, the tangent line to 𝑓 at 𝑥 = 0 is just the
line 𝑦 = 1, and we might want to show this together with the plot.
So let’s plot this line in a different color, and with a different style for the line, but over the same interval.
Because we put 𝑄 in a line by itself at the end, it shows. We were able to use just one cell to define 𝑄 and show it, by
putting each command in a separate line in the same input cell.
Now to show the plots superimposed on each other, we simply add them.
sage: P+Q
Graphics object consisting of 2 graphics primitives
sage: (P+Q).show(xmin=-.1,xmax=.1,ymin=.99,ymax=1.01)
Since the axes no longer cross in the frame of reference, Sage shows a short gap between the horizontal and vertical axes.
There are many options one can pass in for various purposes.
• Some require quotes around the values.
• Such as the color option when we made a "red" line.
• Some do not.
• Such as the xmin in the previous plot, where the minimum x value was just −.1
Usually (though not always) quotes are required for option values which are words or strings of characters, and not required
for numerical values.
Two of the most useful of these options help in labeling graphs.
• The axes_labels option labels the axes.
• As with the word processor, we can use dollar signs (like in LaTeX) to make the labels typeset nicely.
• Here we need both quotes and brackets for proper syntax, since there are two axes to label and the labels are not
actually numbers.
sage: P1+P2
Graphics object consisting of 2 graphics primitives
One additional useful note is that plots of functions with vertical asymptotes may need their vertical viewing range set
manually; otherwise the asymptote may really go to infinity!
sage: plot(1/x^2,(x,-10,10),ymax=10)
Graphics object consisting of 1 graphics primitive
Remember, you can use the command plot? to find out about most of the options demonstrated above.
Below, you can experiment with several of the plotting options.
• Just evaluate the cell and play with the sliders, buttons, color picker, etc., to change the plot options.
• You can access low-level options like the initial number of plotted points, or high-level ones like whether axes are
shown or not.
• This uses a feature of Sage called “interacts”, which is a very powerful way to engage students in exploring a
problem.
sage: x = var( x )
sage: @interact
sage: def plot_example(f=sin(x^2),r=range_slider(-5,5,step_size=1/4,default=(-3,3)),
....: color=color_selector(widget= colorpicker ),
....: thickness=(3,(1..10)),
....: adaptive_recursion=(5,(0..10)), adaptive_tolerance=(0.01,(0.
˓→001,1)),
....: plot_points=(20,(1..100)),
....: linestyle=[ - , -- , -. , : ],
....: gridlines=False, fill=False,
....: frame=False, axes=True
....: ):
....: show(plot(f, (x,r[0],r[1]), color=color, thickness=thickness,
....: adaptive_recursion=adaptive_recursion,
....: adaptive_tolerance=adaptive_tolerance, plot_points=plot_points,
....: linestyle=linestyle, fill=fill if fill else None),
....: gridlines=gridlines, frame=frame, axes=axes)
Plotting a 3D plot is similar to plotting a 2D plot, but we need to specify ranges for two variables instead of one.
sage: g(x,y)=sin(x^2+y^2)
sage: plot3d(g,(x,-5,5),(y,-5,5))
Graphics3d Object
• If you have a wheel on your mouse or a multi-touch trackpad, you can scroll to zoom.
• You can also right-click to see other options, such as
• spinning the plot,
• changing various colors,
• and even making the plot suitable for viewing through 3D glasses (under the “style”, then “stereographic” submenus),
When using the plot3d command, the first variable range specified is plotted along the usual “x” axis, while the second
range specified is plotted along the usual “y” axis.
The plot above is somewhat crude because the function is not sampled enough times - this is fairly rapidly changing
function, after all. We can make the plot smoother by telling Sage to sample the function using a grid of 300 by 300
points. Sage then samples the function at 90,000 points!
sage: plot3d(g,(x,-5,5),(y,-5,5),plot_points=300)
Graphics3d Object
As usual, only the last command shows up in the notebook, though clearly all are evaluated. This also demonstrates that
many of the same options work for 3D plots as for 2D plots.
We close this tutorial with a cool plot that we define implicitly as a 3D contour plot.
sage: r = 4.78
sage: implicit_plot3d(p, (x, -r, r), (y, -r, r), (z, -r, r), plot_points=50, color=
˓→ yellow )
Graphics3d Object
The next tutorial will use all that you have learned about Sage basics, symbolics, and plotting in a specific mathematical
venue - the calculus sequence!
FOUR
This Sage document is one of the tutorials developed for the MAA PREP Workshop “Sage: Using Open-Source Math-
ematics Software with Undergraduates” (funding provided by NSF DUE 0817071). It is licensed under the Creative
Commons Attribution-ShareAlike 3.0 license (CC BY-SA).
This tutorial has the following sections. The first three are based on the topics encountered in a typical three-semester
calculus sequence in the United States; the final section is a checkpoint of sorts.
• Calculus 1
• Calculus 2
• Calculus 3
• ‘Exam’
The tutorial assumes that one is familiar with the basics of Sage, such as outlined in the previous tutorials.
For a refresher, make sure the syntax below for defining a function and getting a value makes sense; then evaluate the cell
by clicking the “evaluate” link, or by pressing Shift + Enter (hold down Shift while pressing the Enter key).
sage: f(x)=x^3+1
sage: f(2)
9
We’ll use this function several times in this tutorial, so it’s important that it is evaluated!
4.1 Calculus 1
The calculus is amazing not so much because it solves problems of tangency or area - individual solutions to these problems
have been known before. It is amazing because it gives a remarkably comprehensive set of rules for symbolic manipulation
for solving such problems in great generality!
Thus, the most typical use of a computer system like Sage in this context is simply to help check (or make less tedious)
basic symbolic manipulation of things like derivatives. Let’s first show what our function 𝑓 is again, then do things with
it.
sage: show(f)
𝑥 ↦→ 𝑥3 + 1
Something most (but not all) curricula for first-semester calculus do is spend a fair amount of time with limits.
What is the limit of this function as 𝑥 approaches 1?
25
PREP Tutorials, Release 10.5
sage: lim(f,x=1)
x |--> 2
Sage gives the answer we expect. The syntax for limits is pretty straightforward, though it may differ slightly from that of
other systems.
Since a limit may exist even if the function is not defined, Sage uses the syntax x=1 to show the input value approached
in all situations.
sage: lim((x^2-1)/(x-1),x=1)
2
Next, we’ll return to the original function, and check the two directional limits.
The syntax uses the extra keyword dir.
• Notice that we use dir= right , not dir=right.
• It’s also okay to use dir= + , like we use dir= - below.
• This is basically because otherwise we might have done something like let right=55 earlier, so instead Sage -
and Python - requires us to put right and - in quotes to make it clear they are not variables.
sage: derivative(sinh(x^2+sqrt(x-1)),x)
1/2*(4*x + 1/sqrt(x - 1))*cosh(x^2 + sqrt(x - 1))
And maybe even knows those you do not want. In this case, we put the computation inside show() since the output is
so long.
sage: show(derivative(sinh(x^2+sqrt(x-1)),x,3))
)︂3 (︃ )︃(︂
)︀ 3 cosh 𝑥 − 1 + 𝑥2
(︂ )︂ (︀√ )︀
1 1 )︀ 3 1 1
cosh 𝑥 − 1 + 𝑥 −
2
sinh 𝑥 − 1 + 𝑥 +
2
(︀√ (︀√
4𝑥 + √ −8 4𝑥 + √
8 (𝑥 − 1) 32
(︀ 5 )︀
8 𝑥−1 𝑥−1 8 (𝑥 − 1) 2
A common question is why Sage might not check automatically if there is some “simpler” version. But simplifying an
expression, or indeed, even defining what a ‘simple’ expression is, turns out to be a very hard technical and mathematical
problem in general. Computers will not solve every problem!
As a brief interlude, let’s consider an application of our ability to do some basic differential calculus.
First, as a reminder of plotting from the previous tutorial, try to plot the function 𝑓 (𝑥), together with its tangent line at
𝑥 = 1, in the empty cells below. (If you can, do it without looking at the previous tutorial for a reminder.)
Did you get it?
Of course, in general we might want to see tangent lines at lots of different points - for instance, for a class demonstration.
So in the following cell, there are several auxiliary elements:
• We define the plot P of the original function.
• There is a parameter c=1/3, which is the 𝑥-value where we want a tangent line.
• We let fprime be the derivative function simply by declaring it equal to the derivative.
• We let L be the tangent line defined by the point-slope formula at 𝑥 = 𝑐.
• We make Q be the plot of this line.
Finally, we plot everything together in the last line by adding 𝑃 + 𝑄.
sage: P=plot(f,(x,-1,1))
sage: c=1/3
sage: fprime=derivative(f,x)
sage: L(x)=fprime(c)*(x-c)+f(c)
sage: Q=plot(L,(x,-1,1), color="red", linestyle="--")
sage: P+Q
Graphics object consisting of 2 graphics primitives
sage: %auto
sage: f(x)=x^3+1
sage: @interact
sage: def _(c=(1/3,(-1,1))):
....: P=plot(f,(x,-1,1))
....: fprime=derivative(f,x)
....: L(x)=fprime(c)*(x-c)+f(c)
....: Q=plot(L,(x,-1,1),color="red", linestyle="--")
....: show(P+Q+point((c,f(c)), pointsize=40, color= red ),ymin=0,ymax=2)
A very sharp-eyed reader will also have noticed that the previous cell had %auto at the very top, and that it was not
necessary to evaluate the cell to use it.
• The command %auto allows us to have a cell, especially an interactive one, all loaded up as soon as we start -
particularly convenient for a classroom situation.
4.1. Calculus 1 27
PREP Tutorials, Release 10.5
• Such instructions are called percent directives . Most are documented in the notebook help one can access at the
top of any worksheet.
A final topic in Calculus 1 usually is basic integration. The syntax for indefinite integration is similar to that for differenti-
ation.
sage: integral(cos(x),x)
sin(x)
4.2 Calculus 2
Since I defined h as a function, the answer I get is also a function. If I just want an expression as the answer, I can do the
following.
sage: integrate(sec(x),x)
log(sec(x) + tan(x))
Here is another (longer) example. Do you remember what command would help it look nicer in the browser?
sage: integrate(1/(1+x^5),x)
1/5*sqrt(5)*(sqrt(5) + 1)*arctan((4*x + sqrt(5) - 1)/sqrt(2*sqrt(5) + 10))/
˓→sqrt(2*sqrt(5) + 10)
Some integrals are a little tricky, of course. Sage tries hard to integrate using Maxima, Sympy, and (optionally, if installed)
Giac. The following can only be integrated by Giac:
sage: integral(e^(-x^2),x)
1/2*sqrt(pi)*erf(x)
Do not forget, if this function is unfamiliar to you (as it might be to students trying this integral), Sage’s contextual help
system comes to the rescue.
sage: erf?
into
∫︁ 𝑏
𝑓 (𝑥)𝑑𝑥 ,
𝑎
sage: integral(cos(x),(x,0,pi/2))
1
The preferred syntax puts the variable and endpoints together in parentheses.
Just like with derivatives, we can visualize this integral using some of the plotting options from the plotting tutorial.
4.2. Calculus 2 29
PREP Tutorials, Release 10.5
sage: plot(cos(x),(x,0,pi/2),fill=True,ticks=[[0,pi/4,pi/2],None],tick_formatter=pi)
Graphics object consisting of 2 graphics primitives
It is possible to be completely symbolic in doing integration. If you do this, you’ll have to make sure you define anything
that’s a symbolic variable - which includes constants, naturally.
On the numerical side, sometimes the answer one gets from the Fundamental Theorem of Calculus is not entirely helpful.
Recall that ℎ is the secant function.
sage: integral(h,(x,0,pi/7))
1/2*log(sin(1/7*pi) + 1) - 1/2*log(-sin(1/7*pi) + 1)
Here, just a number might be more helpful. Sage has several ways of numerical evaluating integrals.
• Doing a definite integral symbolically, then approximating it numerically
• The numerical_integral function
• The . nintegrate method
The first one, using the n or N function for numerical approximation, was also mentioned in the introductory tutorial.
sage: N(integral(h,(x,0,pi/8)))
0.403199719161511
The second function, numerical_integral, uses a powerful numerical program (the GNU Scientific Library).
• Unfortunately, the syntax for this function is not yet consistent with the rest of Sage.
• Helpfully, the output has two elements - the answer you desire, and its error tolerance.
sage: numerical_integral(h,0,pi/8)
(0.4031997191615114, 4.476416117355069e-15)
To access just the number, one asks for the ‘zeroth’ element of this sequence of items. This is done with the following
bracket notation.
sage: numerical_integral(h,0,pi/8)[0]
0.4031997191615114
Notice that we began counting at zero. This is fairly typical in computer programs (though certainly not universal).
To aid readability (more important than one might think), we often assign the numerical integral to a variable, and then
take the zeroth element of that.
sage: ni = numerical_integral(h,0,pi/8)
sage: ni[0]
0.4031997191615114
Finally, the .nintegrate() method from Maxima gives even more extra information.
• Notice again the period/dot needed to use this.
• It is only possible to use h(x); doing h.nintegrate() raises an error.
sage: h(x).nintegrate(x,0,pi/8)
(0.4031997191615114, 4.47641611735507e-15, 21, 0)
Second-semester calculus usually also covers various topics in summation. Sage can sum many abstract series; the notation
is similar to plotting and integration.
Do you remember what to do to see how we typed the nice sum in the text above? That’s right, we can double-click the
text area/cell to see this.
Sage also can compute Taylor polynomials.
Taylor expansions depend on a lot of things. Whenever there are several inputs, keeping syntax straight is important.
Here we have as inputs:
• the function,
• the variable,
• the point around which we are expanding the function, and
• the degree.
In the next cell, we call 𝑔(𝑥) the Taylor polynomial in question.
4.2. Calculus 2 31
PREP Tutorials, Release 10.5
4.3 Calculus 3
We have already seen three-dimensional plotting, so it is not surprising that Sage has support for a variety of multivariable
calculus problems.
Warning
sage: var( y )
y
sage: f(x,y)=3*sin(x)-2*cos(y)-x*y
In an effort to make the syntax simpler, the gradient and Hessian are also available by asking for a total derivative. We
also ask for nicer output again.
sage: show(f.diff(2).det())
Rather than actually figure out the unit vector in that direction, it’s easier to let Sage compute it by dividing the vector by
its norm.
The directional derivative itself (in that direction, at the origin) can also be computed in this way.
sage: (f.diff()*u/u.norm())(0,0)
3/5*sqrt(5)
sage: y = var( y )
sage: contour_plot(y^2 + 1 - x^3 - x, (x,-pi,pi), (y,-pi,pi),\
....: contours=[-8,-4,0,4,8], colorbar=True, labels=True, label_colors= red )
Graphics object consisting of 1 graphics primitive
sage: integrate(integrate(f,(x,0,pi)),(y,0,pi))
6*pi - 1/4*pi^4
Answer: notice that integrate(f,(x,0,pi)) has been itself placed as the function inside integrate(...,
(y,0,pi)).
We could use a 3D plot to help visualize this; these were already mentioned in the symbolics and plotting tutorial.
In addition to multivariate calculus, Calculus 3 often covers parametric calculus of a single variable. Sage can do arbitrary
parametric plots, with fairly natural syntax.
This plot shows the tangent line to the most basic Lissajous curve at 𝑡 = 1. The commands should be strongly reminiscent
of the ones at the beginning of this tutorial.
sage: t = var( t )
sage: my_curve(t)=(sin(t), sin(2*t))
sage: PP=parametric_plot( my_curve, (t, 0, 2*pi), color="purple" )
sage: my_prime=my_curve.diff(t)
sage: L=my_prime(1)*t+my_curve(1) # tangent line at t=1
sage: parametric_plot(L, (t,-2,2))+PP
Graphics object consisting of 2 graphics primitives
4.3. Calculus 3 33
PREP Tutorials, Release 10.5
Tip
• After a while, you’ll find that giving things names other than f and g becomes quite helpful in distinguishing
things from each other. Use descriptive names! We have tried to do so here.
• If you are adventurous, try turning this into an interactive cell along the lines of the single variable example
earlier!
4.4 ‘Exam’
Before moving out of the calculus world, it is good to have a sort of miniature exam.
In the cell below, we have plotted and given:
• A slope field for a differential equation,
• A solution to an initial value problem,
• And a symbolic formula for that solution.
We assume you have never seen several of the commands before. Can you nonetheless figure out which commands are
doing each piece, and what their syntax is? How would you look for help to find out more?
sage: y = var( y )
sage: Plot1=plot_slope_field(2-y,(x,0,3),(y,0,20))
sage: y = function( y ,x) # declare y to be a function of x
sage: h = desolve(diff(y,x) + y - 2, y, ics=[0,7])
sage: Plot2=plot(h,0,3)
sage: show(expand(h)); show(Plot1+Plot2)
5 𝑒(−𝑥) + 2
Ready to see the answers? Do not peek until you have really tried it.
In this cell we do the following:
• Make sure that y is indeed a variable for the first plot.
• Create a slope field for the DE for appropriate inputs of 𝑥 and 𝑦, and give the plot the name Plot1.
• Use the formalism of the function command to get ready for the DE.
• Notice we have here once again used # to indicate a comment.
• In this case, in order to use common terminology, we now have told Sage y is no longer a variable, but instead a
function (abstract) of the variable x.
• Use the differential equation solving command, with I**nitial **C**ondition **S of 2 and 2.
• Plot the solution and give it the name Plot2.
• Show a simplification of the symbolic version of the solution (which we did not know ahead of time!) as well as
the sum of the two graphs - the solution against the slope field.
As you gain experience, you will see how to glean what you are looking for from examples in the documentation like this
- which is one of the real goals of these tutorials.
Congratulations! You are now armed with the basics of deploying Sage in the calculus sequence.
FIVE
This Sage document is one of the tutorials developed for the MAA PREP Workshop “Sage: Using Open-Source Math-
ematics Software with Undergraduates” (funding provided by NSF DUE 0817071). It is licensed under the Creative
Commons Attribution-ShareAlike 3.0 license (CC BY-SA).
This tutorial will cover the following topics (and various others throughout):
• Methods and Dot Notation
• Lists, Loops, and Set Builders
• Defining Functions
• Gotchas from names and copies
• Appendix: Advanced Introductory Topics
We will motivate our examples using basic matrices and situations one might want to handle in everyday use of matrices
in the classroom.
sage: A = matrix([[1,2],[3,4]])
As we can see, this gives the matrix with rows given in the two bracketed sets.
sage: A
[1 2]
[3 4]
Some commands are available right off the bat, like derivatives are. This is the determinant.
sage: det(A)
-2
But some things are not available this way - for instance a row-reduced echelon form. We can ‘tab’ after this to make sure.
sage: r
So, as we’ve already seen in previous tutorials, many of the commands in Sage are “methods” of objects.
That is, we access them by typing:
• the name of the mathematical object,
35
PREP Tutorials, Release 10.5
• a dot/period,
• the name of the method, and
• parentheses (possibly with an argument).
This is a huge advantage, once you get familiar with it, because it allows you to do only the things that are possible, and
all such things.
First, let’s do the determinant again.
sage: A.det()
-2
sage: A.rref()
[1 0]
[0 1]
Note
Things that would be legal without them would be called ‘attributes’, but Sage prefers stylistically to hide them, since
math is made of functions and not elements of sets. Or so a category-theorist would say.
sage: A.det # Won t work
<built-in method det of sage.matrix.matrix_integer_dense.Matrix_integer_dense␣
˓→object at ...>
sage: A.
Sometimes you will have surprises. Subtle changes in an object can affect what commands are available, or what their
outcomes are.
sage: A.echelon_form()
[1 0]
[0 2]
This is because our original matrix had only integer coefficients, and you can’t make the last entry one via elementary
operations unless you multiply by a rational number!
Another question is whether one needs an argument. Remember, it’s easy to just read the documentation!
Below, let’s see whether we need an argument to get a column.
sage: A.column?
sage: A.column(1)
(2, 4)
In the previous example, we saw that the 1 choice for the column of a matrix gives the second column.
sage: matrix([[1,2],[3,4]]).column(1)
(2, 4)
You might have thought that the would give the first column, but Sage (along with the Python programming language)
begins numbering of anything that is like a sequence at zero. We’ve mentioned this once before, but it’s very important
to remember.
To reinforce this, let’s formally introduce a fundamental object we’ve seen once or twice before, called a list.
You should think of a list as an ordered set, where the elements of the set can be pretty much anything - including other
lists.
sage: my_list=[2, Grover ,[3,2,1]]; my_list
[2, Grover , [3, 2, 1]]
You can access any elements of such a list quite easily using square brackets. Just remember that the counting starts at
zero.
sage: my_list[0]; my_list[2]
2
[3, 2, 1]
However, our main reason for introducing this is more practical, as we’ll now see.
• One of the best uses of the computer in the classroom is to quickly show tedious things.
• One of the most tedious things to do by hand in linear algebra is taking powers of matrices.
• Here we make the first four powers of our matrix ‘by hand’.
sage: A = matrix([[1,2],[3,4]])
sage: A^0; A^1; A^2; A^3; A^4
[1 0]
[0 1]
(continues on next page)
This is not terrible, but it’s not exactly nice either, particularly if you might want to do something with these new matrices.
Instead, we can do what is known as a loop construction. See the notation below; it’s at least vaguely mathematical.
These ways of constructing lists are very useful - and demonstrate that, like many Sage/Python things, that counting begins
at zero and ends at one less than the “end” in things like range.
Below, we show that one can get step sizes other than one as well.
Note
It is also important to emphasize that the range command does not include its last value! For a quick quiz, confirm
this in the examples above.
This all works well. However, after a short time this will seem tedious as well (you may have to trust us on this). It turns
out that there is a very powerful way to create such lists in a way that very strongly resembles the so-called set builder
notation, called a list comprehension .
We start with a relatively easy example:
{𝑛2 | 𝑛 ∈ , 3 ≤ 𝑛 ≤ 12}
Now we apply it to the example we were doing in the first place. Notice we now have a nice concise description of all
determinants of these matrices, without the syntax of colon and indentation:
5.2.1 Tables
Notice that each element of this list is two items in parentheses (a so-called tuple).
Even better, we can put a header line on it to make it really clear what we are doing, by adding lists. We’ve seen keywords
like header=True when doing some of our plotting and limits. What do you think will happen if you put dollar signs
around the labels in the header?
It is often the case that Sage can do something, but doesn’t have a simple command for it. For instance, you might want
to take a matrix and output the square of that matrix minus the original matrix.
sage: A = matrix([[1,2],[3,4]])
sage: A^2-A
[ 6 8]
[12 18]
How might one do this for other matrices? Of course, you could just always do 𝐴2 − 𝐴 again and again. But this would be
tedious and hard to follow, as with so many things that motivate a little programming. Here is how we solve this problem.
The def command has created a new function called square_and_subtract. It should even be available using
tab-completion.
Here are things to note about its construction:
• The input is inside the parentheses.
• The indentation and colon are crucial, as above.
• There will usually be a return value, given by return. This is what Sage will give below the input cell.
sage: square_and_subtract(A)
[ 6 8]
[12 18]
sage: square_and_subtract(matrix([[1.5,0],[0,2]]))
[0.750000000000000 0.000000000000000]
[0.000000000000000 2.00000000000000]
sage: square_and_subtract?
Pretty cool! And potentially quite helpful to students - and you - especially if the function is complicated. The 𝐴 typesets
properly because we put it in backticks (see above).
A very careful reader may have noticed that there is nothing that requires the input mymatrix to be a matrix. Sage will
just try to square whatever you give it and subtract the original thing.
sage: square_and_subtract(sqrt(5))
-sqrt(5) + 5
This is a typical thing to watch out for; just because you define something doesn’t mean it’s useful (though in this case it
was).
Try to define a function which inputs a matrix and returns the determinant of the cube of the matrix. (There are a few
ways to do this, of course!)
Before we finish the tutorial, we want to point out a few programming-related things that often trip people up.
The first ‘gotcha’ is that it’s possible to clobber constants!
sage: i
4
Can you figure out why i=4? Look carefully above to see when this happened.
• This gives a valuable lesson; any time you use a name there is potential for renaming.
This may seem quite bad, but could be quite logical to do - for instance, if you are only dealing with real matrices. It is
definitely is something a Sage user needs to know, though.
Luckily, it’s possible to restore symbolic constants.
sage: reset( i )
sage: i; i^2
I
-1
sage: type(e)
<class sage.symbolic.expression.E >
sage: type(pi)
<class sage.symbolic.expression.Expression >
Variables are another thing to keep in mind. As mentioned briefly in earlier tutorials, in order to maintain maximum
flexibility while not allowing things to happen which shouldn’t, only x is predefined, nothing else.
sage: type(x)
<class sage.symbolic.expression.Expression >
sage: type(y)
Traceback (most recent call last):
...
NameError: name y is not defined
Warning
There is a way to get around this, but it unleashes a horde of potential misuse. See the cells below if you are interested
in this.
sage: automatic_names(True) # not tested
sage: trig_expand((2*x + 4*y + sin(2*theta))^2) # not tested
4*(sin(theta)*cos(theta) + x + 2*y)^2
Another related issue is that a few names are “reserved” by Python/Sage, and which aren’t allowed as variable names.
It’s not surprising that ‘for’ is not allowed, but neither is ‘lambda’ (𝜆)! People often request a workaround for that.
There are lots of ways to get around this. One popular, though annoying, way is this.
sage: lambda_^2-1
lambda_^2 - 1
Still, in this one case, showing the expression still shows the Greek letter.
sage: show(lambda_^2-1)
𝜆2 − 1
Finally, there is another thing that can happen if you rename things too loosely.
sage: A = matrix(QQ,[[1,2],[3,4]])
sage: B = A
sage: C = copy(A)
This actually has just made B and A refer to the same matrix. B isn’t like A, it is A. The copy command gets around
this (though not always).
sage: A[0,0]=987
sage: show([A,B,C])
[︂(︂ )︂ (︂ )︂ (︂ )︂]︂
987 2 987 2 1 2
, ,
3 4 3 4 3 4
This is very subtle if you’ve never programmed before. Suffice it to say that it is safest to let each = sign stand for one
thing, and to avoid redundant equals (unlike students at times).
There are several things which are useful to know about, but which are not always introduced immediately in programming.
We give a few examples here, but they are mainly here to make sure you have seen them so that they are not completely
surprising when they come up again.
We saw the “block” structure of Python earlier, with the indentation. This gives the opportunity to introduce conditional
statements and comparisons. Here, we just give an example for those who have seen conditionals (“if” clauses) before.
sage: B = matrix([[0,1,0,0],[0,0,1,0],[0,0,0,1],[0,0,0,0]])
sage: for i in range(5): # all integers from 0 to 4, remember
....: if B^i==0: # We ask if the power is the zero matrix
....: print(i)
4
We use the double equals sign to test for equality, because = assigns something to a variable name. Notice again that
colons and indentation are the primary way that Sage/Python indicate syntax, just as commas and spaces do in English.
Another useful concept is that of a dictionary . This can be thought of as a mathematical mapping from “keys” to “values”.
The order is not important and not guaranteed. A dictionary is delimited by curly brackets and correspondence is indicated
by colons.
Again, we will just give a small example to illustrate the idea.
What if one wants to specify a matrix using just the nonzero entries? A dictionary is a great way to do this.
This one puts 3 as an entry in the (2, 3) spot, for example (remember, this is the third row and fourth column, since we
start with zero).
sage: a = 2
sage: b = 2/1
sage: c = 2.0
sage: d = 2 + 0*I
sage: e = 2.0 + 0.0*I
sage: parent(a)
Integer Ring
sage: parent(b)
Rational Field
sage: parent(c)
Real Field with 53 bits of precision
sage: parent(d)
Number Field in I with defining polynomial x^2 + 1 with I = 1*I
sage: parent(e)
Complex Field with 53 bits of precision
SIX
This Sage document is one of the tutorials developed for the MAA PREP Workshop “Sage: Using Open-Source Math-
ematics Software with Undergraduates” (funding provided by NSF DUE 0817071). It is licensed under the Creative
Commons Attribution-ShareAlike 3.0 license (CC BY-SA).
Thanks to Sage’s integration of projects like matplotlib, Sage has comprehensive two-dimensional plotting capabilities.
This worksheet consists of the following sections:
• Cartesian Plots
• Parametric Plots
• Polar Plots
• Plotting Data Points
• Contour Plots
• Vector fields
• Complex Plots
• Region plots
• Builtin Graphics Objects
• Saving Plots
This tutorial assumes that one is familiar with the basics of Sage, such as evaluating a cell by clicking the “evaluate” link,
or by pressing Shift + Enter (hold down Shift while pressing the Enter key).
45
PREP Tutorials, Release 10.5
Problem : Plot a green 𝑦 = sin(𝑥) together with a red 𝑦 = 2 cos(𝑥). (Hint: you can use pi as part of your range.)
Boundaries of a plot can be specified, in addition to the overall size.
sage: plot(1+e^(-x^2), xmin=-2, xmax=2, ymin=0, ymax=2.5, figsize=10)
Graphics object consisting of 1 graphics primitive
You can fill regions with transparent color, and thicken the curve. This example uses several options to fine-tune our
graphic.
sage: exponential = plot(1+e^(-x^2), xmin=-2, xmax=2, ymin=0, ymax=2.5, fill=0.5,␣
˓→fillcolor= grey , fillalpha=0.3)
Problem : Create a plot showing the cross-section area for the following solid of revolution problem: Consider the area
bounded by 𝑦 = 𝑥2 − 3𝑥 + 6 and the line 𝑦 = 4. Find the volume created by rotating this area around the line 𝑦 = 1.
A parametric plot needs a list of two functions of the parameter; in Sage, we use square brackets to delimit the list.
Notice also that we must declare t as a variable first. Because the graphic is slightly wider than it is tall, we use the
aspect_ratio option (such options are called keywords ) to ensure the axes are correct for how we want to view this
object.
sage: t = var( t )
sage: parametric_plot([cos(t) + 3 * cos(t/9), sin(t) - 3 * sin(t/9)], (t, 0, 18*pi),␣
˓→fill = True, aspect_ratio=1)
sage: r = var( r )
sage: parametric_plot((t^2,sin(r*t),cos(r*t)), (t,0,pi),(r,-1,1))
Graphics3d Object
Although they aren’t essential, many of these examples try to demonstrate things like coloring, fills, and shading to give
you a sense of the possibilities.
More than one polar curve can be specified in a list (square brackets). Notice the automatic graded shading of the fill
color.
sage: t = var( t )
sage: polar_plot([cos(4*t) + 1.5, 0.5 * cos(4*t) + 2.5], (t, 0, 2*pi),
....: color= black , thickness=2, fill=True, fillcolor= orange )
Graphics object consisting of 4 graphics primitives
Problem: Create a plot for the following problem. Find the area that is inside the circle 𝑟 = 2, but outside the cardioid
2 + 2 cos(𝜃).
It may be of interest to see all these things put together in a very nice pedagogical graphic. Even though this is fairly
advanced, and so you may want to skip the code, it is not as difficult as you might think to put together.
sage: html( <h2>Sine and unit circle (by Jurgis Pralgauskis)</h2> inspired by <a href=
˓→"http://www.youtube.com/watch?v=Ohp6Okk_tww&feature=related">this video</a> )
sage: # http://doc.sagemath.org/html/en/reference/sage/plot/plot.html
sage: radius = 100 # scale for radius of "unit" circle
sage: graph_params = dict(xmin = -2*radius, xmax = 360,
....: ymin = -(radius+30), ymax = radius+30,
....: aspect_ratio=1,
....: axes = False
....: )
sage: def sine_and_unit_circle( angle=30, instant_show = True, show_pi=True ):
....: ccenter_x, ccenter_y = -radius, 0 # center of circle on real coords
....: sine_x = angle # the big magic to sync both graphs :)
....: current_y = circle_y = sine_y = radius * sin(angle*pi/180)
....: circle_x = ccenter_x + radius * cos(angle*pi/180)
....: graph = Graphics()
....: # we ll put unit circle and sine function on the same graph
....: # so there will be some coordinate mangling ;)
....: # CIRCLE
....: unit_circle = circle((ccenter_x, ccenter_y), radius, color="#ccc")
....: # SINE
....: x = var( x )
(continues on next page)
Sometimes one wishes to simply plot data. Here, we demonstrate several ways of plotting points and data via the simple
approximation to the Fibonacci numbers given by
(︃ √ )︃𝑛
1 1+ 5
𝐹𝑛 = √ ,
5 2
sage: fibonacci_sequence(6)
<generator object fibonacci_sequence at ...>
sage: list(fibonacci_sequence(6))
[0, 1, 1, 2, 3, 5]
The enumerate command is useful for taking a list and coordinating it with the counting numbers.
sage: list(enumerate(fibonacci_sequence(6)))
[(0, 0), (1, 1), (2, 1), (3, 2), (4, 3), (5, 5)]
So we just define the numbers and coordinate pairs we are about to plot.
˓→160*sqrt(5)*(sqrt(5) + 1)^5)]
Now we can plot not just the two sets of points, but also use several of the documented options for plotting points. Those
coming from other systems may prefer list_plot.
Other options include line, points, and scatter_plot. Having the choice of markers for different data is partic-
ularly helpful for generating publishable graphics.
Contour plotting can be very useful when trying to get a handle on multivariable functions, as well as modeling. The basic
syntax is essentially the same as for 3D plotting - simply an extension of the 2D plotting syntax.
sage: f(x,y)=y^2+1-x^3-x
sage: contour_plot(f, (x,-pi,pi), (y,-pi,pi))
Graphics object consisting of 1 graphics primitive
We can change colors, specify contours, label curves, and many other things. When there are many levels, the colorbar
keyword becomes quite useful for keeping track of them. Notice that, as opposed to many other options, it can only be
True or False (corresponding to whether it appears or does not appear).
This example is fairly self-explanatory, but demonstrates the power of formatting, labeling, and the wide variety of built-in
color gradations (colormaps or cmap). The strange-looking construction corresponding to label_fmt is a Sage/Python
data type called a dictionary , and turns out to be useful for more advanced Sage use; it consists of pairs connected by a
colon, all inside curly braces.
Implicit plots are a special type of contour plot (they just plot the zero contour).
sage: f(x,y)
-x^3 + y^2 - x + 1
sage: implicit_plot(f(x,y)==0,(x,-pi,pi),(y,-pi,pi))
Graphics object consisting of 1 graphics primitive
Sometimes contour plots can be a little misleading (which makes for a great classroom discussion about the problems of
ignorantly relying on technology). Here we combine a density plot and contour plot to show even better what is happening
with the function.
sage: density_plot(f,(x,-2,2),(y,-2,2))+contour_plot(f,(x,-2,2),(y,-2,2),fill=False,
˓→labels=True,label_inline=True,cmap= jet )
It can be worth getting familiar with the various options for different plots, especially if you will be doing a lot of them in
a given worksheet or pedagogical situation.
Here are the options for contour plots.
• They are given as an “attribute” - no parentheses - of the contour_plot object.
• They are given as a dictionary (see the programming tutorial).
sage: contour_plot.options
{ aspect_ratio : 1,
axes : False,
colorbar : False,
contours : None,
fill : True,
frame : True,
labels : False,
legend_label : None,
linestyles : None,
linewidths : None,
plot_points : 100,
region : None}
Let’s change it so that all future contour plots don’t have the fill. That’s how some of us might use them in a class. We’ll
also check that the change happened.
sage: contour_plot.options["fill"]=False
sage: contour_plot.options
{ aspect_ratio : 1,
axes : False,
colorbar : False,
contours : None,
fill : False,
frame : True,
labels : False,
legend_label : None,
linestyles : None,
linewidths : None,
plot_points : 100,
region : None}
And it works!
sage: contour_plot(f,(x,-2,2),(y,-2,2))
Graphics object consisting of 1 graphics primitive
sage: contour_plot.defaults()
{ aspect_ratio : 1,
axes : False,
colorbar : False,
contours : None,
fill : True,
frame : True,
labels : False,
legend_label : None,
linestyles : None,
linewidths : None,
plot_points : 100,
region : None}
The syntax for vector fields is very similar to other multivariate constructions. Notice that the arrows are scaled appropri-
ately, and colored by length in the 3D case.
3d vector field plots are ideally viewed with 3d glasses (right-click on the plot and select “Style” and “Stereographic”)
We can plot functions of complex variables, where the magnitude is indicated by the brightness (black is zero magnitude)
and the argument is indicated by the hue (red is a positive real number).
These plot where an expression is true, and are useful for plotting inequalities.
Remember, what command would give full information about the syntax, options, and examples?
Sage includes a variety of built-in graphics objects. These are particularly useful for adding to one’s plot certain objects
which are difficult to describe with equations, but which are basic geometric objects nonetheless. In this section we will
try to demonstrate the syntax of some of the most useful of them; for most of them the contextual (remember, append ?)
help will give more details.
Points
sage: point((3,5))
Graphics object consisting of 1 graphics primitive
It doesn’t matter how multiple point are generated; they must go in as input via a list (square brackets). Here, we demon-
strate the hard (but naive) and easy (but a little more sophisticated) way to do this.
sage: f(x)=x^2
sage: points([(0,f(0)), (1,f(1)), (2,f(2)), (3,f(3)), (4,f(4))])
Graphics object consisting of 1 graphics primitive
Sage tries to tell how many dimensions you are working in automatically.
sage: f(x,y)=x^2-y^2
sage: points([(x,y,f(x,y)) for x in range(5) for y in range(5)])
Graphics3d Object
Lines
The syntax for lines is the same as that for points, but you get… well, you get connecting lines too!
sage: f(x)=x^2
sage: line([(x,f(x)) for x in range(5)])
Graphics object consisting of 1 graphics primitive
Balls
Sage has disks and spheres of various types available. Generally the center and radius are all that is needed, but other
options are possible.
sage: circle((0,1),1,aspect_ratio=1)
Graphics object consisting of 1 graphics primitive
There are also ellipses and various arcs; see the full plot documentation.
Arrows
Polygons
Polygons will try to complete themselves and fill in the interior; otherwise the syntax is fairly self-evident.
sage: polygon([[0,0],[1,1],[1,2]])
Graphics object consisting of 1 graphics primitive
Text
In 2d, one can typeset mathematics using the text command. This can be used to fine-tune certain types of labels.
Unfortunately, in 3D the text is just text.
We can save 2d plots to many different formats. Sage can determine the format based on the filename for the image.
sage: p=plot(x^2,(x,-1,1))
sage: p
Graphics object consisting of 1 graphics primitive
For testing purposes, we use the Sage standard temporary filename; however, you could use any string for a name that
you wanted, like "my_plot.png".
In the notebook, these are usually ready for downloading in little links by the cells.
SEVEN
Sometimes all one needs to start using Sage in a field is a little help. These “Quickstart” tutorials are designed to get you
up and running in one of these fields with a minimum of fuss and muss.
The assumed background in most of these is the first several tutorials in this set of documents. Similarly, keep in mind
that these documents are concise; the next step from each of them is really the Sage reference manual.
Finally, the last tutorial is a special one introducing the reader to creation of interactive material in Sage. It’s highly
recommended that you study the Programming tutorial before tackling this one.
Contents:
This Sage quickstart tutorial was developed for the MAA PREP Workshop “Sage: Using Open-Source Mathematics
Software with Undergraduates” (funding provided by NSF DUE 0817071). It is licensed under the Creative Commons
Attribution-ShareAlike 3.0 license (CC BY-SA).
As computers are discrete and finite, anything with a discrete, finite set of generators is natural to implement and explore.
Many common groups are pre-defined, usually as permutation groups: that is, explicitly described as subgroups of sym-
metric groups.
• Every group of order 15 or less is available as a permutation group.
• Sometimes they are available under special names, though.
sage: G = QuaternionGroup()
sage: G
Quaternion group of order 8 as a permutation group
sage: H = AlternatingGroup(5)
sage: H
Alternating group of order 5!/2 as a permutation group
sage: H.is_simple()
True
55
PREP Tutorials, Release 10.5
sage: D = DihedralGroup(8)
sage: D
Dihedral group of order 16 as a permutation group
In the previous cell we once again did a for loop over a set of objects rather than just a list of numbers. This can be very
powerful.
sage: D.stabilizer(3)
Subgroup generated by [(1,5)(2,4)(6,8)] of (Dihedral group of order 16 as a␣
˓→permutation group)
sage: len(D.normal_subgroups())
7
sage: for K in sorted(D.normal_subgroups()):
....: print(K)
Subgroup generated by [()] of (Dihedral group of order 16 as a permutation group)
...
Subgroup generated by [(1,2,3,4,5,6,7,8), (1,8)(2,7)(3,6)(4,5)] of (Dihedral group of␣
˓→order 16 as a permutation group)
sage: L = D.subgroup(["(1,3,5,7)(2,4,6,8)"])
sage: L.is_normal(D)
True
sage: Q=D.quotient(L)
sage: Q
Permutation Group with generators [(1,2)(3,4), (1,3)(2,4)]
sage: Q.is_isomorphic(KleinFourGroup())
True
There are some matrix groups as well, both finite and infinite.
sage: for a in S:
....: print(a)
[1 0]
[0 1]
...
[2 2]
[2 1]
sage: SS.list()
Traceback (most recent call last):
...
NotImplementedError: group must be finite
7.1.2 Rings
Sage has many pre-defined rings to experiment with. Here is how one would access /12 , for instance.
sage: twelve.is_field()
False
sage: twelve.is_integral_domain()
False
sage: quat.is_field()
False
sage: quat.is_commutative()
False
sage: quat.is_division_algebra()
True
sage: quat2.is_division_algebra()
True
sage: quat2.is_field()
False
Polynomial Rings
Now we will turn 𝑥 into the generator of a polynomial ring. The syntax is a little unusual, but you will see it often.
sage: R.is_integral_domain()
True
sage: (x^2+x+1).is_irreducible()
True
sage: F = GF(5)
sage: P.<y> = F[]
sage: I = P.ideal(y^3+2*y)
sage: I
Principal ideal (y^3 + 2*y) of Univariate Polynomial Ring in y over Finite Field of␣
˓→size 5
sage: Q = P.quotient(I)
sage: Q
Univariate Quotient Polynomial Ring in ybar over Finite Field of size 5 with modulus␣
˓→y^3 + 2*y
7.1.3 Fields
Sage has superb support for finite fields and extensions of the rationals.
Finite Fields
The generator satisfies a Conway polynomial, by default, or the polynomial can be specified.
sage: F.polynomial()
a^4 + 2*a^3 + 2
sage: F.list()
[0, a, a^2, a^3, a^3 + 1, a^3 + a + 1, a^3 + a^2 + a + 1, 2*a^3 + a^2 + a + 1, a^2 +␣
˓→a + 2, a^3 + a^2 + 2*a, 2*a^3 + 2*a^2 + 1, a^3 + a + 2, a^3 + a^2 + 2*a + 1, 2*a^3␣
˓→2 + 2*a, 2*a^2 + 2, 2*a^3 + 2*a, 2*a^3 + 2*a^2 + 2, a^3 + 2*a + 2, a^3 + 2*a^2 +␣
˓→ a^2 + a, a^3 + a^2, 2*a^3 + 1, 2*a^3 + a + 2, 2*a^3 + a^2 + 2*a + 2, 2*a^2 + 2*a +␣
˓→2, 2*a^3 + 2*a^2 + 2*a, a^3 + 2*a^2 + 2, 2*a + 1, 2*a^2 + a, 2*a^3 + a^2, 2, 2*a,␣
˓→2*a^2, 2*a^3, 2*a^3 + 2, 2*a^3 + 2*a + 2, 2*a^3 + 2*a^2 + 2*a + 2, a^3 + 2*a^2 +␣
˓→2*a + 2, 2*a^2 + 2*a + 1, 2*a^3 + 2*a^2 + a, a^3 + a^2 + 2, 2*a^3 + 2*a + 1, 2*a^3␣
˓→+ 2*a^2 + a + 2, a^3 + a^2 + 2*a + 2, 2*a^3 + 2*a^2 + 2*a + 1, a^3 + 2*a^2 + a + 2,␣
˓→a^2 + 2*a + 1, a^3 + 2*a^2 + a, a^2 + 1, a^3 + a, a^3 + a^2 + 1, 2*a^3 + a + 1, 2*a^
˓→3 + a^2 + a + 2, a^2 + 2*a + 2, a^3 + 2*a^2 + 2*a, 2*a^2 + 1, 2*a^3 + a, 2*a^3 + a^
˓→2 + 2, 2*a + 2, 2*a^2 + 2*a, 2*a^3 + 2*a^2, a^3 + 2, a^3 + 2*a + 1, a^3 + 2*a^2 + a␣
˓→+ 1, a^2 + a + 1, a^3 + a^2 + a, 2*a^3 + a^2 + 1, a + 2, a^2 + 2*a, a^3 + 2*a^2, 1]
𝐹 should be the splitting field of the polynomial 𝑥81 − 𝑥, so it is very good that we get no output from the following cell,
which combines a loop and a conditional statement.
sage: for a in F:
....: if not (a^81 - a == 0):
....: print("Oops!")
Most things you will need in an undergraduate algebra classroom are already in Sage.
sage: N = QQ[sqrt(2)]
sage: N
Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095?
sage: var( z )
z
sage: M.<a>=NumberField(z^2-2)
sage: M
Number Field in a with defining polynomial z^2 - 2
sage: M.degree()
2
sage: M.is_galois()
True
sage: M.is_isomorphic(N)
True
This Sage quickstart tutorial was developed for the MAA PREP Workshop “Sage: Using Open-Source Mathematics
Software with Undergraduates” (funding provided by NSF DUE 0817071). It is licensed under the Creative Commons
Attribution-ShareAlike 3.0 license (CC BY-SA).
Solving differential equations is a combination of exact and numerical methods, and hence a great place to explore with
the computer. We have already seen one example of this in the calculus tutorial, which is worth reviewing.
Forgetting about plotting for the moment, notice that there are three things one needs to solve a differential equation
symbolically:
• an abstract function y;
• a differential equation, which here we put in a separate line;
• the actual differential equation solve command (bold for the acronym desolve ).
sage: show(expand(h))
𝑐𝑒(−𝑥) + 2
Since we did not specify any initial conditions, Sage (from Maxima) puts in a parameter. If we want to put in an initial
condition, we use ics (for initial conditions). For example, we set ics=[0,3] to specify that when 𝑥 = 0, 𝑦 = 3.
And of course we have already noted that we can plot all this with a slope field.
Note
There are many other differential equation facilities in Sage. We can’t cover all the variants of this in a quickstart, but the
documentation is good for symbolic solvers.
sage: desolvers?
For instance, Maxima can do systems, as well as use Laplace transforms, and we include versions of these wrapped for
ease of use.
In all differential equation solving routines, it is important to pay attention to the syntax! In the following example, we
have placed the differential equation in the body of the command, and had to specify that f was the dependent variable
(dvar), as well as give initial conditions 𝑓 (0) = 1 and 𝑓 ′ (0) = 2, which gives the last list in the example.
sage: g(x)=x*e^x+e^x
sage: derivative(g,x,2)-2*derivative(g,x)+g
x |--> 0
It can be fun to compare this with the original, symbolic solution. We use the points command from the advanced
plotting tutorial.
sage: ode_solver?
We can even do power series solutions. In order to do this, we must first define a special power series ring , including the
precision.
sage: h = h.polynomial()
sage: plot(h,-2,5)+plot(2+e^-x,(x,-2,5),color= red ,linestyle= : ,thickness=3)
Graphics object consisting of 2 graphics primitives
This was just an introduction; there are a lot of resources for differential equations using Sage elsewhere, including a book
by David Joyner, who wrote much of the original code wrapping Maxima for Sage to do just this.
This Sage quickstart tutorial was developed for the MAA PREP Workshop “Sage: Using Open-Source Mathematics
Software with Undergraduates” (funding provided by NSF DUE 0817071). It is licensed under the Creative Commons
Attribution-ShareAlike 3.0 license (CC BY-SA).
As computers are discrete and finite, topics from discrete mathematics are natural to implement and use. We’ll start with
Graph Theory.
The pre-defined graphs object provides an abundance of examples. Just tab to see!
sage: graphs.[tab]
sage: G = graphs.HeawoodGraph()
sage: plot(G)
Graphics object consisting of 36 graphics primitives
Adjacency matrices, other graphs, and similar inputs are also recognized.
Graphs have “position” information for location of vertices. There are several different ways to compute a layout, or you
can compute your own. Pre-defined graphs often come with “nice” layouts.
sage: H.set_pos(H.layout_circular())
sage: plot(H)
Graphics object consisting of 18 graphics primitives
Vertices can be lots of things, for example the codewords of an error-correcting code.
Note
Here we have a matrix over the integers and a matrix of variables as vertices.
sage: a=matrix([[1,2],[3,4]])
sage: var( x y z w )
(x, y, z, w)
sage: b=matrix([[x,y],[z,w]])
sage: a.set_immutable()
sage: b.set_immutable()
sage: K=DiGraph({a:[b]})
sage: show(K, vertex_size=800)
sage: L=graphs.CycleGraph(5)
sage: for edge in L.edges(sort=True):
....: u = edge[0]
(continues on next page)
There are natural connections to other areas of mathematics. Here we compute the automorphism group and eigenvalues
of the skeleton of a cube.
sage: C = graphs.CubeGraph(3)
sage: plot(C)
Graphics object consisting of 21 graphics primitives
sage: Aut=C.automorphism_group()
sage: print("Order of automorphism group: {}".format(Aut.order()))
Order of automorphism group: 48
sage: print("Group: \n{}".format(Aut)) # random
Group:
Permutation Group with generators [( 010 , 100 )( 011 , 101 ), ( 001 , 010 )( 101 ,
˓→ 110 ), ( 000 , 001 )( 010 , 011 )( 100 , 101 )( 110 , 111 )]
sage: C.spectrum()
[3, 1, 1, 1, -1, -1, -1, -3]
There is a huge amount of LaTeX support for graphs. The following graphic shows an example of what can be done; this
is the Heawood graph.
Press ‘tab’ at the next command to see all the available options.
sage: sage.graphs.graph_latex.GraphLatex.set_option?
Discrete mathematics is a broad area, and Sage has excellent support for much of it. This is largely due to the
“sage-combinat” group. These developers previously developed for MuPad (as “mupad-combinat”) but switched over
to Sage shortly before MuPad was sold.
Simple Combinatorics
Sage can work with basic combinatorial structures like combinations and permutations.
Of course, we often want these for numbers, and these are present as well. Some are familiar:
sage: Permutations(5).cardinality()
120
sage: D = Derangements([1,1,2,2,3,4,5])
sage: D.list()[:5]
[[2, 2, 1, 1, 4, 5, 3], [2, 2, 1, 1, 5, 3, 4], [2, 2, 1, 3, 1, 5, 4], [2, 2, 1, 3, 4,␣
˓→5, 1], [2, 2, 1, 3, 5, 1, 4]]
sage: s = SymmetricFunctions(QQ).schur()
sage: a = s([2,1])
sage: a.expand(3)
x0^2*x1 + x0*x1^2 + x0^2*x2 + 2*x0*x1*x2 + x1^2*x2 + x0*x2^2 + x1*x2^2
sage: multinomial(24,3,5)
589024800
sage: falling_factorial(10,4)
5040
This is also briefly mentioned in the Number theory quickstart. Sage has a number of good pedagogical resources for
cryptography.
sage: # Two objects to make/use encryption scheme
sage: #
sage: from sage.crypto.block_cipher.sdes import SimplifiedDES
sage: sdes = SimplifiedDES()
sage: bin = BinaryStrings()
sage: #
sage: # Convert English to binary
sage: #
sage: P = bin.encoding("Encrypt this using S-DES!")
sage: print("Binary plaintext: {}\n".format(P))
sage: #
sage: # Choose a random key
sage: #
sage: K = sdes.list_to_string(sdes.random_key())
sage: print("Random key: {}\n".format(K))
sage: #
sage: # Encrypt with Simplified DES
sage: #
sage: C = sdes(P, K, algorithm="encrypt")
sage: print("Encrypted: {}\n".format(C))
sage: #
sage: # Decrypt for the round-trip
sage: #
sage: plaintxt = sdes(C, K, algorithm="decrypt")
sage: print("Decrypted: {}\n".format(plaintxt))
sage: #
sage: # Verify easily
(continues on next page)
Encrypted: ␣
˓→001000011000010100110001110001100100000110111010111110111000110111111011111101111100101010000100100
Decrypted: ␣
˓→010001010110111001100011011100100111100101110000011101000010000001110100011010000110100101110011001
Coding Theory
sage: C = LinearCode(G)
sage: C.is_self_dual()
False
sage: D = C.dual_code()
sage: D
[7, 3] linear code over GF(2)
sage: D.basis()
[
(1, 0, 1, 0, 1, 0, 1),
(0, 1, 1, 0, 0, 1, 1),
(0, 0, 0, 1, 1, 1, 1)
]
sage: D.permutation_automorphism_group()
Permutation Group with generators [(4,5)(6,7), (4,6)(5,7), (2,3)(6,7), (2,4)(3,5), (1,
˓→2)(5,6)]
This Sage quickstart tutorial was developed for the MAA PREP Workshop “Sage: Using Open-Source Mathematics
Software with Undergraduates” (funding provided by NSF DUE 0817071). It is licensed under the Creative Commons
Attribution-ShareAlike 3.0 license (CC BY-SA).
Linear algebra underpins a lot of Sage’s algorithms, so it is fast, robust and comprehensive. We’ve already seen some
basic linear algebra, including matrices, determinants, and the .rref() method for row-reduced echelon form in the
Programming Tutorial, so the content here continues from there to some extent.
We can make a matrix easily by passing a list of the rows. Don’t forget to use tab-completion to see routines that are
possible.
sage: A = matrix([[1,2,3],[4,5,6]]); A
[1 2 3]
[4 5 6]
But there are lots of other ways to make matrices. Each of these shows what is assumed with different input; can you
figure out how Sage interprets them before you read the documentation which the command matrix? provides?
It’s a good idea to get in the habit of telling Sage what ring to make the matrix over. Otherwise, Sage guesses based on
the elements, so you may not have a matrix over a field! Here, we tell Sage to make the ring over the rationals.
sage: B = matrix(QQ, 3, 2, [1,2,3,4,5,6]); B
[1 2]
[3 4]
[5 6]
Don’t forget that when viewing this in the notebook, you can click to the left of the matrix in order to cycle between
“wrapped”, “unwrapped” and “hidden” modes of output.
sage: print(D.str())
[0.000000000000000 1.00000000000000 2.00000000000000 3.00000000000000 4.
˓→00000000000000 5.00000000000000 6.00000000000000 7.00000000000000 8.
˓→00000000000000 9.00000000000000 10.0000000000000 11.0000000000000 12.
˓→0000000000000 13.0000000000000 14.0000000000000 15.0000000000000 16.
˓→0000000000000 17.0000000000000 18.0000000000000 19.0000000000000]
[ 20.0000000000000 21.0000000000000 22.0000000000000 23.0000000000000 24.
˓→0000000000000 25.0000000000000 26.0000000000000 27.0000000000000 28.
˓→0000000000000 29.0000000000000 30.0000000000000 31.0000000000000 32.
˓→0000000000000 33.0000000000000 34.0000000000000 35.0000000000000 36.
˓→0000000000000 37.0000000000000 38.0000000000000 39.0000000000000]
[ 40.0000000000000 41.0000000000000 42.0000000000000 43.0000000000000 44.
˓→0000000000000 45.0000000000000 46.0000000000000 47.0000000000000 48.
(continues on next page)
sage: column_matrix(QQ,[[1,2,3],[4,5,6],[7,8,9]])
[1 4 7]
[2 5 8]
[3 6 9]
sage: F1.augment(F2)
[0 1 1 2]
[1 0 3 4]
sage: F1.stack(F2)
[0 1]
[1 0]
[1 2]
[3 4]
sage: block_diagonal_matrix([F1,F2])
[0 1|0 0]
[1 0|0 0]
[---+---]
[0 0|1 2]
[0 0|3 4]
Vectors are rows or columns, whatever you please, and Sage interprets them as appropriate in multiplication contexts.
sage: F*col
(5, 23, 41)
sage: row*F
(14, 20)
Although our “vectors” (especially over rings other than fields) might be considered as elements of an appropriate free
module, they basically behave as vectors for our purposes.
Sage “prefers” rows to columns. For example, the kernel method for a matrix 𝐴 computes the left kernel – the vector
space of all vectors 𝑣 for which 𝑣 · 𝐴 = 0 – and prints out the vectors as the rows of a matrix.
sage: G.left_kernel()
Vector space of degree 2 and dimension 1 over Rational Field
Basis matrix:
[ 1 -1/2]
Since Sage knows the kernel is a vector space, you can compute things that make sense for a vector space.
sage: V=G.right_kernel()
sage: V
Vector space of degree 3 and dimension 2 over Rational Field
Basis matrix:
[ 1 0 -1/3]
[ 0 1 -2/3]
sage: V.dimension()
2
sage: V.coordinate_vector([1,4,-3])
(1, 4)
Here we get the basis matrix (note that the basis vectors are the rows of the matrix):
sage: V.basis_matrix()
[ 1 0 -1/3]
[ 0 1 -2/3]
sage: V.basis()
[
(1, 0, -1/3),
(0, 1, -2/3)
]
Note
7.4.4 Computations
According to the Numerical analysis quickstart, the question marks indicate that the actual number is inside the interval
found by incrementing and decrementing the last digit of the printed number. So 9.1? is a number between 9.0 and
9.2. Sage knows exactly what number this is (since it’s a root of a polynomial), but uses interval notation to print an
approximation for ease of use.
The eigenvectors_right command prints out a list of (eigenvalue, [list of eigenvectors],
algebraic multiplicity) tuples for each eigenvalue.
It may be more convenient to use the eigenmatrix_right command, which gives a diagonal matrix of eigenvalues
and a column matrix of eigenvectors.
sage: D,P=H.eigenmatrix_right()
sage: P*D-H*P
[0 0 0 0 0]
[0 0 0 0 0]
[0 0 0 0 0]
(continues on next page)
We can easily solve linear equations using the backslash, like in Matlab.
For lots more (concise) information, see the Sage Linear Algebra Quick Reference.
This Sage quickstart tutorial was developed for the MAA PREP Workshop “Sage: Using Open-Source Mathematics
Software with Undergraduates” (funding provided by NSF DUE 0817071). It is licensed under the Creative Commons
Attribution-ShareAlike 3.0 license (CC BY-SA).
Because much related material was covered in the calculus tutorial, this quickstart is designed to:
• Give concrete examples of some things not covered there, without huge amounts of commentary, and
• Remind the reader of a few of the things in that tutorial.
In Sage, vectors are primarily linear algebra objects, but they are slowly becoming simultaneously analytic continuous
functions.
sage: v.cross_product(w)
(28.7800000000000, 1.58000000000000, -8.71000000000000)
𝑦+4
Intersect 𝑥 − 2𝑦 − 7𝑧 = 6 with 𝑥−3
2 = −3 = 1 .
𝑧−1
One way to plot the equation of a line in three dimensions is with
parametric_plot3d.
Vector-Valued Functions
We can make vector-valued functions and do the usual analysis with them.
sage: var( t )
t
sage: r=vector((2*t-4, t^2, (1/4)*t^3))
sage: r
(2*t - 4, t^2, 1/4*t^3)
sage: r(t=5)
(6, 25, 125/4)
Currently, this expression does not function as a function, so we need to substitute explicitly.
sage: velocity(t=1)
(2, 2, 3/4)
sage: T=velocity/velocity.norm()
sage: T(t=1).n()
(0.683486126173409, 0.683486126173409, 0.256307297315028)
Here we compute the arclength between 𝑡 = 0 and 𝑡 = 1 by integrating the normalized derivative. As pointed out in the
calculus tutorial, the syntax for numerical_integral is slightly nonstandard – we just put in the endpoints, not the
variable.
sage: x,y,z=var( x y z )
sage: plot_vector_field3d((x*cos(z),-y*cos(z),sin(z)), (x,0,pi), (y,0,pi), (z,0,pi),
˓→colors=[ red , green , blue ])
Graphics3d Object
If we know a little vector calculus, we can also do line integrals. Here, based on an example by Ben Woodruff of
BYU-Idaho, we compute a number of quantities in a physical three-dimensional setting.
Try to read through the entire code. We make an auxiliary function that will calculate (integrand) 𝑑𝑡. We’ll use our
∫︀
sage: density(x,y,z)=x^2+z
sage: r=vector([3*cos(t), 3*sin(t),4*t])
sage: tstart=0
sage: tend=2*pi
sage: t = var( t )
sage: t_range=(t,tstart,tend)
sage: def line_integral(integrand):
....: return RR(numerical_integral((integrand).subs(x=r[0], y=r[1],z=r[2]),␣
˓→tstart, tend)[0])
Finally, we can display everything in a nice table. Recall that we use the r"stuff" syntax to indicate “raw” strings so
that backslashes from LaTeX won’t cause trouble.
sage: html.table([
....: [r"Density $\delta(x,y)$", density],
....: [r"Curve $\vec r(t)$",r],
....: [r"$t$ range", t_range],
....: [r"$\vec r (t)$", r_prime],
....: [r"$ds$, a little bit of arclength", ds],
....: [r"$s$ - arclength", s],
....: [r"Centroid (constant density) $\left(\frac{1}{m}\int x\,ds,\frac{1}{m}\int␣
˓→y\,ds, \frac{1}{m}\int z\,ds\right)$", (centroid_x,centroid_y,centroid_z)],
....: ])
Partial Differentiation
The following exercise is from Hass, Weir, and Thomas, University Calculus, Exercise 12.7.35. This function has a local
minimum at (4, −2).
Quiz: Why did we not need to declare the variables in this case?
sage: f.gradient()
(x, y) |--> (2*x + y - 6, x + 2*y)
sage: H = f.hessian()
sage: H(x,y)
[2 1]
[1 2]
And of course if the Hessian has positive determinant and 𝑓𝑥𝑥 is positive, we have a local minimum.
sage: html("$f_{xx}=%s$"%H(4,-2)[0,0])
sage: html("$D=%s$"%H(4,-2).det())
Notice how we were able to use many things we’ve done up to now to solve this.
• Matrices
• Symbolic functions
• Solving
• Differential calculus
• Special formatting commands
• And, below, plotting!
sage: f(x,y)=x^2*y
sage: # integrate in the order dy dx
sage: f(x,y).integrate(y,0,4*x).integrate(x,0,3)
1944/5
sage: # another way to integrate, and in the opposite order too
sage: integrate( integrate(f(x,y), (x, y/4, 3)), (y, 0, 12) )
1944/5
sage: var( u v )
(u, v)
sage: surface = plot3d(f(x,y), (x, 0, 3.2), (y, 0, 12.3), color = blue , opacity=0.3)
sage: domain = parametric_plot3d([3*u, 4*(3*u)*v,0], (u, 0, 1), (v, 0,1), color =
˓→ green , opacity = 0.75)
sage: image = parametric_plot3d([3*u, 4*(3*u)*v, f(3*u, 12*u*v)], (u, 0, 1), (v, 0,1),
˓→ color = green , opacity = 1.00)
sage: surface+domain+image
Graphics3d Object
This Sage quickstart tutorial was developed for the MAA PREP Workshop “Sage: Using Open-Source Mathematics
Software with Undergraduates” (funding provided by NSF DUE 0817071). It is licensed under the Creative Commons
Attribution-ShareAlike 3.0 license (CC BY-SA).
Sage includes many tools for numerical analysis investigations.
The place to begin is the default decimal number types in Sage.
sage: ring=RealField(3)
To print the actual number (without rounding off the last few imprecise digits to only display correct digits), call the
.str() method:
sage: ring=RealField(20)
sage: print(ring( 1 ).nextabove().str())
1.0000019
sage: print(ring( 1 ).nextbelow().str())
0.99999905
sage: ring(1/9).str()
0.11111116
sage: ringup(1/9).str()
0.13
sage: ringdown(1/9).str()
0.10
sage: ring(1/9).str(base=2)
0.00011100011100011100100
sage: ring(1/9).exact_rational()
233017/2097152
sage: n(233017/2097152)
0.111111164093018
sage: x=13.28125
sage: x.str(base=2)
1101.0100100000000000000000000000000000000000000000000
sage: xbin.n()
13.2812500000000
To check, let’s ask Sage what x is as an exact fraction (no rounding involved).
sage: x.exact_rational()
425/32
Now let’s convert x to the IEEE 754 binary format that is commonly used in computers. For IEEE 754, the first step in
getting the binary format is to normalize the number, or express the number as a number between 1 and 2 multiplied by
a power of 2. For our x above, we multiply by 2−3 to get a number between 1 and 2.
sage: (x*2^(-3)).str(base=2)
1.1010100100000000000000000000000000000000000000000000
The fraction part of the normalized number is called the mantissa (or significand ).
sage: f=(x*2^(-3)).frac() # .frac() gets the fraction part, the part after the decimal
sage: mantissa=f.str(base=2)
sage: mantissa
0.10101001000000000000000000000000000000000000000000000
Since we multiplied by 2−3 to normalize the number, we need to store this information. We add 1023 in order to not
have to worry about storing negative numbers. In the below, c will be our exponent.
sage: c=(3+1023).str(base=2)
sage: c
10000000010
sage: len(c)
11
Evaluating mantissa[2:54] will give the first 52 binary digits after the decimal point of the mantissa. Note that we
don’t need to store the leading 1 before the decimal point because it will always be there from the way we normalized
things. This lets us get 53-bit precision using only 52 bits of storage.
sage: len(mantissa[2:54])
52
Since the original number was positive, our sign bit is zero.
sage: sign= 0
sage: sign+ +c+ +mantissa[2:54] # the [2:] just chops off the 0. , since we just␣
˓→need to store the digits after the decimal point
0 10000000010 1010100100000000000000000000000000000000000000000000
Here we convert back to our original number from the floating point representation that we constructed.
sage: x
13.2812500000000
So they agree!
Sage uses a cutting-edge numerical library, MPFR, to carry out precise floating point arithmetic using any precision a
user specifies. MPFR has a slightly different convention for normalization. In MPFR, we normalize by multiplying by
an appropriate power of 2 to make the mantissa an integer, instead of a binary fraction. This allows us to use big integer
libraries and sophisticated techniques to carry out calculations at an arbitrary precision.
sage: x.sign_mantissa_exponent()
(1, 7476679068876800, -49)
sage: 7476679068876800*2^(-49)
425/32
Note that the mantissa here has the same zero/nonzero bits as the mantissa above (before we chopped off the leading 1
above).
sage: 7476679068876800.str(base=2)
11010100100000000000000000000000000000000000000000000
Sage also lets you compute using intervals to keep track of error bounds. These basically use the round up and round
down features shown above.
sage: ring=RealIntervalField(10)
sage: a=ring(1/9)
sage: a
0.112?
The question mark notation means that the number is contained in the interval found by incrementing and decrementing
the last digit of the number. See the documentation for real interval fields for details. In the above case, Sage is saying
that 1/9 is somewhere between 0.111 and 0.113. Below, we see that 1/a is somewhere between 8.9 and 9.1.
sage: 1/a
9.0?
We can get a more precise estimate of the interval if we explicitly print out the interval.
Scipy (included in Sage) has a lot of numerical algorithms. See the Scipy docs.
Mpmath is also included in Sage, and contains a huge amount of numerical stuff. See the mpmath codebase.
The Decimal python module has also been useful for textbook exercises which involved rounding in base 10.
Sometimes plotting involves some rather bad rounding errors because plotting calculations are done with
machine-precision floating point numbers.
sage: f(x)=x^2*(sqrt(x^4+16)-x^2)
sage: plot(f,(x,0,2e4))
Graphics object consisting of 1 graphics primitive
We can instead make a function that specifically evaluates all intermediate steps to 100 bits of precision using the
fast_callable system.
This Sage quickstart tutorial was developed for the MAA PREP Workshop “Sage: Using Open-Source Mathematics
Software with Undergraduates” (funding provided by NSF DUE 0817071). It is licensed under the Creative Commons
Attribution-ShareAlike 3.0 license (CC BY-SA).
Since Sage began life as a project in algebraic and analytic number theory (and this continues to be a big emphasis), it is
no surprise that functionality in this area is extremely comprehensive. And it’s also just enjoyable to explore elementary
number theory by computer.
Conveniently, the ring of integers modulo 𝑛 is always available in Sage, so we can do modular arithmetic very easily. For
instance, we can create a number in /11 . The type command tells us that 𝑎 is not a regular integer.
Note that we verified Fermat’s “Little Theorem” in the previous cell, for the prime 𝑝 = 11 and input 𝑎 = 2.
Recalling the basic programming construct called a loop , we can verify this for all 𝑎 in the integers modulo 𝑝. Here,
instead of looping over an explicit list like [0,1,2,3,...8,9,10], we loop over a Sage object.
Notice that Integers(11) gave us an algebraic object which is the ring of integers modulo the prime ideal generated
by the element 11.
This works for much bigger numbers too, of course.
sage: p=random_prime(10^200,proof=True)
sage: Zp=Integers(p) # Here we give ourselves shorthand for the modular integers
sage: a=Zp(2) # Here we ask for 2 as an element of that ring
sage: p; a; a^(p-1); a^(10^400)
83127880126958116183078749835647757239842289608629126718968330784897646881689610705533628095938824110
2
1
21428062940380156097538386722913390559445420264965409656232714664156136144920173818936415427844953758
Whenever you encounter a new object, you should try tab-completion to see what you can do to it. Try it here, and pick
one (hopefully one that won’t be too long!).
sage: Zp.
sage: Zp.zeta?
And we use it to find the fifth roots of unity in this field. We use the list comprehension (set-builder) notation from the
programming tutorial this time.
˓→698397838955722862975688344850250735578853643480710617154654770618734003597949893674234076839712993
˓→␣
˓→574074442191990614988012986723235901632385922015745724828366190256768695370076093153868008522043375
˓→␣
˓→419366418775396766525315677232493679171086389871318795216062437418144020953437245408446072129992970
Luckily, it checked out. (If you didn’t get any, then your random prime ended up being one for which there are no fifth
roots of unity – try doing the sequence over again!)
Similarly to the situation in linear algebra, there is much more we can access at the elementary level, such as
• primitive roots,
• ways to write a number as a sum of squares,
• Legendre symbols,
• modular solving of basic equations,
• etc.
A good way to use Sage in this context is to allow students to experiment with pencil and paper first, then use Sage to see
whether patterns they discover hold true before attempting to prove them.
sage: p = 13
sage: primitive_root(p); two_squares(p); is_prime(p)
2
(2, 3)
True
This makes it easy to construct elementary cryptographic examples as well. Here is a standard example of a Diffie-Hellman
key exchange, for instance. If we didn’t do the second line, exponentiation would be impractical.
The final line of the cell first requests Alice and Bob’s (possibly) public information, and then verifies that the private keys
they get are the same.
It is hard to resist including just one interact. How many theorems do you see here?
sage: @interact
sage: def power_table_plot(p=(7,prime_range(50))):
....: P=matrix_plot(matrix(p-1,[mod(a,p)^b for a in range(1,p) for b in␣
˓→srange(p)]),cmap= jet )
....: show(P)
This is a graphic giving the various powers of integers modulo 𝑝 as colors, not numbers. The columns are the powers, so
the first column is the zeroth power (always 1) and the second column gives the colors for the numbers modulo the given
prime (first power).
One more very useful object is the prime counting function 𝜋(𝑥). This comes with its own custom plotting.
A very nice aspect of Sage is combining several aspects of mathematics together. It can be very eye-opening to students
to see analytic aspects of number theory early on. (Note that we have to reassign 𝑥 to a variable, since above it was a
cryptographic key!)
sage: var( x )
x
sage: plot(prime_pi,2,10^6,thickness=2)+plot(Li,2,10^6,color= red )+plot(x/ln(x),2,10^
˓→6,color= green )
For those who are interested, more advanced number-theoretic objects are easy to come by; we end with a brief sampler
of these.
√ √
In the first example, 𝐾 is the field extension Q( −14), where the symbol a plays the role of −14; we discover several
basic facts about 𝐾 in the next several cells.
Various zeta functions are also available; here is a complex plot of the Riemann zeta.
7.7.4 Cryptography
Sage supports various more advanced cryptographic procedures as well as some basic pedagogical ones natively. This
example is adapted from the documentation.
This Sage quickstart tutorial was developed for the MAA PREP Workshop “Sage: Using Open-Source Mathematics
Software with Undergraduates” (funding provided by NSF DUE 0817071). It is licensed under the Creative Commons
Attribution-ShareAlike 3.0 license (CC BY-SA).
Basic statistical functions are best to get from numpy and scipy.stats.
NumPy provides, for example, functions to compute the arithmetic mean and the standard deviation:
SciPy offers many more functions, for example a function to compute the harmonic mean:
We do not recommend to use Python’s built in statistics module with Sage. It has a known incompatibility with
number types defined in Sage, see Issue #28234.
7.8.2 Distributions
Let’s generate a random sample from a given type of continuous distribution using native Python random generators.
• We use the simplest method of generating random elements from a log normal distribution with (normal) mean 2
and 𝜎 = 3.
• Notice that there is really no way around making some kind of loop.
˓→9880239483346, 16.41063858663054]
We can check whether the mean of the log of the data is close to 2.
Here is an example using the Gnu scientific library under the hood.
• Let dist be the variable assigned to a continuous Gaussian/normal distribution with standard deviation of 3.
• Then we use the .get_random_element() method ten times, adding 2 each time so that the mean is equal
to 2.
For now, it’s a little annoying to get histograms of such things directly. Here, we get a larger sampling of this distribution
and plot a histogram with 10 bins.
The R project is a leading software package for statistical analysis with widespread use in industry and academics.
There are several ways to access R; they are based on the rpy2 package.
• One of the easiest is to just put r() around things you want to make into statistical objects, and then …
• Use R commands via r.method() to pass them on to Sage for further processing.
The following example of the Kruskal-Wallis test comes directly from the examples in r.kruskal_test? in the
notebook.
sage: %r #␣
˓→optional - rpy2
Coefficients:
(Intercept) x
210.0485 -0.7977
null device
1
To get a whole worksheet to evaluate in R (and be able to ignore the %), you could also drop down the r option in the
menu close to the top which currently has sage in it.
This Sage quickstart tutorial was developed for the MAA PREP Workshop “Sage: Using Open-Source Mathematics
Software with Undergraduates” (funding provided by NSF DUE 0817071).
Invaluable resources are the Sage wiki http://wiki.sagemath.org/interact (type “sage interact” into Google), UTMOST
Sage Cell Repository (a collection of contributed interacts).
How would one create an interactive cell? First, let’s focus on a new thing to do! Perhaps we just want a graph plotter
that has some options.
So let’s start by getting the commands for what you want the output to look like. Here we just want a simple plot.
sage: plot(x^2,(x,-3,3))
Graphics object consisting of 1 graphics primitive
Then abstract out the parts you want to change. We’ll be letting the user change the function, so let’s make that a variable
f.
sage: f=x^3
sage: plot(f,(x,-3,3))
Graphics object consisting of 1 graphics primitive
This was important because it allowed you to step back and think about what you would really be doing.
Now for the technical part. We make this a def function - see the programming tutorial.
sage: myplot()
sage: myplot(x^3)
So far, we’ve only defined a new function, so this was review. To make a “control” to allow the user to interactively enter
the function, we just preface the function with @interact.
sage: @interact
sage: def myplot(f=x^2):
....: show(plot(f,(x,-3,3)))
Note
Technically what @interact does is wrap the function, so the above is equivalent to:
def myplot(..): ...
myplot=interact(myplot)
Note that we can still call our function, even when we’ve used @interact. This is often useful in debugging it.
sage: myplot(x^4)
We can go ahead and replace other parts of the expression with variables. Note that _ is the function name now. That is
a just convention for throw-away names that we don’t care about.
sage: @interact
sage: def _(f=x^2, a=-3, b=3):
....: show(plot(f,(x,a,b)))
If we pass ( label , default_value) in for a control, then the control gets the label when printed. Here, we’ve
put in some text for all three of them. Remember that the text must be in quotes! Otherwise Sage will think that you are
referring (for example) to some variable called “lower”, which it will think you forgot to define.
sage: @interact
sage: def _(f=( $f$ , x^2), a=( lower , -3), b=( upper , 3)):
....: show(plot(f,(x,a,b)))
We can specify the type of control explicitly, along with options. See below for more detail on the possibilities.
sage: @interact
sage: def _(f=input_box(x^2, width=20, label="$f$")):
....: show(plot(f,(x,-3,3)))
sage: @interact
sage: def _(f=input_box(x^2,width=20),
....: color=color_selector(widget= colorpicker , label=""),
....: axes=True,
....: fill=True,
....: zoom=range_slider(-3,3,default=(-3,3))):
....: show(plot(f,(x,zoom[0], zoom[1]), color=color, axes=axes,fill=fill))
There are many potential types of widgets one might want to use for interactive control. Sage has all of the following:
• boxes
• sliders
• range sliders
• checkboxes
• selectors (dropdown lists or buttons)
• grid of boxes
• color selectors
• plain text
We illustrate some more of these below.
sage: @interact
sage: def _(frame=checkbox(True, label= Use frame )):
....: show(plot(sin(x), (x,-5,5)), frame=frame)
By default, ranges are sliders that divide the range into 50 steps.
sage: @interact
sage: def _(n=(1,20)):
....: print(factorial(n))
You can set the step size to get, for example, just integer values.
sage: @interact
sage: def _(n=slider(1,20, step_size=1)):
....: print(factorial(n))
....: print(v.norm())
As a final problem, what happens when the controls get so complicated that it would counterproductive to see the interact
update for each of the changes one wants to make? Think changing the endpoints and order of integration for a triple
integral, for instance, or the example below where a whole matrix might be changed.
In this situation, where we don’t want any updates until we specifically say so, we can use the auto_update=False
option. This will create a button to enable the user to update as soon as he or she is ready.
sage: @interact
sage: def _(m=( matrix , identity_matrix(2)), auto_update=False):
....: print(m.eigenvalues())