Navigation

This Sage document is one of the 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 tutorial will cover the following topics (and various others
throughout):

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,

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

Then we do the row-reduced echelon form.

sage: A.rref()[1 0][0 1]

It is very important to keep in the parentheses.

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.

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]

There are lots of advanced things one can do with lists.

sage: my_list[0:2][2, 'Grover']

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.

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:

\[\{n^2\mid n\in\ZZ, 3 \leq n \leq 12\}\]

Who hasn’t written something like this at some point in a course?

This is a natural for the list comprehension, and can be very powerful
when used in Sage.

sage: [n^2fornin[3..12]][9, 16, 25, 36, 49, 64, 81, 100, 121, 144]

That’s it. This sort of turns the loop around.

The notation is easiest if you think of it mathematically; “The set of
\(n^2\), for (all) \(n\) in the range between 3 and 13.”

Some of you may be familiar with a way to take such data and put it in
tabular form from other programs. The table command does this
for us:

sage: table([(i,det(A^i))foriin[0..4]]) 0 1 1 -2 2 4 3 -8 4 16

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 \(A^2-A\) 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.

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: i4

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^2I-1

sage: type(e)<type 'sage.symbolic.constants_c.E'>

sage: type(pi)<type '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.

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: foriinrange(5):# all integers from 0 to 4, remember....: ifB^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).