Professional Documents
Culture Documents
SAGE For Undergraduates.
SAGE For Undergraduates.
(online version)
Gregory V. Bard
Dept. of Mathematics, Statistics, and Computer Science,
University of WisconsinStout, Menomonie, Wi, 54751
E-mail address: bardg@uwstout.edu
2010 Mathematics Subject Classification. Primary: 15-04, 34-04, 65-04,
90-04, 97M10. Secondary: 11-04, 12-04, 28-04, 40-04, 68U05.
With warmth I dedicate this book to my husband, Patrick, who has
supported me throughout my career, in good years and in bad years, and
who has spent many evenings alone because I was working on this book.
Contents
There is no need to read this entire document, just as you would never
read the dictionary cover to cover. This book is ideal for self-study, but if
you are assigned this book as part of a class, then your professor will tell
you which section numbers correspond with what you need to be reading.
For other readers, who reading independently of a specific class, I have
the following suggestions:
Chapter 1 contains the basicswhat you really need to know. Most
of the common tasks in Sage were carefully designed to be as intu-
itive as possible, with notation as close as possible to how mathe-
matics is done on the whiteboard or with a pencil. I recommend
that you never try to read more than 3 entire sections in one day.
Otherwise there is too much for your brain to absorb while still
keeping the experience fun and new. However, 12 sections per
day should be easily digestible.
Note: Personally, I recommend just reading Chapter 1, and then start
playing around on your own. The best way to learn a new bit of
xv
xvi PREFACEHOW TO USE THIS BOOK
xix
xx ACKNOWLEDGEMENTS
lines. That is an example of how software can evolve. You can read about
the original algorithm in Chapter 9 of Algebraic Cryptanalysis.
I would also like thank Robert Beezer and Robert Miller for giving me
encouragement in using Sage in my teaching and research, respectively. In
particular, Robert Beezers outstanding (and free) eBook A First Course in
Linear Algebra was an inspiration for me while writing this book.
The Sage Cell Server has made Sage accessible to a much wider audience
than has ever before been dreamed possible. Even for those experienced
with Sage, the user experience is now vastly improved. This important and
difficult work has been done by Jason Grout, Ira Hanson, Steven Johnson,
Alex Kramer, and William Stein. Originally, Sage was suitable for graduate
students, faculty, and perhaps senior math majors. Then the Sage Notebook
Server came, bringing Sage to the mid-career undergraduate. Now, thanks
to the Sage Cell Server, it is now appropriate to use Sage even in Precalculus
classes, if desired.
The American Mathematics Society was most flexible with me on the
matters of deadlines as well as the many images in this textbook. Producing
a book requires a surprisingly large number of steps, and I am grateful for
the support of Ina Mette, the acquisitions editor, and Marcia Almeida, her
assistant. I am particularly grateful for Ina Mettes energetic and enthusi-
astic encouragement that I turn what was once a small guide into a larger
(published) book. This project would not exist without her encouragement.
I would like to thank Andrew Novocin for teaching me how to include
*.png files in LaTeX documents, which saved me the time of manually
converting the file formats of the armada of screen captures that fill this
book. I might have otherwise abandoned this entire book project.
No author can proofread his or her own work eectively, but that is
particularly the case for me. I am very grateful for the assistance of the
proofreaders Joseph Robert Bertino, Joseph Loeer, and Thomas Suiter,
who have each made suggestions and corrections on portions of this doc-
ument. Of particular merit, Thomas Suiter made the index, and Joseph
Bertino has nobly borne (without complaint) an enormous workload from
me through the last few yearsboth from this book and other projects. Of
course, any errors that remain are my responsibility.
My first job after getting my PhD from the University of Maryland was
at Fordham University, in The Bronx, NY, where I was appointed to one of
the four-year Peter M. Curran Visiting Assistant Professorships. I made
some progress on this project during my time at Fordham, after return-
ing from my summer in China. I received encouragement and suggestions
from Shaun Ault, Melkana Brakalova, Armand Brumer, Michael Burr, Bill
Campbell, Janusz Golec, Maryam Hastings, William Hastings, Nick Kintos,
Robert Lewis, Damian Lyons, Ian Morrison, Leonard Nissim, Cris Poor,
Benjamin Shemmer, Shapoor Vali, and Kris Wol. Fred Marottos book
Introduction to Mathematical Modeling Using Discrete Dynamical Systems,
published by Cengage in 2005, was also an inspiration for this work, though
ACKNOWLEDGEMENTS xxi
I did not have the opportunity to discuss our areas of common interest very
often. Jack Kamis, Mila Martynovsky and Michael Misha Zigelbaum pro-
vided me with valuable and practical teaching advice.
In particular, Shapoor Vali and I wrote our books at roughly the same
time, so we endured the struggle of writing book chapters, proofreading
drafts, and drawing up book-proposals simultaneously. We have both crossed
a great desert, not without pain and suering, and now we can both enjoy
the oasis at the other side.
Many Fordham undergraduates gave me a great deal of tips, corrections,
opportunities for improvement, and ideas. At the risk of accidentally ex-
cluding someone, I wish to mention the following Fordham students: James
Compagnoni, Gray Crenshaw, Dan DiPasquale, Patrick Fox, Alex Golec,
Simon Kaluza, Kyle Kloster, Peter Muller, Luigi Patruno, Seena Vali, and
Sean Woodward. Much encouragement was also given by Ed Casimiro, for
which I am grateful.
After the four-year position at Fordham had elapsed, I had the great luck
to be hired at the University of WisconsinStout, the polytechnic of the
University of Wisconsin system. This was a great boon for me as I received
my undergraduate degree in Computer & Systems Engineering from Rens-
selaer Polytechnic Institute in 1999, and similarly my father received his
undergraduate degree in Mechanical Engineering from ETH in Z urich (the
polytechnic of Switzerland) back in 1951. Accordingly returning to the at-
mosphere of a polytechnic was somewhat like coming home. While the three
institutions are far from being identical triplets, the noble goal of prepar-
ing hard-working students to become engineers, scientists, and managers, or
members of other lucrative technical professions, creates an attitude of focus
on the pragmatic, on hard work, and on exactitude. This polytechnic atti-
tude is reflected across the spectrum of academic rank, from the Chancellor
to the freshmen. It breeds respect for mathematics in general, and calculus
in particular. At UW Stout, mathematics is seen as a bridge to important
career-related coursework, and not as a barrier to graduation, as it was often
viewed at Fordham, by both students and high-ranking administrators.
The vast, vast majority of this book was written while working for
UW Stout. Both Dean Jeery Anderson and Dean Charles Bomar pro-
vided administrative, financial, and emotional support for this project. The
degree of cooperation in our Department of Mathematics, Statistics, and
Computer Science is extremely rare and heartwarming. Unless I am very
much mistaken, every last member of the department has contributed to this
book via a suggestion, correction, comment, filling in for me in class when
I was away at a conference, or by giving encouragement. Teaching 24 cred-
its per year in a climate thoroughly unfriendly1 to human habitation, while
1This is not an exaggeration. Two examples will have to suffice. On the first day
of classes in 2014, namely January 28th, as I was leaving the house to go to campus,
weather.com gave a temperature of 22 F on the thermometer, and 41 F with the
xxii ACKNOWLEDGEMENTS
windchill. For my metric readers, that is 29.4 C on the thermometer, and 40.6 C with
the windchill. On May 2nd and May 3rd, 2013, we had 17 inches of snow (thats 43.2 cm).
ACKNOWLEDGEMENTS xxiii
The funding for Sage comes in large part from the National Science Foun-
dation, and in particular the divisions listed below. The Sage community is
grateful for the support of the National Science Foundation grants:
DMS-0545904, Division of Mathematical Sciences, CAREER: Co-
homological Methods in Algebraic Geometry and Number Theory,
DMS-0555776, Division of Mathematical Sciences, Explicit Ap-
proaches to Modular Forms and Modular Abelian Varieties,
DMS-0713225, Division of Mathematical Sciences, SAGE: Soft-
ware for Algebra and Geometry Experimentation,
DMS-0757627, Division of Mathematical Sciences, FRG: Lfunc-
tions and Modular Forms,
DMS-0821725, Division of Mathematical Sciences, SCREMS: The
Computational Frontiers of Number Theory, Representation The-
ory, and Mathematical Physics,
DMS-0838212, Division of Mathematical Sciences,
EMSW21RTG: Research Training Group on Inverse Problems
and Partial Dierential Equations,
DMS-1015114, Division of Mathematical Sciences, Sage: Unifying
Mathematical Software for Scientists, Engineers, and Mathemati-
cians,
DUE-1022574, Division of Undergraduate Education, Collabora-
tive Research: UTMOST: Undergraduate Teaching in Mathematics
with Open Software and Textbooks,
ACI-1147463, Division of Advanced CyberInfrastructure, Collabo-
rative Research: SI2-SSE: Sage-Combinat: Developing and Sharing
Open Source Software for Algebraic Combinatorics,
as well as funding from Microsoft, Sun Microsystems, Enthought Inc., and
Google.
As I mentioned earlier, the Sage community is enormous, with hundreds
of developers in many countries of several continents. Despite the above
mentioned financial support, almost all of the work is performed on an
entirely voluntary and unpaid basis. For the sacrifice of free time on the part
of so many people, the entire Sage community is grateful in the extreme.
Chapter 1
Welcome to Sage!
Mathematics is something that we do, not something that we watch. There-
fore, the best way to learn any branch of mathematics is to actually get
started and give things a try. The same is true for learning Sage! Just con-
nect to the Sage Cell Server and dive right on in, trying the examples of
the next few pages.
https://sagecell.sagemath.org/
and click evaluate. You will learn that the answer is 15454.2080000000,
or $ 15,454.21 after rounding to the nearest penny. By the way, instead of
clicking evaluate, you can just press shift-enter on the keyboard, and it
will do the same thing.
Warning: It is very important not to enter a comma in large numbers
when using Sage. You have to type 11000 and not 11,000
For those who dont like the caret, you can use two asterisks in a row.
11000*(1+0.12)**3
which is actually a throw-back to the historical programming language
FORTRAN which was most popular1 during the 1970s and 1980s.
What if you make a mistake? Lets say that I really meant to say $ 13,000
and not $ 11,000. Click on the mistake, and correct it using the keyboard,
and change the 11 into 13. Now click evaluate again, and all is well.
Grouping Symbols:
When there are multiple sets of parentheses in a formula, sometimes math-
ematicians use brackets as a type of super parentheses. As it turns out,
Sage needs the brackets for other things, like lists, so you have to always use
parentheses for grouping inside of formulas.
For example, lets say you need to evaluate
1 (1 + 0.05) 30
550
0.05
So you should not type
550 [ 1 - (1+0.05)^(-30) ]/0.05
but rather
550 ( 1 - (1+0.05)^(-30) )/0.05
where the brackets have become parentheses.
Some very old math books use braces { and } as a sort of auxiliary also
to the parentheses and brackets. These too, if they are for grouping in a
formula, must become parentheses. As it turns out, Sage, as well as modern
mathematical books, use the braces { and } to denote sets.
By the way, the above formula was not artificial. It is the value of a loan
at 5% compounded annually for 30 years, with an annual payment of $ 550.
The formula is called the present value of an annuity.
1An irrelevant historical aside: Because rewriting software is a painful and time-
consuming process, many important pieces of scientific software remained written in
FORTRAN until a few years ago, and likewise the same is true of business software in COBOL.
Each new programming language incorporates features of the previous generation of lan-
guages, to make it easier to learn, and accordingly one sees some truly ancient seeds of
dead languages once in a while.
1.2. USING SAGE WITH COMMON FUNCTIONS 3
Square Roots:
The standard high school functions are also built-in. For example, type
sqrt(144)
then click evaluate and youll learn that the answer is 12. From now
on, Im not going to say click evaluate, because repeating that might get
tiresome; Ill assume that you know you have to do that. Since Sage likes
exact answers, try
sqrt(8)
and get 2*sqrt(2) as your answer. If you really need a decimal, try instead
N( sqrt(8) )
and obtain
2.82842712475.
which is a decimal approximation.
The N() function, which can also be written n(), will convert what is
inside the parentheses to a real number, if possible. Usually that is a decimal
expansion, thus unless what is inside the parentheses is an integer2 then it
will be, necessarily, an approximation. Sage will assume that all decimals
are mere approximations, so for example
2To be mathematically correct, I should say an integer or a fraction with denominator
writable as a product of a power of 5 and a power of 2. For example, 25ths, 16ths,
and 80ths can be written exactly with decimals, where as 3rds, 15ths, and 14th cannot.
Observe that 25 = 52 and 16 = 24 as well as 80 = 24 5. Those denominators have
only 2s and 5s in their prime factorization. Meanwhile, 3 = 3 and 15 = 5 3 while
14 = 7 2. As you can see, those denominators have primes other than 2 and 5 in their
prime factorization. If you find this interesting, you should read Using Sage to work with
Integers on Page 145.
4 1. WELCOME TO SAGE!
sqrt(3.4)
will evaluate to 1.84390889145858, without need of using N().
Tab Completion:
Now would be a good time to explain a neat feature of Sage. If you are
typing a long command, like numerical approx and part way through
you forget the exact ending (is it approximation? approximations? appr?)
then you can hit the tab button. If only one command in the entire library
has that prefix, then Sage will fill in the rest for you. If it does not, then
you get a list of suggestions. It is a very useful feature when you cannot
remember exact commands. We will see other examples of built-in help
features in Section 1.10 on Page 47.
Theres another keyboard shortcut that I like. While I mentioned it
before, if you are tired of clicking evaluate all the time, you can just press
Shift and Enter at the same time. This does the same thing as clicking
Evaluate.
Is Sage Case-Sensitive?
Youve probably had a situation in life where you entered your password
correctly, but discovered that it was rejected because you had the wrong
capitalization. For example, perhaps youve left the CAPS-LOCK key
on. In any event, Sage does think of Pi as dierent from pi and Sin as
dierent from sin.
1.2. USING SAGE WITH COMMON FUNCTIONS 5
The only four exceptions known to me are i and n(), as well as True and
False. We will not make extensive use of True and False until Chapter 5,
but it is harmless to mention that you can also enter them as true and
false,
p and Sage recognizes these as the same. You may have heard that
1 is often referred to as the
p imaginary number and is denoted i.
Next, you can represent 1pas either i or I and either way Sage will
know what you meant, namely 1. If youve never heard of imaginary
numbers or i, then you can safely ignore this fact. Lastly, you can write
n(sqrt(2)) or N(sqrt(2)) and Sage treats those as identical. p
So far as I am aware, these easements only apply to 1 and n(), as
well as True and False as it turns out; in all other cases, capitalization
matters.
Exponentials:
Just as
2^3
gives you 23 and likewise
3^3
gives you 33 , if you want to say e3 then just say
e^3
and thats fine. Or for a decimal approximation you can do
N(e^3)
Also, it is worth mentioning sometimes books will write
exp(5 11 + 8) instead of e511+8
and Sage thinks thats just fine. For example,
exp(5*11+8) - e^(5*11+8)
evaluates to 0. Dont forget the asterisk between the 5 and the 11.
Logarithms:
Of course, Sage knows about logarithmsbut theres a problem. There are
several types of logarithm, including the common logarithm, the natural
logarithm, the binary logarithm, and the logarithm to any other base you
feel like using. In high school log refers to the common logarithm, and
ln to the natural logarithm. However, after calculus log refers to the
natural logarithm. Since Sage was mainly meant for university-and-higher
level work, then it is only natural they chose to use the natural logarithm
for log.
So to find the natural logarithm of 100 type
N( log(100) )
for the common logarithm of 100 type
N( log(100,10) )
and for the binary logarithm of 100 type
6 1. WELCOME TO SAGE!
N( log(100,2) )
which of course generalizes. For example, to find the logarithm of 100 taken
base 42, type
N( log(100,42) )
Note that Sage is quite good at getting exact answers. Try
log ( sqrt(100^3), 10)
and you will obtain 3, the exact answer.
A Financial Example:
Suppose you deposit $ 5000 in an account that earns 4.5% compounded
monthly. Perhaps you are curious when your total will reach $ 7000. Using
the formula A = P (1 + i)n , where P is the principal, A is the amount at the
end, i is the interest rate per month, and n is the number of compounding
periods (number of months), we have
A = P (1 + i)n
7000 = 5000(1 + 0.045/12)n
7000/5000 = 5000(1 + 0.045/12)n
1.4 = (1 + 0.045/12)n
log 1.4 = log(1 + 0.045/12)n
log 1.4 = n log(1 + 0.045/12)
log 1.4
= n
log(1 + 0.045/12)
And so, we type into Sage
log(1.4)/log(1+0.045/12)
and get the response 89.8940609330801, so that we know 90 months will
be required. Therefore we write the answer 90 months, or even better, 7
years and 6 months.
This is an example of a computer-assisted solution to a problem. In
addition to that approach, Sage is also willing to solve the problem from
start to finish, with no human intervention. Well see that on Page 46.
[2, -2]
where the square brackets indicate a list. Any sequence of numbers separated
by commas and enclosed in square brackets is a list. Well see other examples
of lists throughout the book.
in calculus but annoying on hand-held calculators, are built into Sage. They
are identified as cot, sec, and csc.
The inverse trigonometric functions are also available. They are used
just like the trigonometric functions. For example, if you type
arcsin(1/2)
you will obtain
1/6*pi
as expected. Likewise
arccos(1/2)
produces
1/3*pi
The usual abbreviations are all known by and used by Sage. Here is a
complete list:
1
sin x arcsin(x) asin(x)
cos 1x arccos(x) acos(x)
tan 1x arctan(x) atan(x)
cot 1x arccot(x) acot(x)
sec 1x arcsec(x) asec(x)
csc 1x arccsc(x) acsc(x)
You can also use Sage to graph the trigonometric functions. Well do that
in the section entitled Using Sage to Graph 2-Dimensionally, on Page 11.
plot(x^2)
and you get a lovely plot of a parabola going in the range
1<x<1
which is the default range for the plot command. It will bound the y-values
to whatever is needed to show those x-values. Heres a screenshot of what
you should see:
plot(x^3-x, -2, 2)
Now would be a good time to mention that you can save any of these
plots to a file after having Sage generate them. Just right-click on the
displayed graph in your web browser, and save the file to your computer.
You can then import the image into any report or paper that you might be
writing. A very cool graph is
plot(x^4 - 3*x^2+2,-2,2)
but notice the asterisk between 3 and x in 3*x . You will get an error if
you leave that out! The plot is
1.4. USING SAGE TO GRAPH 2-DIMENSIONALLY 11
Another minor sticking point is that for y = sin(t) you have to say
plot(sin(x))
or better yet
plot(sin(x),-10,10)
because plot is not expecting t, it expects x. The images that you get are
plot(sin(x)) plot(sin(x),-10,10)
because in this case, Sage does not know what t means. An alternative
way of handling this is given on Page 104.
plot(x^3, 5, 10)
and as you can imagine, the function goes from 53 = 125 up to 103 = 1000,
thus the origin should appear very far below the graph. This is the plot:
Your hint that the location of the x-axis in the display is not where it
would be normally is that the axes do not intersect. This is to tell you that
the origin is far away. When the axes do intersect on the screen, then the
origin is (both in truth and on the screen) where they intersect.
Also, if you want to, you can hide the axes with
in order to obtain
This is important, because normally Sage wants to show you the entire
graph. Therefore, it will make sure that the y-axis is tall enough to include
every point, from the maximum to the minimum. For some functions, either
the maximum or the minimum or both could be huge.
Plot 1 Plot 2
Plot 3 Plot 4
Plot 1:
plot(1/(x^3-x), -2, 2)
Plot 2:
plot(1/(x^3-x), -2, 2, ymin = -5, ymax = 5)
Plot 3:
plot(1/(x^3-x), (x,-2, 2), detect_poles=True,
ymin = -5, ymax = 5)
Plot 4:
plot(1/(x^3-x), (x,-2, 2), detect_poles=show,
ymin = -5, ymax = 5)
As you can see, the first is a disaster. The second one cuts o the
very-high and very-low y-values, but it keeps trying to connect the various
limbs of the graph. When you set detect poles to True, then it will
figure out that the pieces are not connected.
One minor point remains. Did you notice in the four plots above, that
show is in quotes, but True is not in quotes? Thats because True and
False occur so often in math, that they are built-in keywords in Sage.
However, the show occurs less often, and therefore is not built in, and we
must put it in quotes.
As you can see, adding the two plots makes a super-imposition. The
plus sign tells Sage to draw the two curves on top of each other. Now, we
can do better by adding a dot at the point of tangencythe point (1, 2) and
perhaps some gridlines. The command for that will be
As you can see, we added the point using the point command and this
too was superimposed using the plus sign. The gridlines=minor gave
us the very satisfactory grid which can be so useful in preparing nice graphs
that are readable, for lab reports, classroom use, or papers for publication.
We will discuss other ways of making gridlines, as well as other ways of
annotating a graph, in Section 3.1 on Page 91. This specific graph will
appear in a highly annotated way on Page 95.
By the way, it is important that the above command, adding the two
plots plus a point, must be all on the same line. One cannot have a line
break. I cannot typeset it on one line because the page I am typing on is
not infinitely wide. Be sure there are no line breaks when you type those
commands in.
y = (x 1)(x 2)(x 5)
on its graph. (In other words, you want to know what happens if you change
the 5 in that equation to other numbers.) Then you could consider looking
at (x 3) and (x 4) as replacements for the (x 5), as well as (x 6) and
(x 7). This could be done by
plot((x-1)*(x-2)*(x-3), -2, 10) + plot((x-1)*(x-2)*(x-4), -2,
10) + plot((x-1)*(x-2)*(x-5), -2,10) + plot((x-1)*(x-2)*(x-6),
-2, 10) + plot((x-1)*(x-2)*(x-7), -2, 10)
where I chose the domain, x = 2 until x = 10, arbitrarily. By the way,
when you enter that previous command in, it is important to note that it
must be on one (very long) line. If done correctly, we obtain
1.4. USING SAGE TO GRAPH 2-DIMENSIONALLY 17
In any case, now I can see better what that last numeral does. It controls
the location, or x-coordinate, of the last time that the curve crosses the x-
axis. As you can see, the plus sign among the plot commands means to
superimpose them.
There is a technicality here. You must not break a newline among the
plots and plus signs. Therefore, if you have problems getting those last
two commands to work, then check to see that you have no accidental line
breaks in the command. For Sage, these commands must be entered with-
out a line break, kind of like typing a long paragraph in an ordinary word
processoryou can wrap around the end of the line, but you cannot insert
a line break. This is an example of code that is functional, but not easy
to read, nor change, and certainly not easy to understand. We can fix this,
with a bit of eort. The various plot commands and their plus signs must
be strung together, like a paragraph, wrapping naturally from one line to
the next. You do not use the enter key to put each plot on its own line.
Thus, you cannot do:
plot( (x-1)*(x-2)*(x-3), 1, 6)
+ plot( (x-1)*(x-2)*(x-4), 1, 6)
+ plot( (x-1)*(x-2)*(x-5), 1, 6)
+ plot( (x-1)*(x-2)*(x-6), 1, 6)
+ plot( (x-1)*(x-2)*(x-7), 1, 6)
which Sage thinks is five separate commands, instead of one big command.
However, there is a nice way out of this dilemma. You can type the
following, which produces the desired graph.
P1 = plot( (x-1)*(x-2)*(x-3), 1, 6)
P2 = plot( (x-1)*(x-2)*(x-4), 1, 6)
P3 = plot( (x-1)*(x-2)*(x-5), 1, 6)
P4 = plot( (x-1)*(x-2)*(x-6), 1, 6)
P5 = plot( (x-1)*(x-2)*(x-7), 1, 6)
P = P1 + P2 + P3 + P4 + P5
P.show()
Im sure we can all agree that this is much more readable code.
of graph or plot you would like, and just read that tiny subsection of that
chapter.
3x 4y + 5z = 14
x + y 8z = 5
2x + y + z = 7
First you would convert those equations into the following matrix:
2 3
3 4 5 14
A=4 1 1 8 5 5
2 1 1 7
Notice that the coefficients of the xs all appear in the first column; the
coefficients of the ys all appear in the second column; the coefficients of the zs
all appear in the third column. The fourth column gets the constants. Thus
we have encapsulated and abbreviated all of the information of the problem.
Furthermore, observe that additions are represented by a positive coefficient,
and subtractions by a negative coefficient. By the way, the vertical line
between the third and fourth column is just decorativeits purpose is to
show that the fourth column is special in that it contains numbers, whereas
the other columns represent the coefficients of the variables x, y, and z.
Matrices have a special form called Reduced Row Echelon Form often
abbreviated as RREF. The RREF is, from a certain perspective, the simplest
description of the system of equations that is still true. The Reduced Row
Echelon Form of this matrix A is
2 3
1 0 0 3
4 0 1 0 0 5
0 0 1 1
20 1. WELCOME TO SAGE!
Also in the first equation, the w is on the wrong side, and we must
move it to the left of the equal sign. It is necessary that all the
variables end up on one side of the equal sign, and all the numbers
on the other side of the equal sign. With these two repairs, the first
equation is now
w + 2x + y 5z = 6
The second equation has the constant on the wrong side, and so
we must move it across the equal sign, remembering to negate it.
As if that were not enough, both x and w are missing in the second
equation. We treat this as if the coefficients were zero. With these
two repairs, the second equation is now
0w + 0x y+z = 5
The third equation has parenthesesthats not allowed. We have
to remember that 3(x + y) = 3x + 3y.
Also in the third equation, the z is on the wrong side. We must
take care to change +z into z when crossing the equal sign.
A third defect in the third equation is that there is no constant.
We treat this as a constant of zero. Correcting these three issues,
the third equation becomes
w + 3x + 3y z=0
Now the real delinquent is the fourth equation. We have w on the
wrong side, and what is worse is that there are two occasions of
x. When we move the 3x from the right of the equal sign to the
left, it becomes +3x and combines with the +2x that was already
there, to form 5x. As if that were not enough, the constant is on
the wrong side. Last but not least, z is entirely absent. Correcting
all these defects, we have
w + 5x y + 0z = 1
With these (modified) equations in mind, we have the matrix:
2 3
1 2 1 5 6
6 0 0 1 1 5 7
B=6 4 1 3 3
7
1 0 5
1 5 1 0 1
The RREF of that matrix would be tedious to find by hand. However,
it would be far worse to solve that system of equations by hand without ma-
trices, using ordinary algebra. However, using Sage, we will easily compute
the RREF in the next subsection. For now, it turns out that the answer is
w= 107/7 x= 12/7 y = 54/7 z = 19/7
which you can easily verify now if you like.
22 1. WELCOME TO SAGE!
columns. You can feel free to use which ever format you might happen to
feel more comfortable with.
Now that B has been entered (by either method) we should add the
command print B.rref() on its own line, and we learn that the RREF is
2 3
1 0 0 0 107/7
6 0 1 0 0 12/7 7
6 7
4 0 0 1 0 54/7 5
0 0 0 1 19/7
which gives the final answer of
w= 107/7 x= 12/7 y = 54/7 z = 19/7
for the original system of equations. Now we must check our work. For
example, we check the first equation with
print 2*(-12/7) - 5*(19/7) + 54/7
and
print 6 + -107/7
both of which come out to -65/7. The point is not that they come out
to -65/7, but rather that they come out equal. Thus the first equation is
satisfied. We check the other three equations similarly.
We really do have to plug each of the four values into each of the four
equations, by the way. For example, the imposter solution
w= 139/7 x= 8/7 y = 64/7 z = 29/7
satisfies the first three of those equations, but fails to satisfy the last one.
If you happened to read Section 1.5.2, you will recall that we did quite
a lot of work to get B. Those many steps might have contained an error if
we were sloppy. Thats another reason that we should check our work.
print "Question:"
print B
print "Answer:"
print B.rref()
The lines containing print "Question:" and print "Answer:" are en-
tirely optional, but help make the output more readable. They also encour-
age me to check that I had actually entered the matrix which I had intended
1.5. MATRICES AND SAGE, PART ONE 25
Note: this problem might seem artificial, but it actually an applied prob-
lem which we will revisit shortly. Like many application-based problems, the
answers have decimal points, which hopefully should not frighten you. Well
see the answer shortly.
matrix down: 2 3
592 59 1 0.87
4 792 79 1 0.61 5
992 99 1 0.42
and ask Sage to compute the RREF. However, youve already done that
yourself! You already computed the solution
a = 0.0000875 b= 0.025075 c = 2.0448375
as practice, on Page 25 as Section 1.5.6.
Finally, we conclude that the function is
f (p) = 0.0000875p2 0.025075p + 2.0448375
The graph of this function is given below:
If you are curious, the code which produced that plot was
f(x) = 0.0000875*x^2 - 0.025075*x + 2.0448375
x + 2y + 3z = 7
4x + 5y + 6z = 16
7x + 8y + 9z = 24
That results in the matrix
2 3
1 2 3 7
C1 = 4 4 5 6 16 5
7 8 9 24
and that we shall enter into Sage with
C1 = matrix(3,4, [1, 2, 3, 7, 4, 5, 6, 16, 7, 8, 9, 24])
Next, to find the RREF we type
C1.rref( )
and receive back
[ 1 0 -1 0 ]
[ 0 1 2 0 ]
[ 0 0 0 1 ]
This translates into
x z = 0
y + 2z = 0
0 = 1
The bottom equation says 0 = 1, which is clearly not true! There is no
way to satisfy the requirement that 0 = 1. Therefore, this equation has no
solutions. Instead of the answer being a solution, a list of solutions, or
infinitely many solutions, the answer is the sentence This linear system of
equations has no solutions. That will be the outcome whenever the RREF
has a row with all zeros except the last column, which is a non-zero number.
Whenever you see a row with all zeros, except in the last column where a
number other than zero is found, then you must remember that the system
has no solutions.
Another interesting case is to change the 24 in the last equation to 25.
That results in the matrix
2 3
1 2 3 7
C2 = 4 4 5 6 16 5
7 8 9 25
and that we shall enter into Sage with
C2 = matrix(3,4, [1, 2, 3, 7, 4, 5, 6, 16, 7, 8, 9, 25])
1.5. MATRICES AND SAGE, PART ONE 29
Finally, it should be noted that in Appendix D, you can learn the rela-
tively straight-forward technique that maps out exactly how to handle linear
systems of equations with infinitely many solutions, regardless of the num-
ber of rows and columns. The trick there is only slightly more complicated,
but it always works. Furthermore, it gives you formulas for producing as
many solutions from the set of infinitely many solutions, as you might want
to generate. You can also use those formulas for other purposesfor ex-
ample, to test if a candidate solution is actually one of the infinitely many
solutions.
Please do not imagine that linear systems with infinitely many solutions
are terribly rarethey do occasionally come up in applications. However,
they are uncommon enough that we will not burden you with those details
yet, but we will wait until Appendix D.
Defining a Function:
For example, if you want to define f (x) = x3 x then you type
f(x) = x^3-x
f(2)
where we have defined f (x) and asked it the value of f (2). You could
instead pask for f (3), or any other number. Likewise if you wanted to define
g(x) = 1 x2 you would type
g(x) = sqrt( 1-x^2 )
g(1/4)
where we have defined g(x) and asked what g(1/4) evaluates to. You could
just as easily ask for g(1/2) or any other number in the domain of g.
To evaluate several values, you can use the print command.
g(x) = sqrt( 1-x^2 )
print g(0.1)
print g(0.01)
print g(0.001)
print g(0.0001)
6Just to clarify, I am talking about mathematical functions, such as f (x) = x3 . How-
ever, if you are an experienced computer programmer, you might know about defining
functions in a programming languagesometimes called procedures, methods, or subrou-
tines. That will be discussed in Section 5.2 on Page 226.
1.6. MAKING YOUR OWN FUNCTIONS IN SAGE 31
print g(0.00001)
print g(0.000001)
If perhaps you happen to have started calculus, you can see that the
above output would help you evaluate
lim g(x) = 1
x!0+
Plotting Functions:
Now that weve defined f (x) and g(x), we can plot them with
f(x) = x^3-x
plot( f, -2, 2 )
you get the expected plot
Note that you really do have to keep the definitions of f (x) or g(x) in
the window and written out each time you hit Evaluate. This is a fea-
ture of the Sage cell server. It has amnesia, and treats each press of the
button Evaluate as its own separate mathematical universe. This is for
the beginners benefit, because it makes the correcting of minor typograph-
ical errors very easy. You just fix the error, click Evaluate and all is
well. SageMathCloud works just slightly dierently, as will be explained on
Page 301.
Composition of Functions:
You can also compose two functions very easily in Sage. Consider the fol-
lowing two functions
f (x) = 3x + 5 and g(x) = x3 + 1
Perhaps we wish to explore f (g(x)). The easy way to do this is to define
a third function, h(x) = f (g(x)). Then perhaps we might want to print that
function, and the values of h(x) at x = 1, x = 2, and x = 3. The Sage code
for this is straight forward:
f(x) = 3*x + 5
g(x) = x^3 + 1
h(x) = f(g(x))
print h(x)
print h(1)
print h(2)
print h(3)
That produces the output
3*x^3 + 8
11
32
89
as desired. However, if we replace the third line with h(x) = g(f (x)), then
we get completely dierent output
(3*x + 5)^3 + 1
513
1332
2745
34 1. WELCOME TO SAGE!
Multivariate Functions:
This section has dealt with functions of one variable. Sage can very easily
and simply handle functions of multiple variables. For example,
f (x, y) = (x4 5x2 + 4 + y 2 )2
Well cover this in detail in Section 4.1 on Page 127.
a(x) + b(x)
we get the correct answer of 2x2 13x + 21. Note, it is very important to
remember the asterisk between the 5 and the x as well as the 8 and the x.
Similarly, if you change the + sign between a(x) and b(x) into a - sign,
then we also get the correct answer of 3x 9. As you can imagine, the
product can be conveniently calculated as well:
a(x) = x^2 - 5*x + 6
b(x) = x^2 - 8*x + 15
1.7. USING SAGE TO MANIPULATE POLYNOMIALS 35
a(x)*b(x)
but this provides the unfinished yet undeniably true answer
(x^2 - 5*x + 6)*(x^2 - 8*x + 15)
Instead, we can do the following
a(x) = x^2 - 5*x + 6
b(x) = x^2 - 8*x + 15
g(x) = a(x)*b(x)
g.expand()
and we get g(x) written without parentheses. In computer algebra, thats
called expanded form. The expanded form of our g(x) happens to be
x |--> x^4 - 13*x^3 + 61*x^2 - 123*x + 90
The symbol |--> means evaluates to. What Sage is telling you here
is that g(x) is a function that sends x to x4 13x3 + 61x2 123x + 90.
Instead, we can write g.factor() in place of g.expand() in which case
we get the following output:
(x - 2)*(x - 3)^2*(x - 5)
You can also factor more directly with
a(x) = x^2 - 5*x + 6
factor( a(x) )
and get the correct answer of (x 2)(x 3). Alternatively we can be even
more direct by typing
factor( x^2 - 8*x + 15 )
to obtain (x 3)(x 5).
You can also compute the greatest common divisor or gcd of two
polynomials. For example, the following code
a(x) = x^2 - 5*x + 6
b(x) = x^2 - 8*x + 15
f(x) = a(b(x))
print "Direct:"
print f(x)
print "Expanded:"
print f.expand()
print "Factored:"
print f.factor()
would produce the correct answer using only a pencil and a great deal of
human patience
factor( x^4 - 60*x^3 + 1330*x^2 - 12900*x + 46189 )
Speaking of the integer roots theorem, we could type factor(46189)
and get 11 * 13 * 17 * 19 to help us find roots of that quartic polynomial.
The factor command deals with both factoring a polynomial and factoring
an integer. The command divisors(46189), as an alternative, lists all the
positive integers which divide 46,189. Naturally, thats a longer list than
factor, which only would list the prime divisors (and their exponents, if
any). Compare factor(2048) and divisors(2048), if you like.
The composition of functions is also not a problem. The code given in
Figure 1 will compose two polynomials and produce the answer in three
forms. It is noteworthy that this is our first real program in Sage, in
the sense that it is the first time that weve used more than two or three
commands at once.
In particular, our program produces the output:
Direct:
(x^2 - 8*x + 15)^2 - 5*x^2 + 40*x - 69
Expanded:
x |--> x^4 - 16*x^3 + 89*x^2 - 200*x + 156
Factored:
(x^2 - 8*x + 13)*(x - 2)*(x - 6)
The above code demonstrates how it can be very useful to label parts of
your output with print commands if youre outputting more than one or
two items. Such labeling (sometimes called annotating the output) is a
good general practice as you learn to tackle more and more complex tasks
in Sage.
Just as we saw at the end of Section 1.6, you get a dierent answer if
you change f(x) = a(b(x)) into f(x) = b(a(x)). Go ahead, give it a try,
and see for yourself!
1.8. USING SAGE TO SOLVE PROBLEMS SYMBOLICALLY 37
var(theta)
solve(sin(theta)==1/2, theta)
to get
[theta == 1/6*pi]
but note that there are many values for which sin = 1/2. For example,
31 23 19 11 7 5 13 17 25 29
2 ..., , , , , , , , , , , ,...
6 6 6 6 6 6 6 6 6 6 6
are several values of that solve sin = 1/2.
Declaring Variables:
You might be confused to see that var command above. The idea is that
you need to tell Sage that this variable is not yet known. Weve used vari-
ables before, but thats because we had assigned values to them. When you
want a variable to represent some unknown quantity, you must use var.
The variable x is always pre-declared, you do not need to declare itSage
assumes that x is an unknown.
x+b = 6
x b = 4
9a + 3b + 1c = 32
4a + 2b + 1c = 15
1a + 1b + 1c = 6
4
p 2
p
10 2
Solution #2: p = 1, q = 8, x = 3 10 3, y = 6 3
Since there are only two answers, we cannot ask for a third. In fact, if
we type print answer[2] then we get
Traceback (click to the left of this block for traceback)
...
IndexError: list index out of range
which is Sages way of telling you that it has already given you all the
answers for that problemthe list does not contain a 3rd element.
Now lets try to intersect the hyperbola x2 y 2 = 1 with the ellipse
x /4 + y 2 /3 = 1. We type
2
var(y)
solve([x^2-y^2==1, (x^2)/4+(y^2)/3==1], x, y)
and obtain
[x == -4/7*sqrt(7), y == -3/7*sqrt(7)], [x == -4/7*sqrt(7),
y == 3/7*sqrt(7)], [x == 4/7*sqrt(7), y == -3/7*sqrt(7)],
[x == 4/7*sqrt(7), y == 3/7*sqrt(7)]]
which is unreadable. Once again, we change the command to be
answer=solve([x^2-y^2==1, (x^2)/4+(y^2)/3==1], x, y)
and then type
print answer[0]
print answer[1]
print answer[2]
print answer[3]
print answer[4]
and that produces four answers and an error message
[x == -4/7*sqrt(7), y == -3/7*sqrt(7)]
[x == -4/7*sqrt(7), y == 3/7*sqrt(7)]
[x == 4/7*sqrt(7), y == -3/7*sqrt(7)]
[x == 4/7*sqrt(7), y == 3/7*sqrt(7)]
Traceback (click to the left of this block for traceback)
...
42 1. WELCOME TO SAGE!
4
p 3
p
Solution #2: x = 7 7, y = 7 7
4
p 3
p
Solution #3: x = 7 7, y = 7 7
4
p 3
p
Solution #4: x = 7 7, y = 7 7
Complex Numbers:
Normally, we expect an 8th degree polynomial to have 8 roots, over the
complex plane, unless some are repeated roots. Therefore, if we ask what
are the roots of x8 + 1? then surely we expect 8 roots. These are the 8
eighth-roots of 1 in the set of complex numbers. We can find them with
solve(x^8==-1, x)
1.9. USING SAGE AS A NUMERICAL SOLVER 43
which produces
[x == (1/2*I + 1/2)*(-1)^(1/8)*sqrt(2), x == I*(-1)^(1/8), x ==
(1/2*I - 1/2)*(-1)^(1/8)*sqrt(2), x == -(-1)^(1/8), x == -(1/2*I +
1/2)*(-1)^(1/8)*sqrt(2), x == -I*(-1)^(1/8), x == -(1/2*I -
1/2)*(-1)^(1/8)*sqrt(2), x == (-1)^(1/8)]
giving us eight distinct complex numbers, all of which have 1 as their
eighth power. This can be calculated (by hand) more slowly with DeMoivres
formula, but for Sage, this is an easy problem. I simply copy-and-paste the
first root and raise it to the eighth power, as below
( (1/2*I + 1/2)*(-1)^(1/8)*sqrt(2) )^8
and Sage returns the answer 1.
a4 x4 + a3 x3 + a2 x2 + a1 x + a0 = 0
f (x) = x5 + x4 + x3 x2 + x 1
find_root(x^x-5, 1, 10)
or equivalently
find_root(x^x==5, 1, 10)
and then you can see the root is between 1 and 1. This means that we
should type
find_root(e^x-1/x,-1, 1)
Now here you could ask for a root of (sin x) (cos x). Alternatively, you
can also type
find_root( cos(x) == sin(x), 0, pi/2 )
which is just easier notation.
the change for peer review. If the change is found to be helpful and valid, it
will be made. Sometimes the entire process can take as little as six weeks.
This now brings up an important point: you have to know the name
of the command to use either of those first three methods of getting help.
What if you cannot remember the name of the command? This happens
often, and there are several solutions.
The official Sage Reference Manual can be found at
http://www.sagemath.org/doc/reference/
but it is not for beginners! Be warned, the manual is literally thousands of
pages long. The manual is like an encyclopedia: you dont read it cover to
cover, instead you look up what you need. Luckily, there is a handy Quick
Search box on the left-hand side.
Tutorials are much more useful for most readers. Some are organized
around a mathematical topic and others are organized around a target au-
dience. There is a collection of Sage tutorials, a partial list of which can be
found in Appendix C on Page 305.
There is also a way to search all the docstrings of all the commands in
Sage. However, this will usually produce a very large number of results.
Type, for example:
search_doc("laplace")
and you will see a huge response. It is not exactly human-readable. Here is
a particular line of that output:
html/en/constructions/calculus.html:231:<div class="section"
id="laplace-transforms">
The entire line refers to a webpage. The middle number, between the
columns, is a line numberone is the top line, two is the second line, and
so forth. The information after the second column is written in the HTML
language. If you know HTML, then you can8 use that information.
So far search doc has not told us anything useful, but the information
to the left of the first colon is very useful. That is a filename inside of a
directory hierarchy that contains the documentation of Sage. Usually Sage
is used through a server, such as the Sage cell server or SageMathCloud.
However, one can do a local install, which means you are running Sage
contained entirely inside your own computer, and not communicating with
a remote server. This is not recommend except for experts.
What, then, should the rest of us (who use Sage through a web browser
or SageMathCloud) do in order to get at the information? We must go to
the following URL, which is essentially the information which search doc
provided, but in a dierent word order.
http://www.sagemath.org/doc/constructions/calculus.html?
As you can see, we replaced html/en/ with
8If you do not know HTML, perhaps you might want to consider learning it. The
HTML language is extremely useful and easy. Being able to make your own web-pages is
an excellent skill, and highly marketable.
1.11. USING SAGE TO TAKE DERIVATIVES 49
http://www.sagemath.org/doc/
in order to construct that URL. That substitution will work in general. By
the way, the en refers to the English language, with fr referring to French, de
to German, and ru to Russian, according to the normal two-letter language
codes in use on the internet.
An Example of Integration:
Using an integral, how would you calculate the area between the x-axis and
f (x) = x2 + 1 on the interval 3 x 6? Well, that integral would be
Z 6 6
1 3 1 3 1 3
x2 + 1 dx = x +x = 6 +6 3 +3 = 72+6 (9+3) = 66
3 3 3 3 3
and that is a number. Here weve done it analytically, using calculus. This
is an exact definite integral. It is definite, because it ends with a number.
It is exact, because we did no approximations.
On the other hand,
Z
1
x2 + 1 dx = x3 + x + C
3
is an indefinite integral. It produces a function, and not a number. Of course,
we often calculate an indefinite integral on the way to calculating a definite
integral; nonetheless, the definite and indefinite integrals are two distinct
categories. If you want a function, you should use the indefinite integral,
and if you want a number, then you should use the definite integral.
Impossible Integrals:
The word impossible is a dangerous one in mathematics. Some integrals
are famously impossible. The two most famous are the Fresnel Integral
Z x
t2
sin dt
0 2
which is important in optics, and the Gaussian Integral
Z y
2 2
p e( x ) dx
0
1.12. USING SAGE TO CALCULATE INTEGRALS 53
x3
f (x) = e sin(x2 )
9We should also include the hyperbolic cousins of the trigonometric functions and
inverse trigonometric functions, which you might or might not have been taught about.
54 1. WELCOME TO SAGE!
This function f (x) seems interesting, but computing its integral is quite
frustrating. I cannot solve that integral with my pencil, and I am willing to
wager that you cannot either. Try it if you like.
While it is the case that there is some function g(x), somewhere, which
3
has f (x) = e x sin(x2 ) as its derivativea logical consequence of some ad-
vanced real analysis and the fact that f is continuousthe practicalities of
the matter are that there is no way to write down g(x) as a formula. To
be really precise, there is no function g(x), built up of addition, subtrac-
tion, multiplication, division, roots, exponents, logarithms, trigonometric
functions, and inverse trigonometric functions (as well as their hyperbolic
cousins, which you might or might not have been taught about) which will
have g 0 (x) = f (x).
3
In other words f (x) = e x sin(x2 ) is integrable, but the integral cannot
be written in terms of common (and not so common) functions. However,
one could produce a g(x) made with an infinite series in Big-Sigma notation
that would have g 0 (x) = f (x).
Returning now to Sage, since
Z
x3
e sin(x2 )dx
where the 20 could be any decently large number. This comes up in explain-
ing what Eulers gamma function is, but we arent too concerned with that
right now. In any case, we could just type
integral( (t^20)*(e^t), t )
but then we get back
(t^20 - 20*t^19 + 380*t^18 - 6840*t^17 + 116280*t^16 - 1860480*t^15
+27907200*t^14 - 390700800*t^13 + 5079110400*t^12 - 60949324800*t^11
+ 670442572800*t^10 - 6704425728000*t^9 + 60339831552000*t^8
- 482718652416000*t^7 + 3379030566912000*t^6 - 20274183401472000*t^5
+ 101370917007360000*t^4 - 405483668029440000*t^3
+ 1216451004088320000*t^2 - 2432902008176640000*t
+ 2432902008176640000)*e^t
which is large enough that it isnt clear how to get an idea of what that
means. If instead, we had certain bounds, such as to calculate
Z 3
t20 et dt
2
then we would type
integral( (t^20)*(e^t), t, 2, 3 )
and get instead
-329257482363600896*e^2 + 121127059051462881*e^3
which is getting toward an answer! If you really want a numerical answer
then you should use our old trick, the command N (), and type
N( integral( (t^20)*(e^t), t, 2, 3 ) )
which would return the number
8.79797452800000e9
and that means 8.79797452800000 109 . This highlights the dierence and
similarities of the various types of answer. If youve forgotten about N (),
see Page 3.
That number which we just calculated looks like an integer, because it
ends with 528 when you carry out the 109 partbut when we look at the
exact answer, we can see that no, it is not an integer. We know that because
e2 and e3 are involved, and e is an irrational number. Whenever dealing
with computations, it is critical to remember what is an approximation, and
what is exact. Irrational number can be expressed exactly on occasion (like
we just did here, using e2 and e3 ) but that is the exception and not the rule.
In any case, this paragraph has nothing to do with Sage, therefore we return
to the topic at hand.
56 1. WELCOME TO SAGE!
Improper Integrals:
While the following integral is mathematically valid
Z
1 1
1 + 2 dx = x +C
x x
and the right-hand side can be evaluated at x = 1 and x = 1, there is no
finite answer to Z 1
1
1 + 2 dx
1 x
because this improper integral is divergent. The graph will help reveal why
that is the case. Here is the plot of 1 + 1/x2
generated by
plot( -1+1/x^2, -10, 10, ymin=-2, ymax=2 )
Yet, Sage knows this and will say
-x - 1/x
in response to
integral(-1+1/x^2,x)
but instead will respond
ValueError: Integral is divergent.
to the inquiry
58 1. WELCOME TO SAGE!
integral(-1+1/x^2,x,-1,1)
If youd like a proof of the fact that the above integral is divergent,
consider that
Z 1 Z 0 Z 1
1 1 1
1 + 2 dx = 1 + 2 dx + 1 + 2 dx
1 x 1 x 0 x
Lets consider the integral above, from 0 to 1, by means of computing
that integral from a to 1, where a will be slightly more than 0.
Z 1
1 1 1
1+ 2 = x
a x x a
1 1
= 1 a
1 a
1
= a 2+
a
As you can see, when a approaches 0 from the positive real numbers,
the value of a 2 + 1/a becomes huge. More precisely, we can write
1
lim a 2 + =1
a!0+ a
but then that also means
Z 1
1
lim 1+ 2 dx = 1
a!0+ a x
and, as it turns out, the same is true for the integral from -1 to 0 as well.
Therefore, the original integral is equal to 1 + 1 = 1.
which in Sage is
integral(exp(-x^2),x,-oo,oo)
p
and it gives the correct response of .
The idea is simply that oo is a special code for infinity. It is two letter
os, and the idea is that if you squint, oo looks like an infinity symbol.
1.12. USING SAGE TO CALCULATE INTEGRALS 59
a text message or be tweeted. The short temporary link, on the other hand,
is shorter and less intimidating to a human. Being shorter, it is less likely
to be truncated in transit when sent by various means. However, it does
not contain a complete copy of your code. Instead, your code is stored on
the server, and the URL retrieves it. There is no guarantee for how long the
short temporary link will work. Perhaps a day, perhaps a year, or perhaps
forever but perhaps only an hour. In my experience, they often work several
days after being generated. Overall, Id have to say that if the length and
ugliness are not a problem, then the permalink should always be used and
the short link should never be used.
Those are my two favorite methods of sharing Sage code. The third
method Id like to share with you is the large 2D barcode produced when you
click share. This actually encodes the permalink and thus will work with
all smartphones that can read those 2D barcodes. Most phones will require
you to install an app for the smartphone to be able to handle those barcodes,
which are sometimes called QR codes, Quick Response Codes, or ma-
trix barcodes. On my phone, the app10 was called QR Code Reader, and
was free. If you photograph the barcode using one of those apps and the
camera inside your smartphone, then it should open up a web browser and
present the same results as the permalink will. You dont even need to click
Evaluate! Here is a sample 2D barcode:
The fourth method is when youve made a plot (as we learned in Sec-
tion 1.4 on Page 8). If youd like to include this image in any sort of doc-
ument, or email it to someone, then just save the image file from your
web browserin the same way that youd save any other image. In most
browsers, this is a right-click followed by selecting Save Image As. . . , and
entering in a filename at the appropriate spot. This image will be in the
10You really do need the app, however. Otherwise you just get a photograph of the
QR Code, which is totally unexciting.
62 1. WELCOME TO SAGE!
portable network graphic or *.png format. It will work in nearly all pro-
grams that allow the importing of an image. Alternatively, some high-end
mathematics and physics journals prefer encapsulated postscript or *.eps
files. Those can be generated by
P = plot( x^3-x, -2, 2 )
P.save("myplot.eps")
which will give you a link that will start the downloading of myplot.eps
when clicked upon.
The fifth method is just highlighting the Sage code, copying, and then
pasting it into an email. Sometimes I will paste it into SageMathCloud, or
my universitys course management software, D2L. Emailing code can save
time, and it is easy to post code in this way.
The sixth method is to print a screenshot of the Sage Cell Server. Using
a bit of scrolling around and resizing, one can often cause the entire Sage
block of code and its output to be visible at the same time. Then you can
use your browsers print command (often under the file menu) to print the
webpage just like youd print any other webpage. (Often the web browsers
print command is under the File menu.) This is often how I ask students
in my classes to submit a homework problem that has been done in Sage.
Last but not least, the seventh method is to follow the steps for printing a
screenshot of the Sage Cell Server, and instead of printing it as a physical
paper document, to select Save as a PDF from the web browsers print
menu. This PDF is essentially identical as a document to what youd get
from printing, except that it is an electronic copy, rather than a paper copy.
Scientific collaboration is one of the great joys of working in a STEM11
subject. I hope that you will have frequent opportunities to share not only
your ideas, but the hardcore mathematical and quantitative details of your
work, with others. Since Sage has been developed by hundreds of people
scattered across the globe, it is unsurprising that there many features built-in
to Sage to enable sharing. SageMathCloud has even more features, includ-
ing organized projects, sharing on an invitation-only basis, and live-chat
features. You can learn about those on the SageMathCloud website.
n = 360 80p
or equivalently
n
p = 4.50
80
Lets pause a moment, and see if this makes sense. First, plugging in
n = 200 and n = 120, we do get the prices of $ 2 and $ 3 that we expect.
If we set p = 2.50, then we get 160, as we would anticipatethats the
midpoint.
The easy way to find those equations is to compute the slope connect-
ing the points (200, 2) and (120, 3), and then find the equation of the line
between those two points. Of course, the form of the equation depends on
2.1. MICROECONOMICS: COMPUTING A SELLING PRICE 65
whether or not you assign p or n the role of x. I have seen both conventions
used in textbooksthere is no industry standard.
Now observe that, at a price of $ 4.50, he will sell no ice cream at all.
This should be believable, if people are usually expecting to pay around $ 2,
then you cannot charge them more than double what they are accustomed
to pay. The price where demand is zero is called the maximum feasible
price. Meanwhile, if the price of a cone is $ 0, then we sell 360 cones per
daythats called the saturation point and it is the most that one could
ever hope to sell, namely the demand at the price of $ 0. The model breaks
down for prices over $ 4.50, because it predicts a sale of a negative number
of cones, which does not make sense. Likewise, if you set a demand above
360 cones per day (the saturation point) then a negative price is called
for, which also does not make sense. So the model is valid for 0 p 4.50
dollars, or equivalently 0 n 360 cones.
Wed now like to make some revenue, cost, and profit functions in terms
of the number of cones sold, n. Clearly if one sells n cones at price p, then
the revenue is np. Therefore, we have
n n2
r(n) = np = n 4.50 = 4.50n
80 80
as the revenue function. Meanwhile, the cost function is 50 cents per cone,
plus $ 100, for a total of
n2
p(n) = + 4n 100
80
which is a parabola. It makes sense that we should get some sort of curve,
because if you make the price very low, or very high, then the profit is zero
or worseyou have a loss. Somewhere in the middle is the sweet spot, where
profit is made.
Lets make a table and see that these functions make sense and match
our prior data:
66 2. FUN PROJECTS USING SAGE
P.show()
Challenge
Your challenge is to analyze a new business situation. A particular book is
pre-sold by a publisher in two test markets for $ 49.95 and for $ 39.95. It
sells 80 copies and 140 copies respectively. In the past, the general sales for
the year are 100 times the sales of one of the test markets. (Just to be clear,
that means if the price is set at $ 49.95, the marketing experts predict 8000
copies will be sold, and likewise 14,000 copies at $ 39.95.)
The books require $ 7 to print, plus $ 4000 payable once for the proof-
reading costs. The publisher gets 50% of the sales revenue. In case you
are curious, usually around 20% of the sales revenue goes to the local book-
store, 20% to the distributor, and 10% goes to the authors royalties. You
may assume that the sales price and the number of copies sold have a linear
relationship.
The deliverables for this project are
(1) an equation relating the sales price and the number of copies sold,
(2) the revenue function,
(3) the cost function,
(4) the profit function,
2.2. BIOLOGY: CLOGGED ARTERIES AND POISEUILLES LAW 69
The Background
The formula itself is as follows.
r 4
V = ( P )
8L
and regrettably, we do not have time to derive it here. However, I strongly
recommend the curious reader to refer to the article Blood Vessel Branch-
ing: Beyond the Standard Calculus Problem, by Prof. John Adam, pub-
lished in the Mathematics Magazine, Vol. 84, by the Mathematical Associ-
ation of America, in 2011.
Lets take a moment to identify the meaning of each of those variables.
The V is the volume flow rate, in units such as cubic centimeters per
minute. In a major artery, a typical flow might be 100 cm3 /minute.
The radius of the artery is r, in units such as centimeters. A major
artery might be 0.3 cm or very roughly 1/8th of an inch in diameter.
The length of the artery is L, again in units such as centimeters.
A major artery might be 20 cm or 8 inches in length.
1Based on 2010 data, from the Center for Disease Control and Preventions web-
site FastStats. This data excludes (as unnatural causes) any homicides, suicides, and
accidents.
2Poiseuille, J-L. M., Recherches sur la force du coeur aortique, D.Sc., Ecole
Polytech-
nique, Paris, France. 1828.
70 2. FUN PROJECTS USING SAGE
Note: The unit of pressure can vary. The standard unit in the American
system of units is pounds per square inch, because forces are mea-
sured in pounds. Likewise, in the metric system, because forces are
measured in Newtons, the pressure units then become Newtons per
square meter. Using Newtons per square meter is kind of funny
because arteries arent several square meters in area. Another unit
of pressure used is atmospheres where atmospheric pressure is
1 atmosphere. Thats 14.6959 pounds per square inch or 101,325
N/m2 .
Medicine has been around for a long time. For historical reasons, it
is normal to measure blood pressure in a very archaic unit, called
millimeters of Mercury. When you go to the doctor and she tells
you that your blood pressure is 120 over 80, that 120 means 120
millimeters of Mercury, abbreviated 120 mmHg. Just take it as
a unit, and consider 120 to be normal. If you have 145 mmHg
for the first number (called systolic), you might be diagnosed as
having hypertension. A score of 180 mmHg systolic can result in
organ damage and is called a hypertensive emergency.
Viscosity is a physics variable that you might or might not have seen
before, and is denoted . It represents how sticky or thick a
fluid might be. Since blood is the fluid in question, and we wont
consider other fluids, we can just take to be a constant. The usual
unit is a poise. A typical value for blood might be = 0.0035
poise. In comparison, the oil in your car might have = 0.250 poise
(because it is sticky) and water has = 0.001 millipoise (because it
is not sticky). Honey is very sticky, and has a viscosity of 20 poise.
We cant use the poise as our unit, because were using an antique
unit for pressure. For us,
8
= 4.37535 10
Your Challenge
For this project, youre going to create some tables that can be used to help
a physician understand the numerical realities of that quartic relationship
in Poiseuilles Law between arterial radius and blood flow rate.
The tables will allow some variables to change, while most variables
are locked at standard values that are chosen to be very typical. The
standard values for our variables in this project are = 4.375359 10 8 for
the viscosity, L = 20 cm for the artery length, r = 0.3 cm for the arterial
radius, V = 100 cubic centimeters per second for the blood flow rate, and
finally P is 0.0275 mmHg.
2.3. INDUSTRIAL OPTIMIZATION: SHIPPING TACONITE 71
Your first table should keep our standard values for , L, P , and
compute V based on r, using Poiseuilles Law. The r should be
computed based upon the percent blockage, from 0% up to 50%, in
2% increments. The first column of the table should be the percent
blockage, the second column should be the blood flow rate or V .
Your second table should keep our standard values for , L, and V .
Again, the r should be computed based upon the percent blockage,
from 0% up to 50%, in 2% increments. This time, you will compute
the P required to achieve the flow rate of 100 cc/minute given the
blockage (the V given the P ), using Poiseuilles Law. The first
column of the table should be the percent blockage, the second
column should be the P . The third column should represent P
as the percent of normal. In other words, 3/2 the normal P
should be reported as 150%.
The third table should keep our standard values for , L, and
P . The first column should be the percent normal flow from
100% down to 25%, in steps of 3%. The second column should
be the flow rate, in cubic centimeters per second, identified by that
percentage. The third column should be the radius implied by this,
as computed by Poiseuilles Law. The fourth column should be the
percent blockage. (In other words, 0.15 cm radius is a 50% blockage
because 0.15/0.3 = 0.5.)
You can check your work by plugging into the original equation, but you
might also find it useful to compare your first table to the following, which
is given in increments of 6%.
0 % blockage implies 99.9617636500122 cc/minute.
6 % blockage implies 78.0450430095128 cc/minute.
12 % blockage implies 59.9466058383290 cc/minute.
18 % blockage implies 45.1948885141475 cc/minute.
24 % blockage implies 33.3494195216211 cc/minute.
30 % blockage implies 24.0008194523679 cc/minute.
36 % blockage implies 16.7708010049720 cc/minute.
42 % blockage implies 11.3121689849831 cc/minute.
48 % blockage implies 7.30882030491648 cc/minute.
54 % blockage implies 4.47574398425329 cc/minute.
Shipping Costs
and Superior, WI. You will figure out how much taconite to ship from each
mine to each of the four shipping facilities. You have several constraints.
First, it must be the case that the amount of taconite leaving each mine
(for all four destinations) should be exactly the amount produced that week.
It should not be greaterotherwise youre ordering your mines to ship more
taconite than they actually have; it should not be lessotherwise youll have
a build up of taconite that cannot be stored on site. The total production
at each mine is listed in Table 1.
Second, the demand and capacity of each shipping facility must be re-
spected. The Two Harbors, WI facility can receive and ship up to 18,000
tons. The Green Bay facility can receive and ship up to 25,000 tons. The
Duluth/Superior shipping complex can receive and ship between 15,000 and
45,000 tons, the minimum being there to ensure there is enough revenue to
pay the bills at this expensive location. The Minneapolis facility can receive
and ship between 10,000 and 30,000 tons.
Third, the shipping schedule should carry out the task of bringing the
taconite to the receiving and shipping stations at minimum cost. The cost
of shipping from each mine to each receiving and shipping facility is given
in the Table 1, in dollars per ton.
Your goal is to model this problem as a linear program, code it up
in Sage, and solve it. To help you out, I oer the following hint. Let
d1 , d2 , . . . , d7 be the amount shipped out of Duluth/Superior from the seven
mines. Let t1 , t2 , . . . , t7 be the amount shipped out of Two Harbors. Let
g1 , g2 , . . . , g7 be the amount shipped out of Green Bay. Let m1 , m2 , . . . , m7
be the amount shipped out of Minneapolis.
Because youll be showing a lot of work in this process, I have no fear of
giving you the final answer. Here is the output of my program:
The minimum cost shipping arrangement is
1883000.0
The quantities shipped to Two Harbors from the seven mines are
{1: 0.0, 2: 13000.0, 3: 0.0, 4: 0.0, 5: 0.0, 6: 5000.0, 7: 0.0}
The quantities shipped to Green Bay from the seven mines are
{1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0, 5: 0.0, 6: 3000.0, 7: 0.0}
2.4.1. Background
Lets start with an energetic example. Back in the age of airships, American
airships were often filled with helium. However, Germany had no access to
large supplies of helium, and so they used hydrogen instead. This is unfor-
tunate because hydrogen gas can explode in the presence of a spark. The
Hindenburg was an airship made by the Zeppelin Company, and exploded
into a fireball in 1937 near Lakehurst, New Jersey. The hydrogen gas com-
bines with oxygen in the air and forms water vapor. Here is the chemical
formula for that reaction:
2 H2 + O2 ! 2 H2 O
74 2. FUN PROJECTS USING SAGE
(4) In the previous example, we said that phosphoric acid (H3 PO4 )
occurs in soda drinks. Where does it come from? It can be read-
ily made from pure elemental phosphorous and hypochlorous acid
(HClO) in the presence of water. Hydrochloric acid (HCl) is formed
as an additional product. Here is the reaction:
(5) This is one of the preferred methods of extracting gold from di-
lute rock samples. It is also horrendously toxic (NaCN is sodium
cyanide. . . which is as bad as it sounds!)
Since, for each element, we need to have the same number of atoms on
the left as on the right, then we have the following 4 equations in 4 variables:
x1 = 3x3
2x1 + 4x2 = 8x3 + x4
2x1 + 3x2 = 2x4
x2 = 2x3
The matrix equivalent to that system of equations would be
2 3
1 0 3 0 0
6 2 4 8 1 0 7
A=6 4 2 3 0
7
2 0 5
0 1 2 0 0
According to Sage, the RREF is
[ 1 0 0 -1/2 0]
[ 0 1 0 -1/3 0]
[ 0 0 1 -1/6 0]
[ 0 0 0 0 0]
As you can see, we have a row of all zeros. We have a pivot for x1 , x2 ,
and x3 , thus those variables are determined. There is no pivot for x4 , so
that variable is free. The standard form of the infinite set of solutions is
written as follows:
x1 = (1/2)x4
x2 = (1/3)x4
x3 = (1/6)x4
x4 = x4
However, it is customary only to consider integer values for the coef-
ficients of a chemical reactions equation. What do we do when we want
integer-only solutions in a case like this? It is an extremely rare trick, not
commonly taught but easy to learn. First, we take the lcm (least common
multiple) of all the denominators of all the fractions. In this case, the lcm
of {2, 3, 6} is six. Second, we plug in x4 = 6n where n is a new dummy
variable. Now we have
x1 = (1/2)6n = 3n
x2 = (1/3)6n = 2n
x3 = (1/6)6n = n
x4 = 6n
For any integer n, the four values that you would get form an integer
solution to the given equations. This includes nonsense values like n = 0 or
negative values of n. (Or to be precise, the n 0 cases are mathematically
2.4. CHEMISTRY: BALANCING REACTIONS WITH MATRICES 77
valid solutions to the system of equations, but they are not chemically mean-
ingful.) We want the simplest non-zero all-positive solution, so we should
plug in n = 1. Now we have
x1 = 3; x2 = 2; x3 = 1; x4 = 6
giving the final chemical reaction
3 Ca(OH)2 + 2 H3 PO4 ! 1 Ca3 (PO4 )2 + 6 H2 O
but we should note that chemists do not usually write the 1 in front of
the third molecule.
Now we should check our work. As you can see, . . .
. . . we have 3(1)+0 = 3 atoms of calcium on the left, and 1(3)+0 = 3
atoms of calcium on the right.
. . . we have 3(2) + 2(4) = 14 atoms of oxygen on the left, and
1(8) + 6(1) = 14 atoms of oxygen on the right.
. . . we have 3(2) + 2(3) = 12 atoms of hydrogen on the left, and
0 + 6(2) = 12 atoms of hydrogen on the right.
. . . we have 0 + 2(1) = 2 atoms of phosphorous on the left, and
1(2) + 0 = 2 atoms of phosphorous on the right.
All of those are exact matches, therefore we declare success!
print "Question:"
print B
print "Answer:"
print B.rref()
Now we have the output
Question:
[ 8 0 -1 0 0]
[18 0 0 -2 0]
[ 0 2 -2 -1 0]
Answer:
[ 1 0 0 -1/9 0]
[ 0 1 0 -25/18 0]
[ 0 0 1 -8/9 0]
Quickly, we verify that the matrix that we entered was the matrix that
we had desired to enter. Next, we take the lcm of the denominators in the
interesting column. The lcm of {9, 18, 9} is clearly 18. For the first three
coefficients, we multiply the entries in informative column by the negative
lcm (in this case, 18), and obtain 2, 25, and 16. For the fourth coefficient,
it is just the lcm itself, namely 18. We conclude with
2 C8 H18 + 25 O2 ! 16 CO2 + 18 H2 O
Your Challenge:
Now try the first, fourth, and fifth examples on your own. Good luck, and
dont forget to check your work!
2.5. PHYSICS: BALLISTIC PROJECTILES 79
(1) Read the problem very carefully, and write down a sum of forces
equationoften with the aid of a free-body diagram. This, in turn,
produces an acceleration function using F = ma.
(2) Integrate the acceleration function to get the velocity function,
which unfortunately will have a +C.
(3) Use some information from the problem to compute the value of C.
(4) Integrate the velocity function to get the altitude function, which
unfortunately will have a (probably dierent) +C.
(5) Again, use some information from the problem to compute the
value of C.
(6) Check that your three functions are consistent with all the given
data (by plugging in values) and with each other (by taking deriva-
tives).
Note: At this point, you have all three functions explicitly and can answer
most any inquiry about the projectile.
(7) Reread the question and see what is actually asked for.
F = ma(t)
mg = ma(t)
g = a(t)
a(t) = 9.80665
Third, we know that v(0) is the vertical component of the muzzle veloc-
ity. Thats computed with
and therefore
v(t) = 9.80665t + C
v(0) = 9.80665(0) + C
259.807 = C
Fifth, we plug in the fact that y(0) is the altitude of the hill, or 25 m.
y(t) = 4.90332t2 + 259.807t + C
y(0) = 4.90332(0)2 + 259.807(0) + C
25 = C
Finally, we have
y(t) = 4.90332t2 + 259.807t + 25
and we can begin the most important part of the problem: checking our
work.
We can check that y 0 (t) = 9.80664t + 259.807, which matches our
v(t) except for rounding error.
We can check that y 00 (t) = 9.80664, which matches our a(t) except
for rounding error.
We can check that y 0 (0) = v(0) = 259.807, as desired. (Thats the
vertical component of the muzzle velocity.)
We can check that y(0) = 25, as desired. Thats the altitude of the
artillery pieces muzzle.
Now, we should compute what the question actually wants to know. It
wants to know the range of the projectile (how far it goes) so we have to
calculate the time of flight and multiply that by the horizontal velocity. To
find the time of flight, we just have to find out when the projectile hits
the ground (when flight ends) because flight begins when t = 0. Of course,
when the projectile hits the ground, the altitude is zero. Therefore, we set
y(t) = 0, and use the quadratic formula.
0 = y(t)
0 = 4.90332t2 + 259.807t + 25
p
259.807 (259.807)2 4( 4.90332)(25)
t =
2( 4.90332)
t = 0.0960512 or 53.0820
We check our work with y(53.0820) = 0.0174218 m, a dierence of 17
mm, which is not a problem, but which is obviously mere rounding error.
Next, we need the horizontal velocity
(300)(sin 30 ) = (300)(1/2) = 150
and finally the range of the projectile is
(150)(53.0820) = 7962.30
Since a mile is 1609 meters, a range of 7962.30 m seems plausible. After
all, the purpose of artillery is to strike targets several miles away. We should
realize, however, that our altitude of the hill being 25 m is a measurement
accurate probably to the nearest meter or half meter, and not to six signifi-
cant digits. The muzzle velocity is probably also only known to the nearest
82 2. FUN PROJECTS USING SAGE
computation can be very high. The general concept we are discussing here
is called numerical simulation.
we learn that
100! = (2)97 (3)48 (5)24 (7)16 (11)9 (13)7 (17)5 (19)5 (23)4 (29)3 (31)3 (37)2
(41)2 (43)2 (47)2 (53)(59)(61)(67)(71)(73)(79)(83)(89)(97)
Therefore, you can see that 298 , 349 , and 525 will not divide 100!. How-
ever, though those three numbers are all 6-smooth, so they are surely 100-
smooth. So we have now located three examples of 100-smooth numbers
that do not divide 100!.
In fact, weve now demonstrated that requiring numbers to be divisors
of 100! is a stricter standard than requiring them to be 100-smooth. In
general, the set of numbers dividing B! is a subset of the numbers that
are B-smooth. Overall though, if you consider numbers less than B!, the
exceptions are few and far between, and the concepts are roughly equivalent.
2.6. CRYPTOLOGY: POLLARDS p 1 ATTACK ON RSA 87
2(10,000!) mod N
Having come to realize that 10, 000! is a number that has 36,660 dig-
its (approximately) we probably should not compute it and then ask for
2(10,000!) . That might take a very long time to compute. We have to find a
dierent approach.
2.6. CRYPTOLOGY: POLLARDS p 1 ATTACK ON RSA 89
Consider computing
c1 = 21 mod N
c2 = (c1 )2 mod N
c3 = (c2 )3 mod N
4
c4 = (c3 ) mod N
5
c5 = (c4 ) mod N
6
c6 = (c5 ) mod N
.. .. ..
. . .
Then we would have
c6 (c5 )6 ((c4 )5 )6 (((c3 )4 )5 )6 ((((c2 )3 )4 )5 )6 (((((c1 )2 )3 )4 )5 )6 2(1)(2)(3)(4)(5)(6)
but observe, thats just what we wanted to compute, namely
2(1)(2)(3)(4)(5)(6) 2(6!)
In a similar manner, we can see that cB 2(B!) mod N .
is a very smooth number, with 200 primes in its prime factorization (counting
multiplicities) and none contribute more than a paltry 5 to final, enormous,
product. What is the opposite extreme to this?
The other extreme would be a prime number. There is only one prime
factor, and it makes all the contribution to the magnitude by itself. Of
course, p and q are odd and thus neither p 1 nor q 1 can be prime.
However, they could be 2 times some prime number. Prime numbers p where
both p and (p 1)/2 are prime simultaneously are called safe primes. The
almost identical notion, where both p and 2p+1 are prime, are called Sophie
Germain primes, named for Marie-Sophie Germain (17761831).
To make Pollards attack totally infeasible, many RSA implementations
require both primes to be safe primes. For these numbers, B would have
to be (p 1)/2 or greater. Even if p is only 200 bits long, which is far
too small, then (p 1)/2 will be 199 bits long, and that would make it
computationally infeasible to compute 2B! . The sun would run out of fuel,
turning into a red giant5 long before such a computation could terminate.
Advanced Plotting
Techniques
One of the most enjoyable uses of Sage is to produce colorful graphic images,
whether for teaching or for publication. Sage has an enormous variety of
plotting and graphing utilities. The basics of plotting were first introduced
in Section 1.4 on Page 8. If you havent read that yet, youll want to go
read that now. Almost everything else you would want to plot is covered
here in this chapter. The exception are certainly highly colorful or 3D
plots which can only appear on a computer screen and not in a printed
book. Those plots are discussed in the electronic-only online appendix to this
book Plotting in Color, in 3D, and Animations, available on my webpage
www.gregorybard.com for downloading.
Moreover, because scatter plots are essentially only used while making
regressions, the technique for scatter plots is discussed in Section 4.9 on
Page 157, for simplicity. Similarly, slope field plots are only used (so far as
I am aware) in the study of first-order dierential equations, and therefore
those procedures are discussed in Section 4.22.3 on Page 197 for better
continuity of the exposition.
Plot 1 Plot 2
Plot 3 Plot 4
Plot 5 Plot 6
94 3. ADVANCED PLOTTING TECHNIQUES
Plot 2:
Plot 3:
Plot 4:
Plot 5:
Plot 6:
Last but not least, it is worth mentioning that the text command knows
the mathematical document preparation language LaTeX. If you dont
know LaTeX, then you can type instead
the_words = text( f(x) = x^2 + 1 and tangent line.,
(0.5, -2.75), fontsize=20 )
and have almost the same eect.
The fill command is excellent for working with integrals, even of func-
tions that cross the x-axis. However, for other types of filled plots, such as
graphing systems of inequalities, other techniques are far more flexible and
correct. That will be covered in the electronic-only online appendix to this
book Plotting in Color, in 3D, and Animations, available on my webpage
www.gregorybard.com for downloading.
P1 = text($\int_0^2 (-1+\sqrt{x}) \, dx$, (0.5, 0.3),
fontsize=20)
P2 = plot( -1+sqrt(x), 0, 2, fill=True)
P = P1 + P2
P.show()
As you can see from the screen-capture below, Sage knows which way
to shade depending on if the function is positive or negative.
Plot 3: The function f (x) = sin(exp( 2 1 x )) is just the sine of the pre-
vious example. To the right of x = 2, this is like sin(0), and thus there is
almost no oscillation. To the left of x = 2, this is like a sine wave where
the frequency approaches infinity. It is interesting to look at this graph at
various scales.
plot(sin(exp(1/(2-x))), -1, 4)
Plot 4: This function f (x) = sin(10x)
10x is interesting for several reasons.
First, it is visually attractive. Second, it occurs in the study of wavelets,
which is a subject in its own right. Third, many students will cancel the
xs and work with f (x) = sin(10)/10 instead, or perhaps cancel the 10s
as well leaving only f (x) = sin. Fourth, this function comes up in both
mathematical analysis (as well as in signal processing) so frequently that it
is given its own name:
sin(10x)
f (x) = sinc(10x) =
10x
plot(sin(10*x)/x, -2, 2)
Plot 1 Plot 2
Plot 3 Plot 4
r() = 2 cos 5
Plot 1 Plot 2
Plot 3 Plot 4
images. For the image on the left, the plot points option has been used,
and on the right, it was removeddefaulting to only 200.
As you can see, we get a much lower quality image when we plot only
200 points instead of 10,000 points. One way to understand this is to realize
that the domain is 12 < < 2, and thus 200 points is only
For example,
g(x,y)=x^4+y^4-16
x2 + y 5 + 5xy = 25
the explicit form would be even more tedious, if not impossible. The plot,
below, is given by the commands
var("y")
implicit_plot( x^2 + y^5 + 5*x*y == 25, (x,-10,10), (y,-10,10),
gridlines="minor", axes=True)
104 3. ADVANCED PLOTTING TECHNIQUES
As you can see, this plot shows a nice background that looks like graph
paper, using the gridlines option that we first saw in Section 1.4 on Page 8.
The axes=True command is required to show the axes in an implicit plot.
Note that implicit functions in three variables (x, y, and z) are discussed
in the electronic-only online appendix to this book Plotting in Color, in
3D, and Animations, available on my webpage www.gregorybard.com for
downloading.
Backwards Compatibility:
The following syntax makes the plot command look like the implicit plot
commands syntax:
plot( x^2, (x, -2, 2) )
where as we would normally have typed
plot( x^2, -2, 2 )
as in the original plotting section (Section 1.4 on Page 8). This useful for
when you have to plot things in terms of t and not in terms of x. For
example:
var(t)
plot( -16*t^2+400, (t, 0, 3) )
is the height of a bowling ball dropped o of a 400 foot building, t seconds
after release. Here is the plot:
A level set is the set of points (x, y) such that f (x, y) = z for some fixed z.
For example, if
f (x, y) = x2 + y 2
then the following plot shows the level sets for z 2 {25, 50, 75, 100, 125, 150}.
These are the old-fashioned contour plots that would have been found
in textbooks during the 20th century. Modern contour plots use shading,
which usually makes them easier to read, but at an increased cost of ink.
The following code
var(y)
106 3. ADVANCED PLOTTING TECHNIQUES
generates an image for the same function as the previous image, g(x, y) =
x2 y 2 , but in the shaded style.
In these shaded contour plots, the darker regions represent f values that
are smaller, and the lighter regions indicate f values that are larger. By the
way, the plot points option helps Sage figure out how carefully drawn you
want the contour plot to be. I usually use 200 or 300. The default is 100,
which is too small in my opinion.
In all fairness, I must note that sometimes the shading does more harm
than good. The following contour diagram is perfectly readable without
shading.
var("y")
contour_plot( x^4 + (y)^4/2, (x, -10, 10), (y, -10, 10),
fill=False, axes=True )
3.5. CONTOUR PLOTS AND LEVEL SETS 107
On the other hand, if one backspaces over the fill=False and axes
= True commands, the resulting shaded contour plot has a giant black
region occupying the large central portion of the plot, inside the innermost
oval. This renders the graph almost unreadabletry it if you like.
In order to explore the relationships between some three-dimensional
objects and their contour diagrams, I have made an interactive web page
(sometimes called an interact or an applet) to show some complex shapes
both in 3D plots and in contour plots, simultaneously.
but the series variable n runs over all odd positive integers.
Instead, lets define n = 2j + 1. Then as j runs through 0, 1, 2, 3, . . . , n
will run through 1, 3, 5, 7, . . . , producing all odd positive integers. This will
allow us to use Sages sum command. Furthermore, well just let j run from
0 to 100. After all, when j = 101, we will have n = 203, and that term will
2 2
have e 203 in it, which is going to make that term completely negligible.
In reality, we could stop at j = 10 or j = 20 and probably produce the
same graph, but computers do not mind doing a lot of tedious work, so well
compromise at j = 100. Boyce and DiPrima use = 1, and so we will do
the same. Now we have
n=1
80 X 1 (2j+1)2 2 t/2500 (2j + 1)x
u(x, t) = e sin
2j + 1 50
j=1
Since this is a function of two variables, one way we could visualize this
is by half-evaluation. We could plot u(5, t) for 0 < t < 100 and get an
108 3. ADVANCED PLOTTING TECHNIQUES
idea of what the temperature is like over time, 5 cm from one end of the
rod. To do this, we would type
var("j t")
As you can see, a color bar or grayscale legend has been attached to
tell us what the various shades of gray indicate, in terms of degrees Celsius.
That is quite useful here in thermodynamics, but it would not necessarily
have been relevant in the pure mathematics examples that we saw earlier in
this section.
Last but not least, the aspect ratio option needs to be explained.
When plotting geometric objects, such as the two-variable functions that
110 3. ADVANCED PLOTTING TECHNIQUES
we saw moments ago, it is important that the same scale be used on the
x-axis and the y-axis. Otherwise the angles will be o and other distortions
will occur. If we were to remove the aspect ratio=0.1 option, Sage would
observe that we are plotting 300 in one variable, and 50 in another vari-
able. Therefore, the graph would be six times narrower than it is tall, to
maintain the same scale. The best way to see this is to backspace over the
aspect ratio=0.1 option, and hit evaluate. Instead, with the option, the
50 on the x-axis is interpreted as 500, and we obtain a graph that is 1.6 times
wider than it is tall. That is a graph much easier to read. We should not
feel bad about making this change, because 50 cm and 300 s are in totally
dierent units, and thus the notion of the same scale is meaningless.
which was derived from hypothetical data for a small business that produces
concrete pipes. The model was found in Linear and Non-Linear Program-
ming with Maple: An Interactive, Applications-Based Approach by Paul
Fishback, published by CRC Press in 2010. The function appears in sev-
eral places throughout the book, but is derived from data as the primary
example of Section 7.3.5, Non-Linear Regression.
Using the code:
var("y")
contour_plot( 1400*x^0.51*y^0.32, (x, 0, 160), (y, 0, 160),
plot_points=300)
we get the following shaded contour plot, which is moderately informative.
var("y t")
f(t) = sin(2*t)
g(t) = sin(3*t)
The phenomenon that we saw with polar coordinates on Page 101, where
we had too few points per radian, can also occur in parametric equations.
Consider changing the domain to 100 < t < 100 in the previous example,
taking care to keep y = cos(2t). To be explicit, that means change (t,
0, 2*pi) into (t, -100, 100). The resulting output is extremely poor,
because the points are far apart. Since the domain is length 200 in units
of t, and the default number of points plotted is 200, each point used to
construct the plot is 1 unit of t apart. When we had the interval being of
length 2, the points are /100 0.0314159 units of t apart, rather a large
dierence.
level classes. If the reader would like to learn more, I recommend Ch. 9.2
and Ch. 9.3 in Soo Tans Calculus with Early Transcendentals, 1st Edition,
published by Cengage in 2011.
Just as f~(x, y) returns a vector for each point (x, y), we have (at a bunch
of points in the coordinate plane) an arrow, representing some vector. The
direction is very faithfully reproduced, and the length of the arrow is a rough
representation of the magnitude of that vector.
3.7. VECTOR FIELD PLOTS 115
How can we interpret such plots? One way is that if a small object were
placed in the coordinate plane, at each instant of time, it would move in the
direction pointed to by the arrow under the object. The only assumptions
are that the mass and radius of the object be tiny. Another interpretation
involves gradients, which we will now explore.
As you can see, thats the same vector-valued function which we just
plotted. If we wanted to visualize g(x, y) as the z-coordinate of (x, y) we
could cause a 3D-plot using
g(x,y) = sin(y) - cos(x)
As you can see, we get a patterned object not unlike an egg carton.
Now look at the vector field plot again. There are some spots where a
bunch of arrows are all pointing to the same point. If you put a marble in
the neighborhood of that point, it would be drawn toward that point, and
stay there. Those are points where rg is the zero-vector, and corresponds
116 3. ADVANCED PLOTTING TECHNIQUES
to a local minimum of the egg carton. There are also spots where a bunch of
arrows are all pointing away from a particular point. If you put a marble in
the neighborhood of that point, it would be repelled away from that point
and not return. Those are points where rg is also the zero-vector, but they
correspond to a local maximum of the egg carton. An applied mathematician
or physicist would say that these are attractive and repulsive equilibrium
points, for the local minimum and local maximum cases, respectively.
How can you distinguish between those local minima and maxima? Well,
you could have Sage generate a vector field plot and make the identification
visually. Or, you could consider the Hessian matrix (in this case a 2 2
matrix of second partial derivatives), and then compute the determinant of
that matrix. Clearly, one task is considerably more difficult than the other.
x1= 0
y1= 0
x2= 2
y2= 0
q0= -1
q1= 2
q2= 1
f1 = - q0*q1*r_vec_1 / r_vec_1.norm()^3
f2 = - q0*q2*r_vec_2 / r_vec_2.norm()^3
net_f = f1 + f2
Third, we define two vectors. The vector r vec 1 goes from (x, y) to
(x1 , y1 ). Likewise, the vector r vec 2 goes from (x, y) to (x2 , y2 ). Whenever
you have to define a vector, whether in Sage or in any other mathematical
situation, it is convenient to remember the trick head minus tail. If you
visualize r vec 1 as an arrow, then the arrowhead would be at (x1 , y1 ), and
the tail feathers would be at (x, y).
Fourth, we define the charges of the mobile charge, Charge 1 and Char-
ge 2 as q0, q1, and q2. Fifth, we apply Coulombs law. For the force between
Charge 1 and the mobile charge, we compute f1 and likewise f2. As you can
see, I dropped all the constants, because they wont aect1 the directions
of the vectors. Sixth, net f is the sum of those two forces, giving the total
force on the mobile charge. Note that we had no need of computing the force
of Charge 1 upon Charge 2, nor the equal and opposite force of Charge 2
upon Charge 1, because they arent relevant to the mobile charge. Last but
not least, we use the plot vector field command, to plot the vector field
for 0.1 x 1.9 and 2 y 2.
Whats actually happening here is that when (x, y) gets too close to
one of the charges, the distance gets very small. That means that the
denominator, which is cubed, gets extremely tiny. That makes the force
absolutely huge. The vector then becomes so long that it ends up taking up
1It was also for this reason that we never bothered with units in this problemthe
units will not aect the directions of the vectors.
3.7. VECTOR FIELD PLOTS 119
far more space in the plot than it should, and creates this visually misleading
result. In a Sage vector field plot, the tail of the arrow represents the location
which the arrow is describing. However, the eye seems to imagine that the
arrowhead represents that location. Normally, this wont come up often.
Mathematically speaking, (0, 0) and (2, 0) are the poles of the total force
function, because the function divides by zero there. In general, you will
get a much better vector field plot if you exclude the poles from the region
being graphed.
A Challenge:
You are now ready to attempt the mini-project on Electric Field Vector
Plots, which is given on Page 90.
@f @f
rf (x, y) =< , >=< sin(x), 2 cos(y) >
@x @y
We will draw the contour plot of f (x, y), as well as the vector field plot
of the gradient, rf (x, y), but superimposed on the same image. The code
that we use is as follows:
f(x,y) = cos(x)-2*sin(y)
gradient = derivative( f )
show( P1 + P2 )
Here we can see what is like a collection of hills and valleys (the contour
plot), almost in the style of geological contour maps used by geologists and
boy scouts. The arrows, representing the gradient, represent the direction
of movement that a drop of rain would take, moving from higher altitude to
lower altitude. We can clearly see where the flooding would be in a major
rainstorm. Last but not least, we can definitely see that the gradient vector
is always perpendicular to the level-set curves (the curves that comprise the
contour plot.)
For more information about scatter plot see Section 4.9 on Page 157.
Since this transformation of ordinary two-dimensional space (namely R2 )
into the log-log plane was so useful, you might be curious if there is an
analogy for three dimensional space (namely R3 ). There is, and it is called
log-log-log space. This comes up in the derivation of Cobb-Douglas style
formulas in macroeconomics. In general, those equations are of the form
P = cK a Lb
122 3. ADVANCED PLOTTING TECHNIQUES
Lets take a brief moment to verify that last one, by cubing it carefully.
p 3 p p 2
1 i 3 = 1 i 3 1 i 3
p p
= 1 i 3 1 + 2i 3 + i2 3
p p
= 1 i 3 1 + 2i 3 3
p p
= 1 i 3 2 + 2i 3
p p p p
= ( 1)( 2) + ( 1)(2i 3) + ( i 3)( 2) + ( i 3)(2i 3)
p p
= 2 2i 3 + 2i 3 2i2 (3)
= 2 (2)( 1)(3)
= 2+6=8
However, of these three, the first is realnormally thats the one we want
(at least, usually.) Similarly, if I ask for the cube root of -8, there are three
numbers z in the complex plane such that z 3 = 8. Specifically, they are
z = 2 cos(0 ) i2 sin(0 ) = 2 0i = 2
p
z = 2 cos(120 ) i2 sin(120 ) = 1 i 3
p
z = 2 cos(240 ) i2 sin(240 ) = 1 + i 3
n p p o
2, 1 i 3, 1 + i 3
and as you can see, it is just the previous set times 1. Again, of these
three solutions, the first is real, and normally thats the one we want (at
least, usually.) Now it is noteworthy that I can get all three solutions with
the following command
solve( x^3 == 8, x )
print -8^(1/3)
then youll only get a graph showing 0 < x < 2, along with the error message
because Sage is returning the complex roots (which are not visible on the real
plane) for the x < 0 values. As you can see, Sage is explicitly reprimanding
you for raising a negative number to a fractional power.
The graph is given below:
124 3. ADVANCED PLOTTING TECHNIQUES
An alternative is to use
plot( sign(x) * (abs(x)^(1/3) ), -1, 1)
which is a lot easier to explain. The absolute value, computed by abs
will guarantee that the input to the one-third power is positive. However,
3.9. RARE SITUATIONS 125
negative x-values should have negative cube roots, and positive x-values
should have positive cube roots. Therefore, we multiply by sign(x). The
function sign(x) will return 1 for any negative x and +1 for any positive
x, but it will return 0 for x = 0. By multiplying by sign(x) we guarantee
that the computed cube root will have the correct sign. You can see a graph
of the sign(x) function below:
Half-Evaluating a Function:
Consider the following code:
var(y)
f(x,y) = (x^4 - 5*x^2 + 4 + y^2)^2
print f(x,y)
print f(x=1)
print f(y=2)
That code produces the following output:
(x^4 - 5*x^2 + y^2 + 4)^2
y^4
(x^4 - 5*x^2 + 8)^2
The first line is the actual function f (x, y) as we had defined it earlier.
The second line is what happens if x is locked at x = 1. In that case, we get
a function of y alone, and it is a rather simple function. The third line is
what happens if y is locked at y = 2. As you might guess, we get a function
of x alone. This process of locking one or more of the variables of a function,
while leaving one or more of the variables of a function free, is called half
evaluation.
If youre saving for retirement, and want to deposit $ 100 per biweekly
paycheck for 40 years, and invest at the rate of 9.1% compounded bimonthly.
Since there are 52 weeks per year, the biweekly paychecks will come 26 times
per year and m = 26. Then we have t = 40, r = 0.091, i = 0.0035, n = 1040,
and c = 100. The correct formula in this case is the future value of an
annuity or the increasing annuity formula and is given by
(1 + i)n 1 (1 + r/m)mt 1
FV = c =c
i r/m
which we can evaluate with
(100)*( (1 + 0.0035)^1040 - 1 ) / 0.0035
obtaining the rather lovely sum of $ 1,052,872.11.
Last but not least, if you want to get a 30-year home mortgage, at
the rate of 5.4% compounded monthly, making house payments of $ 900
per month, then you would have t = 30, m = 12, n = 360, r = 0.054,
i = r/m = 0.054/12 = 0.0045, and c = 900. The correct formula for this
problem is the present value of an annuity or the decreasing annuity
formula and is given by
1 (1 + i)n 1 (1 + r/m)mt
PV = c =c
i r/m
which we can evaluate with
(900)*( 1 - (1 + 0.0045)^(-360) ) / 0.0045
obtaining the result of $ 160,276.16. Depending on where you live, that can
be a very nice townhouse. For example, if you find a nice place with an
asking price of $ 178,084.62, then putting 10% down would imply a down
payment of $ 17,808.46, leaving $ 160,276.16 for the bank to provide via this
mortgage.
if a customer came to you and asked how much the monthly payment would
be for a $ 180,000 house, youd be able to plug 180,000 into the P V equation
above, plug in n = 360 and i = 0.0045, and just solve for c. However, the
lowest layer of bank employees are unable to do that. Instead they will look
up the CPT on the rate sheet, find that it is 5.6153079187, and just compute
(180)(5.6153079187) = 1010.75
enabling them to tell the customer that $ 1010.75 is going to be their monthly
house payment with that mortgage.
Meanwhile, the rate sheet has to come from somewhere. A midlevel
bank employee would compute the CPT while generating the rate sheet
by taking
1 (1 + i)n
PV = c
i
solving for c and obtaining
(P V )(i)
c=
1 (1 + i)n
where one can plug in the i and n values. Naturally, P V = 1000. Lets
compute this now with Sage.
Since c = 1000 is not going to change, we can put as the first line
c=1000
and then, we could define our own function by typing
CostPerThousand(i, n) = ( c * i ) / (1 - (1+i)^(-n) )
as our second line. Note, our setting c = 1000 here is not unlike how we had
set k = 355/113 on Page 32.
Keeping those two lines in there, we can use the function repeatedly as
our third line. For example, for a 30-year mortgage at 6.5% compounded
monthly, we can type as our third line
CostPerThousand( 0.065/12, 30*12 )
and then if the rate rises to 7% we can replace that line with
CostPerThousand( 0.07/12, 30*12 )
and so on, and so forth.
Notice that the function name has to be only one word, but by varying
the capitalization that way (which programmers call Camel Case), we
could express an idea that was more than one word. Surely it is much easier
to read CostPerThousand than costperthousand or COSTPERTHOUSAND.
While this function is nice, (for example it will save us from agonizing
each time over the placement of the parentheses,) it also isnt quite perfect.
Our data will be given in terms of the number of years of the loan t, not the
number of payments n = mt = 12t. Likewise, the rate will be the nominal,
published rate r not the per-period rate i = r/m = r/12. One student once
described this to me by saying that the n and i are math-friendly, whereas
the t and r are human-friendly.
132 4. ADVANCED FEATURES OF SAGE
g(x, y) = xy + sin(x2 ) + e x
4.3.2. Gradients
The next question we might be asked is to find the gradient of a multivariate
function. If you want rf then you type
g(x,y) = x*y + sin(x^2) + e^(-x)
g.derivative()
and Sage will correctly calculate the gradient. Alternatively, you can type
diff(g) in place of g.derivative(). In either case, Sage displays
(x, y) |--> (2*x*cos(x^2) + y - e^(-x), x)
which is to remind you that this is a map from a point (x, y) to a pair of
real numbers, and not an ordinary function. Interestingly, the gradient of a
univariate function such as f (x) = 2e x , done this way, is just the ordinary
first derivativewhich is exactly correct according to the laws of calculus.
and also consider ~b =< 24, 63, 52 > as well as ~c =< 10, 14, 8 >.
Note, that some books prefer to write ~b =< 24, 63, 52 > for a vector,
and B = (24, 63, 52) for a point in space. This distinction is an excellent
oneuseful to students and faculty alikeand mathematics books should
use it. However, this notation is also a recent innovation, and might be
unfamiliar to many readers who are accustomed to seeing parentheses used
for both points and vectors.
Because Sage already uses the symbols < and > for comparisons, namely
less than and greater than, it is unfortunately necessary that Sage (like
all but the most recent textbooks) cannot use the new notation. This is
unavoidable. However, the vector command removes all confusion, as you
will see momentarily.
136 4. ADVANCED FEATURES OF SAGE
a notion of the square root of a matrix, but it is rarely used and we will
not go into it here.
M = A.augment(b)
138 4. ADVANCED FEATURES OF SAGE
print "Before:"
print M
print
print "After:"
print M.rref()
Of course, the print commands arent really necessary but they are
very informative to the user. Some mathematicians will use the backslash
operator or the solve right command. However, this augment-and-RREF
strategy does have its advantages.
Consider changing the last entry in A, namely A33 to 9 instead of 1.
Then run our augment-and-RREF code again.
We see the following output
Before:
[ 1 2 3 24]
[ 4 5 6 63]
[ 7 8 9 52]
After:
[ 1 0 -1 0]
[ 0 1 2 0]
[ 0 0 0 1]
This is extremely informative. From the row of zeros followed by a 1, we
see that the original system of equations has no solution. We can also see
that the first and second column are eective, or elementary vectors, while
the third column is defective, or a non-elementary vector. If you know what
rank means in linear algebra, we can see that the matrix has rank 2. If
you dont know what that means, do not worry about it right now. Lets
see what would happen if we were to put the same question to the backslash
operator.
If we were to type
A = matrix( 3, 3, [1, 2, 3, 4, 5, 6, 7, 8, 9] )
A \ b
we would get the response:
ValueError: matrix equation has no solutions
which is undeniably true but not as informative as the augment-and-RREF
strategy.
What happens if you use the backslash when there are infinitely many
solutions? Lets try it and find out! The commands:
A = matrix( 3, 3, [1, 2, 3, 4, 5, 6, 7, 8, 9] )
4.4. MATRICES IN SAGE, PART TWO 139
A \ d
produce the vector < 0, 3, 0 >, which is a perfectly valid solution. On the
basis of this output we would be justified in assuming that this is the unique
solution to that problem. However, we can also see that < 1, 1, 1 > is a
solution. When there are infinitely many solutions, the backslash operator
simply picks one. In particular, it will pick the solution formed by making
all the free variables equal to zero.
We could instead type
A = matrix( 3, 3, [1, 2, 3, 4, 5, 6, 7, 8, 9] )
B = A.augment(d)
B.rref()
to get the output
[ 1 0 -1 0]
[ 0 1 2 3]
[ 0 0 0 0]
which, if you know how to read it, is much more informative. The circum-
stance of having an infinite number of solutions to a linear system (in other
words, having a free variable) is discussed in Section D on Page 309.
Last but not least, we must recall that A.rref() is asking for a reduced
row-echelon form. However, there is also the row-echelon form or REF.
This half-completed version of the RREF is extremely useful to know about
if you have to work with matrices by hand, but in the computer age, its
role is secondary at best. The command to compute the REF instead of the
RREF is simply
A.echelon_form()
You can verify the correctness of the inverse by asking for A*B or alter-
natively B*A, both of which will return the identity matrix. You can also
replace A.inverse() with A 1 , as below:
A = matrix( 3, 3, [1, 2, 3, 4, 5, 6, 7, 8, -1] )
B = A^(-1)
print B
You might be wondering what happens if you invert a singular matrix?
We can simply change the 1 in the lower right-hand corner of the matrix
into a 9. Then the matrix is singular. We get an error message consisting
of a lot of garbage, followed by
ZeroDivisionError: input matrix must be nonsingular
Sometimes it is useful to compute the inverse of a matrix the long way.
To accomplish this, we attach an identity matrix of the appropriate size, to
the right of the original matrix. For example, the code
A = matrix( 3, 3, [1, 2, 3, 4, 5, 6, 7, 8, 9] )
B = identity_matrix(3)
C = A.augment(B)
print "Before:"
print C
print "After:"
print C.rref()
produces the output below.
Before:
[1 2 3 1 0 0]
[4 5 6 0 1 0]
[7 8 9 0 0 1]
After:
[ 1 0 -1 0 -8/3 5/3]
[ 0 1 2 0 7/3 -4/3]
[ 0 0 0 1 -2 1]
As you can see, the matrix is not invertible. The RREF-process got
stuck in the third column. This is much more informative than the error
message we would get if we tried to just invert A with A.inverse().
A = matrix( 2, 2, [-2, 7, 0, 0] )
print A.left_kernel()
print "Test:"
print vector([0, 1])*A
print A*vector([0, 1])
produces the output:
Free module of degree 2 and rank 1 over Integer Ring
Echelon basis matrix:
[0 1]
Test:
(0, 0)
(7, 0)
It is noteworthy that our test code verifies that ~v A = ~0, as desired, but
A~v 6= ~0, as it turns out. This is to emphasize that the left kernel and right
kernel are not the same sets.
Id now like to explain the first two lines of the output above. As well
see throughout these examples, the degree 2 part refers to the dimension
of the vectors in the kernel. The rank is the dimension of the space which
gets sent to zerothis is usually called the nullity of A, but one should
take care to dierentiate between left nullity and right nullity. It is
important to emphasize that the rank of the left kernel, the rank of the
right kernel, and the rank of A itself, can all be dierent.
For example, the matrix
1 2 3 4 5
6 7 8 9 0
has rank 2, but its left kernel is rank 0 (just the zero vector) and its right
kernel is rank 3. You can find these numbers immediately with the functions
A.right nullity(), A.left nullity(), and A.rank(), for any matrix A.
Meanwhile, the equivalent code using right kernel would be as follows:
A = matrix( 2, 2, [-2, 7, 0, 0] )
print A.right_kernel()
print "Test:"
print vector([7, 2])*A
print A*vector([7, 2])
which produces the output
Free module of degree 2 and rank 1 over Integer Ring
Echelon basis matrix:
[7 2]
Test:
142 4. ADVANCED FEATURES OF SAGE
(-14, 49)
(0, 0)
Again, we see that A~v = ~0, as desired, but that ~v A 6= ~0. For sure, the
left kernel and right kernel are distinct mathematical objects. Sometimes
the right kernel is called the null space of A. For that reason, if one
says the kernel of A in mathematics, they usually mean the right kernel.
However, in Sage, A.kernel() refers to the left kernel, which is extremely
unusual. The wise programmer will be explicit and use A.right kernel()
and A.left kernel() so that there can be no possible confusion.
By the way, I was discussing this once with Prof. William Stein, and
he specifically asked me to mention in the book that real programmers
always check the documentation. No one actually remembers fine details
like the distinction between the left kernel and the right kernel. Even if you
are confident that you remember which is which, it is better to check anyway
(using the techniques of Section 1.10 on Page 47) to avoid the possibility of
being mistaken.
To show how the concept works more powerfully, I wrote a program for
you. See Figure 1 on Page 143. Here you see a larger matrix and we compute
the left kernel and right kernel very carefully. You can also see that if ~a and
~b are in the kernel, then r1~a + r2~b will also be in the kernel, for any real
numbers r1 and r2 that you might want to choose.
4.4.6. Determinants
Lets return briefly to the matrix that we opened this lesson with. If we
wanted to know its determinant, all we would need to do is type is the
following:
A = matrix( 3, 3, [1, 2, 3, 4, 5, 6, 7, 8, -1] )
det(A)
4.4. MATRICES IN SAGE, PART TWO 143
Nullspace: Nullspace:
Free module of degree 4 and rank 2 over Integer Ring Free module of degree 4 and rank 2 over Integer Ring
Echelon basis matrix: Echelon basis matrix:
[ 1 1 1 -1] [ 1 1 -1 3]
[ 0 3 0 -1] [ 0 3 -2 3]
Tests: Tests:
(1, 1, 1, -1) maps to (0, 0, 0, 0) (1, 1, -1, 3) maps to (0, 0, 0, 0)
(0, 3, 0, -1) maps to (0, 0, 0, 0) (0, 3, -2, 3) maps to (0, 0, 0, 0)
(1, 4, 1, -2) maps to (0, 0, 0, 0) (1, 4, -3, 6) maps to (0, 0, 0, 0)
(1, -5, 1, 1) maps to (0, 0, 0, 0) (1, -5, 3, -3) maps to (0, 0, 0, 0)
(17, 158, 17, -64) maps to (0, 0, 0, 0) (17, 158, -111, 192) maps to (0, 0, 0, 0)
(71, 2735, 71, -959) maps to (0, 0, 0, 0) (71, 2735, -1847, 2877) maps to (0, 0, 0, 0)
Figure 1. The very large example for the left kernel and
right kernel commands.
when we tried system solving with that same vector, but after changing the
1 into a 9.
The cases of infinitely many solutions and no solutions, can and will
occur only with determinant equal to zero. The case of a unique solution is
what occurs if and only if the determinant is non-zero.
dotproduct = a.dot_product(b)
myfraction = dotproduct / ( norm(a) * norm(b) )
theta = arccos(myfraction)
4.6. WORKING WITH THE INTEGERS AND NUMBER THEORY 145
print f(10^6)
print nth_prime(10^6)
print f(10^7)
print nth_prime(10^7)
That code produces produces the output
1.56115269304996e7
15485863
1.82134480855829e8
179424673
and after adjusting for the scientific notation, we can see that the estimate
and reality are within about 1% of each other.
148 4. ADVANCED FEATURES OF SAGE
and then you learn that the answer is 4. It is called euler phi because
it was discovered by Leonhard Euler (17071783), who also discovered the
number
e 2.718281828
and many other mathematical concepts. He still holds the record for the
largest number of published papers by a mathematician, even though hes
been dead for more than 230 years.
A Fun Challenge:
As it comes to pass, if p and q are distinct prime numbers, the value of (pq)
is very easy to calculate. However, Im not going to tell you what the formula
is. I think it would be great fun for you to just try a bunch of numbers of
the form pq and see if you can discover the formula for yourselfit isnt too
hard. Just remember that distinct primes implies p 6= q.
sigma is the Greek letter equivalent to our s, and sum begins with s.
However, there is no s in tau nor in count. Likewise, both tau and
count have a t, but sum and sigma have no t. Keep in mind,
(n) sums the divisors, while (n) counts the divisors.
Sometimes in number theory, we want to calculate the sums of the
squares or cubes of the divisors. Consider that 45 has as its divisors
divisors(45) = {1, 3, 5, 9, 15, 45}
so we have sigma totaling to 78, because
1 + 3 + 5 + 9 + 15 + 45 = 78
Accordingly, the sum of squares would be
12 + 32 + 52 + 92 + 152 + 452 = 2366
and with cubes
13 + 33 + 53 + 93 + 153 + 453 = 95, 382
but in Sage the commands for that are sigma( 45, 2 ) for squares and
sigma( 45, 3 ) for cubes.
Likewise, sigma( 45, 1 ) is the same as sigma. There are two ways
to compute in Sage. One way is given by sigma(3600, 0) which just
tabulates 1 for each divisor. In other words, each divisor is raised to the 0th
power, and thus becomes 1. Then, if you add up all those 1s, you learn how
many divisors there are.
Another way to compute (250) would be to type
len( divisors( 250 ) )
which returns the length of the list of the divisors of 250well, thats exactly
what means. The len keyword in Python will return the length of any
list, regardless of the type of problem being attempted.
which sum up to
1 + 2 + 4 + 71 + 142 = 220
Therefore we see 220 and 284 are intimately related. The technical term
is that 220 and 284 are an amicable pair of integers. The Arabs found
this so moving that they inscribed these numbers on jewelry that they would
give to their spouses, signifying an intimate relationship. These are called
Amicable Pairs220 representing the young lady, and 284 representing the
young gentleman.
Observe that we omitted n when summing the divisors of n in this case.
You can find this in Sage via
sigma( 220 )-220
and
sigma( 284 )-284
Two other examples of amicable pairs are 1184 and 1210, as well as 2620
and 2924.
[1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 30, 36,
40, 45, 48, 50, 60, 72, 75, 80, 90, 100, 120, 144, 150, 180, 200,
225, 240, 300, 360, 400, 450, 600, 720, 900, 1200, 1800, 3600]
For the Mayan system (base 20), we have a shorter list, obtained with
divisors(400).
[1, 2, 4, 5, 8, 10, 16, 20, 25, 40, 50, 80, 100, 200, 400]
As you can see, for each base, we now know how many admissible de-
nominators exist.
Base 2, there are 3 denominators. (Excluding 1, there are only 2.)
Base 10, there are 9 denominators. (Excluding 1, there are only 8.)
Base 20, there are 15 denominators. (Excluding 1, there are 14.)
Base 60, there are 45 denominators. (Excluding 1, there are 44.)
Note: What we are really doing is computing (n2 ).
As you can see, the Babylonian system is most convenient for simple
division of products, livestock, and money during trade. Not only are there
44 ways to write fractions, exactly, using two symbols past the units place,
but the list begins with
{1, 2, 3, 4, 5, 6, 8, 9, 10, 12, . . .}
namely every possible denominator up to and including 12 with the excep-
tion of 7 and 11. Perhaps it is unsurprising that we use base 60 for angles
in geometry and trigonometry as a result, as well as dividing hours into
minutes and seconds.
x x!
binomial(x,m) This is written m or m!(x m)! or x Cm
x!
binomial(x,m) * m! This is usually written m! or x Pm
x 2
lim
x!0 x 3
you should type
limit( (x-2)/(x-3), x=0)
to learn that the answer is 2/3, which is perhaps obvious. Perhaps less
obvious would be the limit
x2 4x + 3
lim
x!1 x2 3x + 2
for which you should type
limit( (x^2-4*x+3)/(x^2-3*x+2), x=1)
to obtain the answer 2. If you do not know how to do that without a
computer or calculator (in other words, only with pen and pencil), then let
me suggest that you try factoring those two polynomials as a first step.
Last but not least, if you wanted to verify the strange and amazing fact
2 1
lim (cos x)1/x = p
x!0 e
then you should type
limit( cos(x)^(1/x^2), x=0)
to obtain the desired (but very surprising) answer
e^(-1/2)
To show that the last limit there, given in terms of cosine and x2 is true,
you could try values like x = 0.001 on any scientific calculator, or with Sage.
But to prove the limit true is rather difficult. It requires two applications of
LH
opitals Rule or a Taylor Series (but not both), so far as I am aware.
Infinite Limits:
Sometimes limits go to infinity. For example,
1 1 1
lim = lim = lim =1
x!0+ x2 x!0 x2 x!0 x2
is the classic example in most calculus textbooks. However, if we were to
put 1/x3 in place of 1/x2 in those limits, then wed have a problem.
If we approach 0 from the positive numbers, the limit for 1/x3 would
be +1, but if we approach 0 from the negative numbers, the limit for 1/x3
would be 1. Therefore, the limit does not exist if we approach 0 in general.
To see how Sage handles this, consider the following code:
4.9. SCATTER PLOTS IN SAGE 157
Notice how the data, namely those five points, are separated by commas
and enclosed by brackets? This is an example of a list in Sage. You can
enclose any data with [ and ], and separate the entries with commas, to
make a list. This is notation that Sage inherited from the computer language
called Python.
Now we can easily make a scatter plot, by just typing
scatter_plot( datapoints )
which will produce for us the scatter plot shown below on the left. However,
it is important that the list with the data points remain inside of the Sage
Cell server on your screen. So throughout this section and the next, youll
need that list of data points to be inside the box where you normally type
commands.
Perhaps you have the custom of computing best fit lines in a spread-
sheet tool, or in a statistical package. If so, thats great. If not, then
Sage will be very able to do this for you. Well explain how to do that
in the next section. Meanwhile, the actual best fit line for this example is
y = 7.1 2.015x, and the scatter plot on the right includes this line. As you
can see, it is a rather good fit, but an imperfect fit. That plot with the line
included was created by typing
scatter_plot( datapoints ) + plot( 7.1-2.015*x, 0, 4 )
By the way, if youre curious how Sage came up with 7.1 and 2.015,
that is discussed on Page 4.16.4. Now lets consider another data set. This
example will explain to you why we are bothering to make a plot at all,
when there are so many tools out there, including Sage, to give us the line
of best fit whenever we want one. First, enter the data
otherdata = [ (-3, 10), (-2, 5), (-1, 2), (0, 1), (1, 2),
(2, 5), (3, 10) ]
and note that cut and paste usually works rather well if you dont want
to retype the above list. Imagine that this is some data from a scientific
experiment, and that you lab partner has copied the data and has found
the line of best fit, y = 0x + 5 using some sort of statistics package, but
4.9. SCATTER PLOTS IN SAGE 159
has not created a scatter plot. You, of course, are mindful of scientific best
practices, and therefore you type
scatter_plot(otherdata)
to obtain the plot below on the left. Then you can add in the line of best
fit, and you get the plot on the right in Figure 4.9.
As you can see, this is absurd. The data is clearly an ordinary parabola.
Therefore, a line is a terrible approximation for this data. However, of all the
lines that could ever be drawn, even though all of them have unacceptably
high error, there is one line that has the least error. It turns out that this
line of least (squared) error, for this data set, is y = 0x + 5. Furthermore,
it is manifestly clear that this line is a horrible fit, as shown in the plot on
the right. It is for this reason that always plotting the scatter plot with the
best fit line is considered to be a standard operating procedure in most
labs. By the way, the previous plot was produced by the command:
scatter_plot(otherdata) + plot( 0*x+5, -3, 3)
Now is a good time to explain that the object which scientists call the
best fit line is actually better known among mathematicians as a linear
regression. By linear regression, we mean analyzing a set of data to find
the line that best fits the data. Here, we should have done a quadratic
regression which would find the parabola which best fits the data. In a few
pages, well see how to do that.
A Chemistry Example:
Perhaps you might think that the parabola example is quite artificial. Youre
right, I did think it up just to prove a point. However, the following data
shows how a 2 kilogram sample of Cobalt-62 might decay. Here the x-
coordinate is time in minutes, and the y-coordinate is weight in grams.
cobalt_data=[ (0, 2000), (0.75, 1414), (1.5, 1000), (2.25, 707),
(3.00, 500), (3.75, 353), (4.50, 250), (5.25, 177),
(6.00, 125)]
We can type scatter plot(cobalt data) and get the scatter plot:
160 4. ADVANCED FEATURES OF SAGE
non-armadillos. Most functions are not linear, and therefore you should not
assume that your data is best served by a linear model.
scatter_plot(cobalt_data) + plot(1999.96*exp(-0.462162*x), 0, 6)
The plot obtained is the image on the right in Figure 4.9. Last but not
least, one might consider a quadratic regression. Thats a regression of the
form y = ax2 + bx + c, and the command for that would be
var("a b c")
model(x) = a*x^2 + b*x + c
find_fit(cobalt_data, model)
where you can see that the only real change is the middle of the three lines
again, but also we had to declare c as a variable, which we did in the var
command. In any case, the response from Sage is
[a == 62.755170737557854, b == -666.86435772164759,
c == 1925.5757574133333]
While thats clearly not a very bad fit, it is unwise to model radioactive
decay with a quadratic function. This is not only because many of the data
points were missed. The issue can be most easily seen by allowing time
to have the range 0 to 15, instead of 0 to 6. Just change the 6 into a 15 at
the end of the last line we just typed.
We get the following image
4.12. CAN SAGE DO SUDOKU? 163
[5 0 0 0 8 0 0 4 9]
[0 0 0 5 0 0 0 3 0]
[0 6 7 3 0 0 0 0 1]
[1 5 0 0 0 0 0 0 0]
[0 0 0 2 0 8 0 0 0]
[0 0 0 0 0 0 0 1 8]
[7 0 0 0 0 4 1 5 0]
[0 3 0 0 0 2 0 0 0]
[4 9 0 0 5 0 0 0 3]
which has some non-zero entries, but mostly contains zeros to mark where
the blanks would go in an ordinary Sudoku game. Now you can solve the
game by typing
sudoku(A)
and obtain
[5 1 3 6 8 7 2 4 9]
[8 4 9 5 2 1 6 3 7]
[2 6 7 3 4 9 5 8 1]
[1 5 8 4 6 3 9 7 2]
[9 7 4 2 1 8 3 6 5]
[3 2 6 7 9 5 4 1 8]
[7 8 2 9 3 4 1 5 6]
[6 3 5 1 7 2 8 9 4]
[4 9 1 8 5 6 7 2 3]
which is a valid Sudoku solution. However, there might be other solutions.
However, for certain very hard problems, you can spend 10 minutes
on computation, and 2 seconds on transit time, and a 1/4th of a second
on display and the interface. So this feature of Sage is there to help you
measure that.
print answers[0]
print answers[1]
print answers[2]
print answers[3]
Then I might see that answers[2] is the root that I am interested in.
However, how am I going to efficiently typeset
x == (5/9*sqrt(3)*sqrt(2) - 35/27)^(1/3) -
5/9/(5/9*sqrt(3)*sqrt(2) - 35/27)^(1/3) - 2/3
in LATEX for a conference paper or a journal article? Luckily, Sage will
do this for me. The following code:
answers = solve(x^4 + x^3 + x^2 + x - 4, x)
print answers[2]
latex(answers[2])
produces the following output
4.16. MATRICES IN SAGE, PART THREE 167
print "A:"
print A
print
print "I:"
print I
print
print (A-I*x)
print
print det(A-I*x)
print factor(det(A-I*x))
4.16. MATRICES IN SAGE, PART THREE 169
I:
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]
[-x 0 0 -4]
[ 1 -x 0 0]
[ 0 1 -x 5]
[ 0 0 1 -x]
x^4 - 5*x^2 + 4
(x + 2)*(x + 1)*(x - 1)*(x - 2)
By the way, the characteristic polynomial of A has a fascinating rela-
tionship with A. If you type
print A^4 - 5*A^2 + 4
where we have taken the matrix A and treated it as if it were x, we get the
zero matrix backthat will always occur.
print B.eigenvectors_right()
print
b(x) = B.charpoly()
print solve( b(x)==0, x )
That code produces the following output:
[(-0.3722813232690144?, [(1, -0.6861406616345072?)], 1),
(5.372281323269015?, [(1, 2.186140661634508?)], 1)]
[
x == -1/2*sqrt(33) + 5/2,
x == 1/2*sqrt(33) + 5/2
]
We see a sequence of items separated by commas and enclosed in brack-
ets, so we know that we have a list in the syntax of Sage and Python. Each
of the two items in the list is an ordered triple, consisting of the eigenvalue
, and the eigenvector ~v , followed by the multiplicity of the eigenvalue in
the matrixs characteristic polynomial.
Below that is the output of solve where we explicitly found the roots
of the characteristic polynomial. Therefore, we obtain the exact, algebraic
form of the eigenvalues. This is more pleasing to me, because otherwise, we
dont really know what the significance of the numerical values might be.
However, in many applications, the numerical values are all you need. Notice
how Sage reminds you that the eigenvalues are numerical approximations
in the eigenvectors command by use of the ? symbol after the least-
significant digit.
Earlier, I noted that if you plug in the matrix A in place of x inside its
characteristic polynomial then you get the zero matrix back. The charac-
teristic polynomial is usually, but not always, the lowest-degree polynomial
that achieves this phenomenon. However, if the characteristic polynomial
has repeated roots, there is another polynomial which is of lower degree, that
will also send A to the zero matrix. That is the minimum polynomial of
A, and it is found by the command A.minpoly().
might be more that I did not find.) If you have a particular application in
mind that often uses one particular decomposition, factorization, or canon-
ical form, then I hope that you will find it below.
A \ b
Unsurprisingly, Sage responds that there is no solution. I have too many
constraints, and not enough variables that I can change to be able to satisfy
all five equations simultaneously. What, then, should I do?
What if an approximate solution were to be okay? It turns out that I
can get an approximate solution as follows:
A~x = ~b becomes instead AT A~x = AT ~b
where AT is the transpose of A. Note that while A was a 5 2 matrix, since
AT is a 2 5 matrix, we have that AT A is a 2 2 matrix. Likewise, AT ~b is
a 2-dimensional vector. If you are unfamiliar with the transpose operation,
note that it is just interchanging the rows and the columns of the matrix.
This means that the old rows are the new columns, and the old columns are
the new rows. In our case, this means that
T 0 1 2 3 4
A =
1 1 1 1 1
Therefore, I type into Sage the following code:
A = matrix(5, 2, [0, 1, 1, 1, 2, 1, 3, 1, 4, 1] )
print A
print
M = A.transpose() * A
d = A.transpose() * b
M \ d
The output indicates that I have m = 403/200 or m = 2.015 and b =
71/10 = 7.1 as my solution. Do these numbers look familiar? It turns out
that this is precisely and exactly the linear regression problem that we had
on Page 157. Whenever you are computing a linear regression (i.e., a best-fit
line) on n data points, then you are solving n linear equations in 2 unknowns,
using this funky method, called Least Squares. The method was invented
4.17. COMPUTING TAYLOR OR MACLAURIN POLYNOMIALS 173
Analogous to the tangent line and tangent parabola, the nth degree
Taylor polynomial of f (x) at x0 is the unique nth degree polynomial p(x)
such that p(x0 ) = f (x0 ), and p0 (x0 ) = f 0 (x0 ), as well as p00 (x0 ) = f 00 (x0 ),
and so forth, until the nth derivative. The definition does not restrict the
n+1th or higher derivativesthey can be dierent, or they can be the same.
Oddly, some math faculty insist that if x0 = 0, that the polynomial be
called a MacLaurin polynomial, whereas if x0 6= 0, it is to be called a Taylor
polynomial. This rule is extremely strange. The mathematicians involved
are Brook Taylor (16851731) and Colin Maclaurin (16981746), as well as
James Gregory (16381675). Sadly, each had an unusually short life, even
by the standards of the their own times.
print "Polynomial:"
print p(x)
Meanwhile, we can change the 0 in the second line of our code to be pi.
Then we get the 5th degree Taylor polynomial of f (x) at the point x = .
Thats the plot above, on the right.
In summary, the taylor command expects four inputs: first, the func-
tion; second, the variable; third, the point about which the approximation
is being made; fourth, the degree of the approximation required. Here, we
asked for the 5th degree and got the 4th degree. Thats because the fifth-
degree coefficient turns out to be zero. Since we dont normally write 0x5 ,
that fifth-degree term is missing entirely.
By the way, as this is a four-parameter function, it happens that I almost
always get confused on the order of the four parameters. Real program-
mers always check the documentation. No one actually remembers fine
details like the particular order of the inputs. Even if you are confident that
you remember which is which, it is better to check anyway (using the tech-
niques of Section 1.10 on Page 47) to avoid the possibility of being mistaken.
Gme ms
F =
r2
print "Polynomial:"
print p(x)
var(y z)
f(x, y, z)=120*(y-x^2+1)^2 + (2-x)^2 + 110*(z - y^2)^2 + 150*(3-y)^2
minimize(f, [0.1, 0.3, 0.4])
Then we receive the output
Optimization terminated successfully.
Current function value: 0.000000
Iterations: 14
Function evaluations: 22
Gradient evaluations: 22
sum(1/k^4, k, 1, oo)
We get the answer: 4 /90. The two consecutive letters o are the Sage
symbol for infinity in this case, namely oo. If you squint and cross your eyes
slightly, the oo looks like 1.
6With the notable but extremely silly exception of a = 0, where the series converges
to 0 regardless of the choice of cr .
4.19. INFINITE SUMS AND SERIES 185
converges to, and then give a proof of that. We will ignore radius of
convergence issues for now, which actually do not come up in this problem.
First, lets ask Sage what that sum actually turns out to be, using the
following code:
var("j")
sum( x^(2*j+1)/factorial(j), j, 0, oo)
The response is
x*e^(x^2)
which will be our objective in our proof.
Lets say that you are pretty sure that
y y2 y3 y4 y5 y6
ey = 1 + + + + + + +
1 2! 3! 4! 5! 6!
but not entirely sure. You can verify this with
var("k y")
sum( y^k/factorial(k), k, 0, oo)
As you can see, Sage has helped us twice: first to give us a target for
our proof, and second to help us confirm an important basic formula which
we might or might not have misremembered. The rest is pretty straight
forward, after we substitute y = x2 into the definition of ey . We have the
following proof, but of course a student would have to add some words to
this.
y y2 y3 y4 y5 y6
ey = 1 + + + + + + +
1 2! 3! 4! 5! 6!
2 x2 x4 x6 x8 x10 x12
ex = 1+ + + + + + +
1 2! 3! 4! 5! 6!
2 x3 x5 x7 x9 x11 x13
xex = x+ + + + + + +
1 2! 3! 4! 5! 6!
j=1
X x2j+1
2
xex =
j!
j=0
Philosophical Point
Of course, the point of all this is that Sage is to be a set of training wheels for
the students learning of this famously hard topic: infinite series. Sage can
help students get over the initial befuddlement and confusion when being
first exposed to this material. The goal is that, at least after a while, the
student should consult Sage less frequently, until the problems can be solved
without Sages help at all. Only then can a rigorous Calculus II exam be a
success.
186 4. ADVANCED FEATURES OF SAGE
103993/33102,
104348/33215,
208341/66317,
312689/99532,
833719/265381,
1146408/364913,
4272943/1360120,
5419351/1725033,
80143857/25510582]
The first four of those contain three very famous approximations. Many
of us were taught 22/7 in high school. The approximation 355/113 was
discussed extensively on Page 32. The approximation 3 is said to have been
used by several ancient civilizations, including the Bible. See the article
The Chronology of Pi by Herman C. Schepler, in Mathematical Magazine,
Vol 23, No. 3, 1950. An interesting rebuttal can be found at
http://www.purplemath.com/modules/bibleval.htm
M aximize 2x + y
subject to :
1.5 2x y
1 x y
1 x 2y
x 0
y 0
By the way, if youre curious to see what that example looks like graph-
ically, it is given below. The shaded regions are those whose points do
not satisfy all the inequalities (i.e. infeasible points), while the unshaded
188 4. ADVANCED FEATURES OF SAGE
region is the one whose points do satisfy all the inequalities (i.e. feasible
points). Incidentally, code for making graphs of this type will be included
in the electronic-only online appendix to this book Plotting in Color, in
3D, and Animations, available on my webpage www.gregorybard.com for
downloading.
x = LP.new_variable()
print LP.solve()
print LP.get_values( x )
We will now go line-by-line through that code.
The first line is the least intuitive. The name LP gives a name to
this linear program, and it can be whatever name youd like to give
it. The long word MixedIntegerLinearProgram must always ap-
pear, in that capitalization, without spaces. Then you will indicate
7http://www.gregorybard.com/interacts/feasible_region.html
4.21. SYSTEMS OF INEQUALITIES AND LINEAR PROGRAMMING 189
Sage is going through a change right now. It has to do with the non-
negativity of variables inside of linear programs. The code presented in this
section will work both before the change and after the change. It would be
tedious and confusing to describe the change here. However, this warning
is displayed for a while before the change, so that users are aware that a
change is coming.
190 4. ADVANCED FEATURES OF SAGE
space into (convex) polyhedra. Sage can graph these, and that is described
in the electronic-only online appendix to this book Plotting in Color, in
3D, and Animations, available on my webpage www.gregorybard.com for
downloading.
This attribution has been made by many through the centuries, but its most
famous8 phrasing is by Galileo (15641642) in The Assayer,
. . . in this grand bookI mean the universewhich stands
continually open to our gaze, but it cannot be understood
unless one first learns to comprehend the language and
interpret the characters in which it is written. It is written
in the language of mathematics, and its characters are
triangles, circles, and other geometrical figures, without
which it is humanly impossible to understand a single word
of it; without these, one is wandering around in a dark
labyrinth.
However, it is often not until the course Dierential Equations, relatively
late in the mathematical education of some students, that this promise is
delivered. Suddenly, with the contents of that course, many of the hardest
problems in physics, chemistry, ecology, and finance are rendered transpar-
ent and facileto the point where they become mere homework problems.
Sadly, realistic problems from actual applications are often dirtythe
coefficients have decimal points, the equations are not cleanly solvable (es-
pecially if you include air resistance), and some problems are just plain diffi-
cult. This where Sage can be of a genuine service to a student. The student
can focus on modeling phenomena and correctly posing the problemthe
tedium of numerical solutions or series solutions can be best delegated to the
computer. By this division of labor between man-and-machine, considerably
harder and more realistic problems can be tackled than by a single human
working in isolation. This topic is the crown jewel of applied mathematics,
and the author strongly encourages any student to explore far beyond the
boundaries of the undergraduate course and penetrate deeply into advanced
topics.
Luckily, an entire book has been written to teach the Dierential Equa-
tions course using Sage. The book is Introduction to Dierential Equations
Using Sage, by David Joyner and Marshall Hampton, published by Johns
Hopkins University Press in 2012. That book covers a wide array of top-
ics related to dierential equations, and therefore it would be redundant to
reproduce all of that here.
Instead, we will show how to solve simple dierential equations, then
move on toward initial-value problems, and the construction of slope fields.
Then I present a capstone problem which is modeling the trajectory of a
torpedo, including the force of hydrodynamic drag. While Sage is extremely
capable of numerical solutions (with Runge-Kutta methods), series solu-
tions, boundary-value problems, systems of ordinary dierential equations,
separation of variables, and so forththe reader is referred to the Joyner-
Hanson book for those procedures.
print "Unsimplified:"
print h
print "Simplified:"
print h.expand()
The first line is a bit new to us. Just as we learned to declare unknown
variables with the var command back on Page 38, we must declare unknown
functions also. The method of declaring an unknown function is with the
function command, noted above. The only purpose of this is to tell Sage
and Python that we dont know what y(x) is going to turn out to be. In
any case, we get the following response:
Unsimplified:
(c + 7*e^x)*e^(-x)
Simplified:
c*e^(-x) + 7
You can also change diff(y,x) into diff(y,x,2) to make the second
derivative, rendering the dierential equation
d2 y
+y =7
dx2
which results in the response:
Unsimplified:
k2*cos(x) + k1*sin(x) + 7
Simplified:
k2*cos(x) + k1*sin(x) + 7
Now lets change the line with h to a new dierential equation, repre-
senting
dy
y + sin x = 0
dx
using the code:
h = desolve(y*diff(y,x)+sin(x)==0, y)
We get a rather dierent sort of answer:
Unsimplified:
-1/2*y(x)^2 == c - cos(x)
Simplified:
-1/2*y(x)^2 == c - cos(x)
4.22. DIFFERENTIAL EQUATIONS 195
Here, y(x) has been defined implicitly, not explicitly. However, we can
utilize a bit of algebra and see what is really intended:
( 1/2)(y(x))2 = c cos x
2
(y(x)) = 2 cos x 2c
p
y(x) = 2 cos x 2c
The indicates that Sage could not have given us a single function as
an answer. Because of the , as written, y(x) would fail the vertical line
test and thus cannot be considered a function. In other words, for any
function, choose any specific x in its domain, then there can only be one
y-value for that x-value. Here, we would have two y-values, and thats not
allowed. The better way to think of it is to imagine two solutions:
p
y1 (x) = 2 cos x 2c
p
y2 (x) = 2 cos x 2c
Actually, theres an infinite number of functions that satisfy the dier-
ential equation, because we can pick any value of c that we want. Lets say
that we choose to include the minus sign (i.e by picking y2 (x)) and that we
choose c = 832. How can we verify that this is indeed a solution?
We should type the following code:
f(x) = -sqrt(-2*(832-cos(x)))
print h.expand()
Now I have the answer:
-1/3*x^2 + x + 20/3/x
which really means
1 2 20/3
f (x) = x +x+
3 x
and therefore
2 20/3
f 0 (x) = x+1
3 x2
as well as
f (x) 1 20/3
= x+1+ 2
x 3 x
allowing us to conclude that the solution is correct by checking:
f (x) 2 20/3 1 20/3
f 0 (x) + +x = x+1 + x+1+ 2 +x
x 3 x2 3 x
2 1 20/3 20/3
= + + 1 x + (1 + 1) + + 2
3 3 x2 x
= 0+2+0=2
The new step were going to take is that were going to solve the original
dierential equation for dy/dx. In this case, we obtain
dy y
= x+2
dx x
which means
dy 1 20/3 2 20/3
= x 1 2
x+2= x +1
dx 3 x 3 x2
and note that all solutions to the dierential equation must obey that rela-
tionship, not just the one that satisfies our initial conditions.
Next, were going to construct a slope field plot. For every position on
the coordinate plane, we can use the equation above to find what dy/dx
should be. Sage will select about 400 points, in a 20 20 pattern, forming a
198 4. ADVANCED FEATURES OF SAGE
grid over the coordinate plane. For each point, Sage will compute dy/dx at
that point, and will draw a vector with that slope, centered on that point.
Our plot will cover 0 < x < 6 and 5 < y < 15, and we will also plot our
particular f (x) from the above, superimposed on the same image. Here is
the code:
var("y")
f(x) = -1/3*x^2 + x + (20/3)/x
As you can see, our solution (the solid curve) matches all the vectors that
are very near to it. In some ways, our solution is like connecting a sequence
of adjacent vectors, head-to-tail, to get a sweeping curve that takes us from
x = 0 to x = 6. Likewise, all other solutions would be similar sweeping
curves. If you had a dierent initial condition, youd start at a dierent
point, but youd still connect one vector to another, head-to-tail, to get a
sweeping curve.
A brief word is in order about the two options
headlength = 4, headaxislength = 3
Experts in dierential equations prefer to not have arrowheads on their
vectors when making slope field plots. I guess this makes sense, because
they might crowd the image (especially if the vectors are close together).
Furthermore, the arrowhead always goes on the right of the line segment
representing the shaft, so the arrowhead actually conveys zero additional
information. On the other hand, I really do prefer the arrowheads to be
there, because they are visually appealing and because they are useful to
4.22. DIFFERENTIAL EQUATIONS 199
If you look at the graph closely, you will see that for the rightmost
25% of the time, the graph looks like a line. Also, for large values of t,
our function y(t) will be a line. Without the force of hydrodynamic drag,
however, our function y(t) would be a parabola. Therefore, we can see that
the force of drag does not merely change the solution quantitatively, but
rather qualitatively. The slope of that line is called the terminal velocity
and at that velocity, the force of drag is equal to the thrust. Of course, it
should be noted that for y > 0 the torpedo is above the water and therefore
a completely dierent model must be used at that stage.
we normally would imagine that the code for computing the Laplace Trans-
form of our previous example would be as below:
var("s")
f(t) = 5*t*exp(t-3)
L(s) = integral( f(t)*exp(-s*t), t, 0, oo )
print L(s)
202 4. ADVANCED FEATURES OF SAGE
1/3*(sqrt(3)*sin(1/2*sqrt(3)*t) - cos(1/2*sqrt(3)*t))*e^(1/2*t)
+ 1/3*e^(-t)
However, that function is very hard to comprehend. For example, if I
have to put this function into a technical mathematical paper, then I have
to figure out how Im going to encode it into LATEX. Luckily, Sage can help
with this. If I replace the last line with
latex( inverse_laplace( L(s), s, t ) )
Then I get the frightening response
\frac{1}{3} \, {\left(\sqrt{3} \sin\left(\frac{1}{2} \, \sqrt{3} t
\right) - \cos\left(\frac{1}{2} \, \sqrt{3} t\right)\right)}
e^{\left(\frac{1}{2} \, t\right)} + \frac{1}{3} e^{\left(-t\right)}
which I can insert into my mathematical paper in LATEX. It encodes into
the following:
1 p 1p 1p 1 1
f (t) = 3 sin 3t cos 3t e( 2 t) + e( t)
3 2 2 3
9Of course, the gradient is the most important operator in Vector Calculus, (at least
in applied mathematics). Usually the gradient is introduced in an earlier course, such
as Multivariate Calculus, but we learned how to compute gradients in Section 4.3.2 on
Page 135. Therefore, we do not repeat it here.
204 4. ADVANCED FEATURES OF SAGE
print H(0,3)
print
print H(0,0)
print
print H(sqrt(pi), 2)
As you can see here, weve asked for the Hessian but in a numerical
sense.
p Weve asked for the specific matrix at the points (0, 3), (0, 0), and
( , 2). The responses are what we expect, as noted below:
p
3 1 3 1 e 2 1
1 0 1 0 1 0
Observe that three out of the four entries in the matrix (all but the
upper-left corner) are locked at fixed values. The upper-left corner varies
with x but not with y. Try other inputs to verify that this is true. Now if you
look at the symbolic Hessian, youll see that indeed, three of the four entries
are constants, and the upper-left corner is a function of x but constant with
respect to y.
Sometimes we just want to know the determinant of the Hessian. In
mathematical economics, there are times where producing example functions
f (x, y) with one unique local (and therefore global) minimum is very useful.
When we restrict consideration to functions of two variables, f (x, y)
there is a very useful shortcut. It turns out that this phenomena (namely,
that the local minimum or local maximum is unique) is guaranteed to occur
if the determinant of the Hessian is positive for all points (x, y). This is
the analogous result that univariate functions g(x) have a unique local (and
therefore global) minimum if g 00 (x) > 0 for all x. Furthermore, univariate
functions g(x) have a unique local (and therefore global) maximum if g 00 (x) <
0 for all x. With that in mind, we can type
g(x,y) = (x + y + 2)*(x + y + 1)*(x + y - 1)*(x + y - 2)
h(x,y) = det(diff( g, 2 ))
print h(x,y)
206 4. ADVANCED FEATURES OF SAGE
to get that determinant of the Hessian very quickly. In this case, the deter-
minant is zero everywhere.
and was easily computed by hand. However, for more complicated functions,
we might prefer to use Sage. For this function g, we would type
g(x, y, z) = x^2 + y^3 + z^4 + x*y*z^2
print "Laplacian:"
print L(x,y,z)
print "Hessian:"
print diff( g, 2 )
We obtain the following output:
Laplacian:
2*x*y + 12*z^2 + 6*y + 2
Hessian:
[ (x, y, z) |--> 2 (x, y, z) |--> z^2 (x, y, z) |--> 2*y*z]
[ (x, y, z) |--> z^2 (x, y, z) |--> 6*y (x, y, z) |--> 2*x*z]
[ (x, y, z) |--> 2*y*z (x, y, z) |--> 2*x*z (x, y, z) |--> 2*x*y + 12*z^2]
4.24. VECTOR CALCULUS IN SAGE 207
As you can see, the Laplacian is just the sum of the entries on the main
diagonal of the Hessian.
print "Function:"
print f
print "Jacobian:"
print diff(f)
print "Jacobian Determinant:"
print det( f.diff() )
As you can see, Sage considers the Jacobian to be the natural meaning
of the word derivative for a function that has a vector input and a vector
output. Upon further thought, this makes sense. Specifically, if the output
of some function is one-dimensional, but with a multidimensional input,
then the Jacobian would be equal/identical to the gradient as a row vector,
and Sage considers the gradient to be the natural meaning of the word
derivative for functions for many-input one-output functions.
However, if the determinant of the Jacobian Matrix is desired, one must
explicitly use the det command, like any other determinant.
print "Divergence:"
print div(x,y,z)
print "Jacobian:"
print derivative( f )
4.24. VECTOR CALCULUS IN SAGE 209
print "Original:"
print g(x, y, z)
gradient = derivative( g )
print "Gradient:"
print gradient
which results in the output:
Original:
x*y*z^2 + z^4 + y^3 + x^2
Gradient:
(x, y, z) |--> (y*z^2 + 2*x, x*z^2 + 3*y^2, 2*x*y*z + 4*z^3)
Now with that in mind, we can interpret the three components of the
gradient as f1 , f2 , and f3 . We will program Sage to take the partial deriva-
tives and compute the sum. Use the following code:
f1(x,y,z) = y*z^2 + 2*x
f2(x,y,z) = x*z^2 + 3*y^2
f3(x,y,z) = 2*x*y*z + 4*z^3
Laplacian:
2*x*y + 12*z^2 + 6*y + 2
As you can see, this is an exact match for the Laplacian that we had
computed on Page 206. We have now verified that the divergence of the
gradient (of this particular function) is equal to the Laplacian (of this par-
ticular function). Thats a far cry from proving the theorem in general, but
it is nice to know that we can at least verify individual instances.
f1 f2 f3
" @ @
# " @ @
# " @ @
#
= det @y @z ~i det @x @z ~j + det @x @y ~k
f2 f3 f1 f3 f1 f2
@ @ @ @ @ @
= f3 f2 ~i f3 f1 ~j + f2 f1 ~k
@y @z @x @z @x @y
= curlf~
Essentially, if you can remember that 3 3 matrix, and take its determi-
nant successfully, then you can compute the curl of any function R3 ! R3 .
You might be curious to know why I called it semi-nonsense. The reason
is that @/@x is an operator, and computing
@
f2
@x
is not a multiplication in any way, shape or form. Yet, the process of com-
puting those 2 2 determinants is exactly and precisely two multiplications
4.24. VECTOR CALCULUS IN SAGE 211
Since f2 and f3 are the zero function in this case, then we can focus on
f1 . We can see that
@ @ @
f1 = 0 f1 = 2y f1 = 0
@x @y @z
and thus the normal formula for the curl simplifies rapidly
@ @ @ @ @ @
r f~ = curlf~ = f3 ~
f2 i + f1 ~
f3 j + f2 f1 ~k
@y @z @x @z @x @y
= (0 0)~i + (0 0)~j + (0 2y)~k
= 2y~k =< 0, 0, 2y >
var("y")
plot_vector_field( (y^2,0), (x,-1,1), (y,-1,1) )
As you can see, all the arrows point to the right. The x-coordinate does
not matter; the arrows near the x-axis (those with a small y-coordinate,
in absolute value) have a small magnitude, while those far from the x-axis
(those with a large y-coordinate, in absolute value) have a large magnitude.
Now ask yourself, if this plot was representing a flowing fluid, how would
you expect a paddle-wheel to behave if inserted:
above the x-axis?
on the x-axis?
below the x-axis?
Take a moment to really think about this. (Please do not read further
until youve tried to answer that thought experiment.)
In any case, if the paddle wheel is on the x-axis, there would be no
rotation. However, above the x-axis, we would expect clockwise rotation,
and below the x-axis, we would expect counter-clockwise rotation. Thats
because one side of the paddle wheel is being bueted to much greater extent
than the other. Recalling that clockwise rotation on a two-dimensional piece
of paper indicates a vector into the paper, and counter-clockwise rotation
indicates a vector out of the paper, we see that our answer of < 0, 0, 2y >
makes sense.
When y is zero, all coordinates of the curl are zero, thus the curl is
zero. (That means no paddle wheel rotation.)
When y is negative, the third coordinate is positive, thus the curl
points out of the paper. (That means counter-clockwise paddle
wheel rotation.)
When y is positive, the third coordinate is negative, thus the curl
points into the paper. (Similarly, that means clockwise paddle
wheel rotation.)
Now we must compute this in Sage. The calculus was easy in this ex-
tremely simple example, but in other examples it might be extremely un-
pleasant. The following code-snippet is very handy:
4.24. VECTOR CALCULUS IN SAGE 213
var("y z")
f1 = y^2
f2 = 0
f3 = 0
Naturally, we get the expected output of (0, 0, -2*y) from that code.
var("y z")
f1 = x^2*y
f2 = x + y + sin(x)
f3 = 0
As you can see, we added two lines to make a vector plot, and obtained
the following image:
214 4. ADVANCED FEATURES OF SAGE
217
218 5. PROGRAMMING IN SAGE AND PYTHON
Lets make our code more powerful now. If I wanted to go every 1/4th
of one percent, I could do
for i in range(1,120):
print N(i/400),
print " implies ",
print N( 15000*(1+(i/400))^5 )
which entailed three changes. First, the (i/100) in the big N() became
i/400, to make the steps 1/400 (a quarter of a percent) instead of 1/100
(or one percent). Next, the loop goes to 120 instead of 30, so that I stop at
29.75%, instead of stopping one-fourth of the way there. Lastly, I decided
to make the leftmost print show the actual rate, rather than the value of i,
so that went from print i to print N(i/100). Leaving o the N() in that
first print produces the funny result of Sage trying to reduce the fractions
that comprise the interest rate into lowest terms. Try it yourself and see
what I mean.
We can make our earlier example with x3 x produce more professional-
looking output too. We could type
for x in range(-10,11):
print "x=",
print x,
print " means y=",
print x^3-x
At this point, our code is getting rather tall in the sense that were
using up a large number of lines but not doing very much of anything.
It turns out that we can save some vertical space by combining the print
statements. This is permitted so long as we keep the commas. For example,
give the following code a try.
for x in range(-10,11):
print "x=", x, " means y=", x^3-x
total = 0
for i in range(0, 1001):
total=total+i
print total
Wasteful Loops:
It would be wasteful and unwise to instead print each number from 1 to
1000, and then add them up. The code to do that would be
total = 0
for i in range(0, 1001):
print i
total=total+i
print total
Note the print i between the for statement and the total =
total+i statement. Here there is too much output to display and the list
of numbers is enormous, scrolling downward for a long time. It is important
to avoid such techniques (especially if using a million or a billion numbers)
as important computational resources, such as bandwidth and computing
time, would be thereby wasted. The waste is particularly exaggerated in
a system like Sage because you are using the internet to transfer all those
intermediate values from the Sage server to your web browser. When my
students are frustrated that their code is running extremely slowly, often
the cause is that they have superfluous print statements which are wasting
time.
By the way, did you notice how the 0 was included, but the 1001 was
excluded? This is similar to the examples in Section 5.1.1 on Page 218,
where we evaluated f (x) = x3 x over the domain range(-10, 11), where
-10 was included but 11 was excluded. The reason that Python works that
way is so that range(0, 10) will run exactly 10 times, range(0, 100) will
run exactly 100 times, and range(0, 1000) will run exactly 1000 times. By
the way, each pass or run of a for loop is called an iteration.
222 5. PROGRAMMING IN SAGE AND PYTHON
is doing around the value x = 8. Then you could write the following code
for i in range(0,9):
xtemp = 8 - 10^(-i)
print N( e^( 1/( 8-xtemp ) ) )
which inquires about the values of f (x) at the points
7, 7.9, 7.99, 7.999, 7.9999, 7.99999, 7.999999, 7.9999999, 7.99999999
Those numbers also have the names
8 100 , 8 10 1
, 8 10 2
, 8 10 3
, 8 10 4
, 8 10 5
, 8 10 6
, 8 10 7
, 8 10 8
2.71828182845905
22026.4657948067
2.68811714181614e43
1.97007111401705e434
8.80681822566292e4342
2.80666336042612e43429
3.03321539680209e434294
6.59223253461844e4342944
1.54997674664843e43429448
which is clearly going to infinity. (If 1.54 1043,429,448 isnt close enough
to infinity, then I dont know what is!) Then by changing the 8 10 i into
8 + 10 i we would obtain
for i in range(0,9):
xtemp=8+10^(-i)
print N( e^( 1/( 8-xtemp ) ) )
which inquires about the values of f (x) at the points
9, 8.1, 8.01, 8.001, 8.0001, 8.00001, 8.000001, 8.0000001, 8.00000001
which also have the names
8+100 , 8+10 1
, 8+10 2
, 8+10 3
, 8+10 4
, 8+10 5
, 8+10 6
, 8+10 7
, 8+10 8
which are two interesting answers in their own right. The final conclusion,
however, must be
lim f (x) = d.n.e.
x!8
because we must say that a limit (in general) does not exist if the limit
approaching from the left and the limit approaching from the right do not
equal each other.
224 5. PROGRAMMING IN SAGE AND PYTHON
Caveat:
The exploration of that limit required a bit of work, but not too much, and
it answered a rather difficult question. Thus, we can see that the technique
of numerical evaluation of limits has a place in mathematics. Nonetheless,
bewarenumerical limits are horribly unreliable!
For example, the sum of the reciprocals of the first n prime numbers
goes to infinity as n goes to infinity. To be precise, I mean the sum
1 1 1 1 1 1 1 1 1 1
+ + + + + + + + + +
2 3 5 7 11 13 17 19 23 29
goes to infinity. This theorem has a nice but difficult proof and it would not
be enjoyable to go through it at this time.
However, youd never be able to detect this divergence via a computer.
In fact, as n grows, that sum basically grows like log(log n). (Im simplifying
this discussion slightly by removing a few details). For example, if your
standard of close enough to infinity were 1000, youd have to wait until
1000 1000
ee numbers were totaled. The concept of ee is so large it is not easy
for me to decide how to describe it. Even if your standard of close enough
10
to infinity were 10, youd have to wait until ee numbers were tabulated,
10
and note that ee has 9565 digits!
Needless to say that if you were to attempt to calculate this with a for
loop, long before that tabulation terminates the sun will have already turned
into a red giant and we will all be burned to a crisp.
where v is the velocity of some object, and c is the speed of light. This
formula describes how objects moving very fast will shrink in the direction
of travel, become more massive, and have time slow down (or dilate) for
them.
If we apply the previous tool to this problem, we would do it as follows:
f(v,c) = 1/sqrt(1-(v^2/c^2))
for i in range(0,10):
print i,
print "th derivative is",
print diff(f,v,i)
which tells you that the 9th derivative is
893025*v/((-v^2/c^2 + 1)^(11/2)*c^10) +
13097700*v^3/((-v^2/c^2 + 1)^(13/2)*c^12) +
51081030*v^5/((-v^2/c^2 + 1)^(15/2)*c^14) +
72972900*v^7/((-v^2/c^2 + 1)^(17/2)*c^16) +
34459425*v^9/((-v^2/c^2 + 1)^(19/2)*c^18)
a calculation that I would not want to do by hand.
1My friend Martin Albrecht, a major Sage developer, once called Python executable
pseudocode.
226 5. PROGRAMMING IN SAGE AND PYTHON
top_cost = 0.5
bottom_cost = 1.3
side_cost = 5
bottom_top_area = length*width
front_back_area = length*height
left_right_area = width*height
Given a customer preference for the volume of the aquarium, there are
many choices of dimensions and they will have substantially dierent costs.
Consider a customer who wants a 12,000 cubic inch aquarium. (Note that
12,000 cubic inches is about 52 gallons so that is not a very large aquarium
at all.) We can compute the following prices:
A choice of 20 30 20 has a cost of $ 110.80.
A choice of 40 30 10 has a cost of $ 91.60.
A choice of 60 20 10 has a cost of $ 101.60.
A choice of 80 15 10 has a cost of $ 116.60.
Those prices were computed using the analyzeAquariumDesign subrou-
tine, which youll find in Figure 1. The following commands were used, one
at a time, after the subroutine was defined.
230 5. PROGRAMMING IN SAGE AND PYTHON
As you can see, the code has a few new features which you perhaps
have not seen before. The symbol that looks like six apostrophes in a row
is actually a triple quotation mark. Between the triple quotation marks
you can put whatever words you want to explain what your subroutine
does, to some person reading your code. Generally, it is better to use a
few sentences rather than just one. This description is called a docstring
and it is very important. Without a good docstring, it is unlikely that
any other person would ever use your code. However, code-reuse is an
enormously important strategy in both industry and academia. It would be
phenomenally expensive to reinvent the wheel each time that a computer is
needed to perform some task. By the way, when we used the ? operator
(see Section 1.10 on Page 47), what we were reading were the docstrings
written by earlier Sage programmers.
The variables top cost, bottom cost, and side cost are used to store
the costs for each part of the aquarium. If I had instead used the actual
number 0.5 at each place where the variable top cost appears, then the
code would have been less readable. Also, the price might change. If the
price becomes 0.6 instead of 0.5, then maybe I might change it only in a
few placesfailing to change it everywhere. Then the calculations would
be ruined. However, by using a variable to store the value at the top of the
program, I need only change it in one spot. Making code easy to update and
maintain is also extremely important both in the industrial and academic
worlds.
We saw variables used like this before (see Section 1.6 on Page 32),
however there is some additional useful terminology. When a variable is
created and used exclusively inside of a subroutine then it is called a local
variable. However, these variables are created outside of any subroutine,
and so are visible to all the subroutines; those variables are called global
variables. In many types of programming, global variables are discouraged
but in scientific or mathematical computing, they seem to be more common.
It is considered good programming style to place all the global variables at
the top of the program, so that they can be easily foundhowever, this is
not strictly necessary. Python and Sage will not object if you were to break
that rule of coding etiquette.
Every other line of the code in Figure 1 was either a print statement or
a mathematical equation. Often in scientific computing, complex tasks can
be carried out with these very simple tools.
By the way, this subroutine analyzeAquariumDesign will become the
basis of an interactive webpage using Sage. Making Interactive webpages
5.2. WRITING SUBROUTINES 231
can be great fun, and it is the topic of Chapter 6. We will explore using this
particular subroutine in Section 6.4 on Page 290.
evaluated at 0, 1, 2, 3."""
for k in range(0, howmany):
print f(k),
print
We can also define the following functions to test our code:
a(x) = 3*x + 5
b(x) = 2 - x
c(x) = 7 + 10*x
d(x) = 8*exp(-0.1*x)
f(x) = 5*3^x
g(x) = (1/8)*2^x
h(x) = (0.125)*2^x
We can now test our code with function to sequence( a, 20 ) and
see what happens. Likewise, you can use b(x) or c(x) by replacing a with
b or c, and so forth. You will notice some interesting behavior dierences
between g(x) and h(x), which are dierent to Sage despite the fact that to
a mathematician, g(x) and h(x) are the same function. Try it yourselfI
wont spoil the surprise.
Something I find really neat about Sage is that you can type code like
function_to_sequence( 3*x, 20 )
and Sage will figure out what you meant. You do not need to define a
separate function like j(x) = 3x to work with 3x as a function.
where j runs through the positive integers, and x might be real, complex,
or imaginary.
sin x = 1 x
f (x) = 1 x sin x
3As you might guess, Newtons Method is named for Isaac Newton (16421727).
234 5. PROGRAMMING IN SAGE AND PYTHON
which has the left-hand and right-hand sides of our equation coming out to
equal for 15 decimal placesaccuracy to the nearest quadrillionth.
Summary:
From this exercise, we can see that Newtons method has two important
properties. First, once f (x) and f 0 (x) as well as the initial guess are given,
then the method is very simple to carry out. Second, the method is not
terribly exciting for a human being to use, because it is repetitive. After
all, once the initial guess and the two functions f (x) and f 0 (x) are known,
all we are doing is repeatedly using some formulas several times. These two
features mean that Newtons method is ideal for a computer, and this is
even more so the case when we realize that the computer has more digits of
precision than we might be wiling to use with our handheld calculator.
x_old = N(x_new)
The first line notifies Sage that we are about to define a subroutine. The
name of it will be newton method and it will have two parameters, called
f and x old. It is extremely important that the next few lines are indented.
The degree of indentation shows which commands are subordinate to which
others. Since Newtons Method requires knowledge of the derivative of the
function whose root you are trying to find, we are not surprised to see the
next line defining f prime(x). Note that we cannot use an apostrophe in
place of the prime, as in f 0 (x), because the apostrophe already has a meaning
in Python. This minor point was first mentioned on Page 49.
Now we come to a loop that will run 10 times, as signaled by the for
command. As you can see, the loop is mostly print statements, to let the
user know whats going on. At this point, the syntax of the print command
is likely to be familiar to you, but you can also flip back to Section 5.1.2 on
Page 219.
The three lines of the loop that are not print statements are three
assignments. The first defines the ratio as we saw in the previous subsec-
tion. The second assignment defines xnew from xold according to the rules
of Newtons method.
5.3. LOOPS AND NEWTONS METHOD 237
Finally, we see the line x old = N(x new) which might be confusing.
Basically, during the run of the for loop identified by j = 3, the value of
xold will be the value that xnew had during the run of the for loop identified
by j = 2. This command provides the link between one run of the loop and
the next run of the loop.
The only surprise would be the use of the N( ) command, which we pre-
viously had used only to convert an exact (algebraic) form of some number,
perhaps hard to understand, into a floating-point form or decimalwhich
is easier to understand but which is necessarily only a mere approximation.
The use of N( ) here is to force Sage to compute approximately and
not exactly. That might be surprising because one of Sages strengths is its
abilities to compute exactly. However, we will see an example in the next
subsection which will reveal to us why I have made this choice.
4This issue, called backwards compatibility is an extremely serious one in any soft-
ware project involving more than one programmer. A student who wishes to have any sort
of job at all must take a moment to realize that they will not be the only one programming
a computer at their new company. Therefore, they should take great care to think about
this issue in depth. Breaking the code of other people by modifying something without
permission is an outstandingly eective way to get fired.
5.3. LOOPS AND NEWTONS METHOD 241
f_prime(x) = diff( f, x )
x_old = N(x_new)
I have to be honest here, and tell you that I had to experiment a few
times until I found an initial-guess-selection function that I fought suitable.
Last but not least, we have to decide how to use the optional parameters.
I decided to set max iterate=100 so that I can be sure that I have a very
good answer. There is a downside to using 100 iterationsthe output will
be extremely long, and the user will have to scroll. However, well learn how
to mitigate this issue using verbosity control on Page 246.
244 5. PROGRAMMING IN SAGE AND PYTHON
def selfLogarithm( y ):
"""This subroutine returns x such that x^x = y, where
y is a positive real number."""
g(x) = x^x - y
guess = 1 + log( y, 10 )
return answer
The final code snippet is to be found in Figure 4. Note that this code
absolutely requires Version 2 or higher of our newton method subroutine,
because Version 1 did not have a return statement.
Now we can test this code by typing
selfLogarithm( 17 )
Figure 5. The Two Cases of Parallel Tangent Lines, from Section 5.3.7
y = (0.793700525 )x + 0.314980262
y = (0.793700525 )x 0.157490130
f_prime(x) = diff( f, x )
if (verbose==True): # new
print "iteration=", j
print "x_old=", x_old
print "f(x)=", f(x_old)
print "f(x)=", f_prime(x_old)
print "ratio=", ratio
print "x_new=", x_new
print
x_old = N(x_new)
return x_old
This is our first encounter with the if construct, and it is a very easy to un-
derstand use of that command. We will combine this with a new parameter
called verbose. Like the max iterate parameter, the verbose parameter
will be optional.
If the verbose parameter is set to True, we will print, and if it is not,
we will not. The code itself is given in Figure 5.4.1. Those lines which have
changed (since Version 2 given in Figure 3) have the # changed annotation
along side them, and those which have been moved have the annotation #
moved. New lines have the # new annotation.
While it looks like a large number of changes, it really is not a major
dierence.
I have added the optional parameter, verbose.
248 5. PROGRAMMING IN SAGE AND PYTHON
I have moved all the print statements to the same spot. It is a bit
of a decision as to where to put them. They have to be late enough
to ensure that ratio and x new are actually computed. However,
if I had put the print statements after x old = N(x new) then the
distinction between x old and x new would be lost.
I added the command if (verbose==True):
All the print commands were indented one level.
The indenting is very important. For example:
The print statements are indented very far, which shows that they
are subordinate both to the if statement and the for statement.
That means the if statement will be run during each iteration of
the for loop, and the print statements will only be executed if the
parameter verbose is True.
The x old = N(x new) statement is indented less, which shows
that it is subordinate to the for statement but not to the if
statementin other words, the condition of verbose being True
or False is of no consequence whatsoever to this line, which will
be executed either way. On the other hand, the line is subordinate
to the for loop. Therefore, each iteration of the for loop will see
this line computed.
The return x old statement is intended very little. This means
that is not subordinate to the for loop nor is it subordinate to the
if. However, it is still subordinate to the def which means that it
is indeed part of our subroutine. It will be executed once only, not
once for each cycle of the for loop.
You can test this code with any of the following test commands:
newton_method( b, 2 )
newton_method( b, 2, verbose=True )
newton_method( b, 2, max_iterate=5 )
newton_method( b, 2, max_iterate=5, verbose=True )
newton_method( b, 2, verbose=True, max_iterate=5 )
As you can see by the last two lines of test code, the optional parameters
can be given in any order. However, in the def line of any subroutine, the
mandatory parameters must be listed first, and the optional parameters are
listed after thatone cannot mingle the two. This is a rule that Sage has
inherited from Python.
We have a minor technicality to discuss now. In the if statement, we see
two equal signs, or ==. Up to this point, we have used one equal sign. The
key is that if you are testing equality, then you use two equal signs, but if you
are causing equality, then you use one equal sign. For example, if we wanted
to force verbosity to be True, we would be typing verbose=True at some
point in the subroutine. However, in the if statement, we need to check
equality, not force it, so we use two equal signs with if (verbose==True):
to make that happen.
5.4. AN INTRODUCTION TO CONTROL FLOW 249
p(x) = x3 + x2 5x + 9
Even its plot is not particularly unusual, as you can see below (showing
5 < x < 4).
iteration= 0
x_old= 2
f(x)= 11
f(x)= 11
ratio= 1
x_new= 1
iteration= 1
x_old= 1.00000000000000
f(x)= 6.00000000000000
f(x)= 0.000000000000000
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-1-8a48587f6c88> in <module>()
28 return x_old # changed
29
---> 30 newton_method( p, Integer(2), max_iterate=Integer(20))
/home/sageserver/sage/local/lib/python2.7/site-packages/sage/structure/el...
in sage.structure.element.RingElement.__div__ (sage/structure/element.c:1...
/home/sageserver/sage/local/lib/python2.7/site-packages/sage/symbolic/ex...
in sage.symbolic.expression.Expression._div_ (sage/symbolic/expression....
Newtons method computation for each of their iterations, yet one million
iterations of the multivariate solver would not be very unusual.
Accordingly, we should make some sort of cut o. If f (x) is smaller
than some particular value, perhaps one billionth, then we should stop the
computation and report the final answer. We might take a moment to decide
if we want that value to be preset or instead, set by the user. A preset value is
better for users who might not be very familiar at all with Newtons method,
while allowing it to be set by the user would be better for expert users. The
best of both worlds can be achieved by using an optional parameter. The
beginning user need not worry about (or even be told) about the optional
parameter, but the expert can override when needed. Also, since the value
is unlikely to be overridden too often, using an optional parameter keeps
us from having too many things between the parentheses each time the
subroutine is called.
The traditional name for a cut-o value of this kind is epsilon. The
Greek letter is often used to represent a value of close enough in compu-
tational mathematics. In Figure 5.4.3, youll find the new code, or Version 4,
of Newtons method. The key new lines are
The first line says (in Python) what a mathematician would write as
if |f (x)| < then and the second line, the return statement, tells the
subroutine to return the final answer. It is implicit in that return statement
that the subroutine has completed its computation, and that nothing more of
the subroutine will be run until it is called again. Thus it is not uncommon
for a subroutine to have several return statements, but whenever any of
them are reached, the computation ends.
f_prime(x) = diff( f, x )
if (verbose==True):
print "iteration=", j
print "x_old=", x_old
print "f(x)=", f(x_old)
print "f(x)=", f_prime(x_old)
print "ratio=", ratio
print "x_new=", x_new
print
x_old = N(x_new)
return x_old
if the user sets it to True then it should print all the primes that it discovers
while counting up from 1 to x.
f_prime(x) = diff( f, x )
if (verbose==True):
print "iteration=", j
print "x_old=", x_old
print "f(x)=", f(x_old)
print "f(x)=", f_prime(x_old)
print "ratio=", ratio
print "x_new=", x_new
print
x_old = N(x_new)
return x_old
Notice also how we used the + sign to make a longer error message than
can fit on one line. It is not permitted to break a quotation, such as our
error message, across two lines. Therefore, we wrote the quotation in two
pieceseach fitting on one lineand then used the plus sign to tell Sage
that it is actually one long error message. You can see the output generated
in Figure 10. As always, the last line of an error message in Sage is the most
important.
There are many advantages to using the raise command to notify the
user of a major error, rather than just stopping the program. First, you
could imagine that in a large program, some sequence of subroutines might
call a sophisticated multivariate solver, which would call our newton method
subroutine. If we just return a value (such as 0) and print an error message,
we are not notifying the higher layers that something has gone wrong,
and the entire program might do very strange things as a result. However,
the raise command would halt computation, and prevent the larger pro-
gram from doing very unexpected things. Second, there is a try: except
construct in Python, which we cannot explore here. Using that construct,
you can actually respond and accommodate the error, and perhaps try the
subroutine again. Third, the raise command allows you to oer the user a
nice error message.
As you have no doubt seen, many error messages in Sage are extremely
unreadable. This has no doubt caused you some frustration at times. Thats
the reason why you should try to avoid causing that frustration in your users
and why you should make informative error messagesas well as hope that
later generations of Sage developers will do similarly.
x2 4x + 3
f (x) =
x2 5x + 6
Now we will utilize a very powerful concept in computer programming,
called the if-then-else construct. This is like the if statements that we
used before, but now we are adding an else command. The idea is that
well first check (with an if) whether or not the denominator is zero. If it is
zero, then well print dne for does not existthat would be the then
part. If it is not zero, then we want to print the value of the entire function
at that natural numberthat would be the else part.
Consider the following code:
def rationalFunctionToSequence( num, denom, howmany ):
"""This subroutine takes a function as the first input, and
then evaluates that function at the first howmany natural
numbers. For example, if howmany is 4, then the f is
evaluated at 0, 1, 2, 3. Any poles are reported as dne."""
for j in range(0, howmany):
if (denom(x=j) == 0):
print "dne",
else:
value = num(x=j) / denom(x=j)
print value,
Now we have two parameters for communicating the function to the
subroutine, because we need the numerator and denominator separately.
The third parameter tells us how many natural-number function evaluations
are requested. The second line is just a for loop to take us through the first
few natural numbers, namely 0, 1, 2, . . . , n 2, n 1. Next well evaluate
the denominator at the point x = j, and see if it is zerothats the third
line. In the fourth line, only to be executed if the denominator is zero, we
print dne.
The fifth line is the else command which means that the sixth and
seventh lines, which are indented under the else and therefore subordinate
to it, will be executed only if the denominator is not equal to zero. We
compute the value of f (x) at x = j, which is merely the numerator divided
by the denominator (line six), and finally we print it in (line seven).
Now, lets test our code, with the following lines:
f(x) = x^2 - 4*x + 3
g(x) = x^2 - 5*x + 6
rationalFunctionToSequence( f(x), g(x), 10 )
We get the following output, and can be satisfied that the subroutine
works correctly:
1/2 0 dne dne 3/2 4/3 5/4 6/5 7/6 8/7
5.5. MORE CONCEPTS IN FLOW CONTROL 259
The else command is a time-saver but it also makes the code more
readable. The following code is equivalent, but more tedious to write and
to read:
if (denom(x=j) != 0):
value = num(x=j) / denom(x=j)
print value,
Here, weve explicitly said that print "dne" is only to occur if the
denominator is zero. Similarly, the division of numerator and denominator,
storing it in value, and printing it, will only occur if the denominator is
not zero. Therefore, the else command is not strictly necessary, but it
does make things easier for the programmer. The advantages of having
else available are easier to appreciate when we handle complex if-then-else
statements inside each other. We wont get to that in this Chapter, but
other books on Python would.
A historical note is that even though there is no then command in
Python, nor in C, C++, nor Java, the concept is still called if-then-else.
Thats because some very old programming languages, like BASIC and Pas-
cal, used the word then as a command. The nomenclature reflects that
historical memory.
return guess
5.6. WHILE LOOPS VERSUS FOR LOOPS 261
This code will start with a value for guess that is 0. It will keep
executing the command guess = guess + 1 while it remains true that
factorial(guess) < y evaluates True. However, the very moment that
factorial(guess) < y evaluates False, it will halt the loop and not incre-
ment guess. In plainer words, the very moment that factorial(guess) >=
y the loop stops and program flow will continue with the next line return
y.
We can test this with a few numbers and see that it works. For example,
first_factorial_greater_than(130)
returns 6 because 5! = 120 and 6! = 720.
You can also try checking with the following:
print first_factorial_greater_than( 10^6 )
print factorial(9)
print factorial(10)
f_prime(x) = diff( f, x )
iterations=0
if (verbose==True):
print "iteration=", iterations # changed
print "x_old=", x_old
print "f(x)=", f(x_old)
print "f(x)=", f_prime(x_old)
print "ratio=", ratio
print "x_new=", x_new
print
x_old = N(x_new)
return x_old
target = x
current_prime = 2
while (target>1):
if ( (target % current_prime) == 0 ):
# target is divisible by the current prime.
print current_prime,
target = target / current_prime
else:
# target is not divisible by the current prime.
current_prime = next_prime( current_prime )
print
That print statement at the end of the subroutine will allow us to try
multiple test cases at once. Lets try testing with
trialDivisionFactor( 25 )
trialDivisionFactor( 26 )
trialDivisionFactor( 27 )
We get the excellent output below:
Computing the factorization of 25 : 5 5
Computing the factorization of 26 : 2 13
Computing the factorization of 27 : 3 3 3
You can try that three-line test again, after removing the lonely print
statement at the end of the subroutine. The funny output obtained will
demonstrate why we need that print statement. A better test would be to
check a bunch of consecutive integers, as below.
for y in range(19, 50):
trialDivisionFactor( y )
If you try that check, youll see that our code is working well.
However, the subroutine does not work well with a negative input. Well
have to fix that. For example, nothing gets printed if you try
trialDivisionFactor( -10 )
where ` 2 since n is not prime. We know p that there does not exist a prime
dividing n that is less than or equal to n, so we have
p
p1 > n
p
p2 > n
p
p3 > n
.. .. ..
. . .
p
p` > n
Combining all these (which is only allowed because everything is posi-
tive) yields:
p
(p1 )(p2 )(p3 ) (p` ) > ( n)`
(p1 )(p2 )(p3 ) (p` ) > n`/2
n > n`/2
Since ` 2 then `/2 1 and n`/2 > n1 . We now have
n > n`/2 and n`/2 > n therefore n > n
which is clearly a contradiction. Therefore, our supposition was false, and
n is surely prime.
Therefore, we should check if current prime is greater than the square
root of target. If so, then we can freely halt the while loop because target
is prime.
Your challenge is to modify the existing code from above to make this
shortcut happen. A good test case for your work might be
x = 1, 000, 730, 021
print new_point
scatter_plot( list_of_points )
First, we define our function and second, we start with an empty list of
points. (Those are our first two lines). Just as any sequence of numbers,
separated by commas, and enclosed in square brackets, is a listthe empty
list is simply a pair of square brackets with nothing between them. Then
we quickly define a variable verbose which will be convenient later. Next
follows the for loop which does most of the work.
For every iteration through the for loop, we compute an x-coordinate.
While k will move from 150 to 150, each x-coordinate is to be very close
together. In fact, we multiply by 0.01, forcing x to move from 1.5 to 1.5
in increments of 0.01. The y-coordinate is just f (x). Then, we construct a
point, which is an ordered pair, and it is just x comma y. It might be
interesting for you to set verbose to True instead of False, to actually see
that list. Next, we update our list of points by adding together the old list,
and a list consisting only of the new point. Finally, when all k values are
processed and the for loop has completed, we make a scatter plot.
The line
could use more explaining. In this line, we are telling Sage that the new list
of points should become the old list of points, plus also the new point. The
plus sign between two lists is going to result in a concatenation (or merger)
of the two lists. However, unlike set theory, order matters and duplicate
entries can occur. Well explore the dierences between sets and Python
lists momentarily. The fact that we had to write the name of the list twice
is slightly inconvenient because the name of this list is somewhat long. To
alleviate this, Python actually has a shortcut
list_of_points.append( new_point )
that will stick a single element at the end of the given list.
Now the natural question would be is this how Sage does it? What
happened here is the basic algorithm that is almost always used in tools like
graphing calculators or older mathematical software. Sage actually takes
a few points in tiny equally spaced intervals along the x-axis, instead of
just one point. Also, those representative points within the interval are not
equally spaced, but are chosen at random. We explained why on Page 3.2.
Lastly, Sage will occasionally detect that more points are needed in certain
subintervals because the function is going wild there and will evaluate
extra points in those subintervals.
5.7. HOW ARRAYS AND LISTS WORK 269
print a + b
print b + a
We obtain the following output:
[2, 3, 4, 1, 3]
[1, 3, 2, 3, 4]
Here, we can really see the dierence between Python lists and sets. First
of all, in a mathematical set, no entry appears more than once. However,
here we see that entries can appear more than once. Also, in mathematical
sets, order does not matter. In Python, order matters.
Sometimes it is good to know the length of a Python list. For that,
we use the len command. We actually saw this briefly on Page 150 when
talking about determining how many divisors a number might have.
print len(a)
print len(b)
The in command is used with Python lists and if statements to make
behavior dependent upon membership in a list. As you can see, 2 is a part
of our list a but not a part of our list b. Accordingly, the following lines
will return True and False respectively, as one would expect.
print 2 in a
print 2 in b
To access specific members of a list, we use the square brackets. Com-
puter scientists count from 0 and not from 1, for very hard to explain but
very good reasons having to do with memory locations. Therefore, the first
entry is entry 0, the second entry is entry 1, and third entry is entry 2, and
so forth. Interestingly, there are times when you want the last entry, or the
second to last entry, or the third to last entry. While I dont know of other
270 5. PROGRAMMING IN SAGE AND PYTHON
Youre might be wondering why we checked the lengths of the lists and
why we raise an exception if they are of dierent length. Lets say that I
have a list with 5 items in it. When I ask for names[0] or names[1], the
number in the square brackets is called an index (plural: indices). Because I
have five items, the valid list indices are 0, 1, 2, 3, 4. Also, because Python
allows negative indices, I can ask for -1, -2, -3, -4, and -5. The natural
numbers count from first to last, and the negative integers count from last
to first. What is forbidden is to ask for indices that are greater than or
equal to 5. If the length of one list is dierent from the length of another
list, then the last index will ask for something which does not exist in the
shorter list. This will generate an exception (even if we didnt use raise),
and would halt the program.
To test the above phenomenon, add a name to the end of the names list,
and call the subroutine again. The subroutine would raise an exception
and the program stops. Now backspace over the if statement that checks the
lengths, and the raise statement after it. See how the subroutine behaves
now, when you tack on a spurious name. An error message will be generated
either way. However, using an if followed by a raise, you can make the
error message human readable.
for g in grades:
if ((g<0) or (g>100)):
raise RuntimeError(Invalid grade in list!)
total = total + g
if (g < lowest_seen):
lowest_seen = g
5It should be noted that some UK universities have adopted the American model.
Furthermore, I know that German universities often have weekly written problem sessions
in their mathematics classes too, which are basically the same concept as our weekly or
biweekly quizzes.
274 5. PROGRAMMING IN SAGE AND PYTHON
denominator = len(grades) - 1
return N(numerator/denominator)
First, you might be surprised at the line:
for g in grades:
which is a dierent sort of syntax for the for loop than weve seen so far.
Here, we are saying that g should take the value of each of the members of
the list grades exactly once.
As you can see, we raise an exception if a grade is less than zero or over
100%. Weve used the keyword or here, which means that the if statement
will trigger if either g < 0 or if g > 100. In other situations, you can use the
and command similarly.
We also have an accumulator, called total. The lowest seen needs a
bit of explanation. If we are in the middle of a loop, and see a grade g lower
than lowest seen, then we need to update lowest seen to be this very
low value of g. When the loop is finished, then surely lowest seen is the
lowest g value that we ever saw.
The only thing left is to choose a value for the start of the subroutine.
I chose 101, because no grades will be over 100. Alternatively, if a grade
over 100 is found, the subroutine will raise an exception. I am always
guaranteed to find a grade in the list such that the grade is lower than 101.
This way, lowest seen will always be one of the grades in the listand in
fact, it will be the lowest.
You can test the above subroutine with the following output.
averageGrades( [ 100, 80, 90, 70, 80, 90 ] )
We get the score of 88 as we expected.
lists are of unequal size, then raise an exception. If the lists are of equal
size, call your previously written subroutine for each student in the list. A
report should be generated that shows the students name, their GPA, and
lastly, their fate. You might have to modify your old subroutine slightly to
accommodate this.
for x in answers:
print x
That would print all nine complex roots, namely
{0, 1, 2, 3, 4, 2i, i, i, 2i}
but maybe we dont want to see the imaginary roots. We can try the fol-
lowing instead
f(x)=x^9-10*x^8+40*x^7-100*x^6+203*x^5-290*x^4+260*x^3-200*x^2+96*x
answers = solve( f(x) == 0, x )
for x in answers:
if (x.rhs() in RR):
print x
which will restrict us to the real roots only, excluding the four purely imag-
inary roots.
By the way, rhs() stands for right hand side. The left hand side would
be accessible by lhs() but would be useless in this case, since it would just
be x.
6In fact, if you know about the dierent sizes of infinity, R and C are the larger
kind of infinity or uncountably infinite, sometimes called @1 . On the other hand, Q
and Z are the smaller kind of infinity or countably infinite, sometimes called @0 . The
symbol @ is the Hebrew letter called aleph.
276 5. PROGRAMMING IN SAGE AND PYTHON
Building Interactive
Webpages with Sage
In this chapter, were going to learn how to construct an interactive webpage,
sometimes called an interact or an app, that can be posted to the web.
Unlike other uses of Sage, this particular feature is quite powerful for a simple
reason: anyone with access to the internet can find your interactive webpage.
Without any knowledge of Sage, or even much knowledge of mathematics,
they can move some sliders around and see how a graph changes, or watch
some other sort of mathematical concept unfold. Since many students are
visual learners, this concept of an interactive webpage can be of phenomenal
assistance to those who would otherwise be struggling to learn some chunk
of mathematics.
For example, students in low-level classes (at the university or even high
schools and middle schools) can be given the URL, and students can begin
using the interactive webpage with very little intervention of the teacher.
No experience with Sage or any other computer algebra software is needed.
In fact, most students will have no idea that Sage was ever involved at all.
Personally, I had been involved with Sage for 5 years and 10 months
before I learned how to make interacts over the 20122013 winter break.
When I finally did, I was amazed at how easy it is to actually do this. Had I
realized earlier how easy it is to make interactive webpages, I would certainly
have begun many years previously.
Our Examples
This chapter will make reference to five diverse but elementary mathematical
examples:
Tangent Line: This is our primary example. I will build this inter-
act up slowly from scratch as we go through the main body of the
chapter. The goal is to draw a moving tangent line to a simple
second-degree polynomial. I will highlight how I built this applet
by using my six-stage process.
281
282 6. BUILDING INTERACTIVE WEBPAGES WITH SAGE
First, I want to find the best example possible for communicating the
mathematical ideait should not be too complex but it also should not
be too simple. In this case, we want to draw a tangent line and show an
early calculus student (perhaps less than three weeks into the course) what
a tangent line looks like. Therefore, it is pedagogically useful to choose the
drawn function to be something extremely simplelike a polynomial. Ive
chosen the function f (x) = x3 x.
Second, I try to focus on what the user can change, and what the user
should not be permitted to change. These will become the sliders in the
interact. The user should be able to change the x-coordinate of the point
where the tangent line is drawn, but not the y-coordinate, which should be
computed by the interact. In this way, the user will never choose a point
that is not on the curve y = x3 x.
Third, I often like to make a sketch of what the output will look like. I
ask myself how I can optimally display the circumstances to show sufficient
detailbut not so much detail as to confuse the student. Now that my
concept is finalized, I can log into SageMathCloud and begin work.
f(x) = x^3 - x
b = y_0 - m*x_0
P = P1+P2+P3
P.show()
return
the user see where they should be looking. I chose the color red, because
it usually signifies something important. Recall that superimposing plots in
Sage is done by adding them. Therefore, I add these three plots together.
Last but not least, I have to show the superimposed plot, and finally
the subroutine has concluded. This conclusion is marked with a return
command.
If you need some reminders about adding plots, to accomplish superim-
position of plots, see Page 18. For reminders about the point command,
see Page 15.
f(x) = x^3 - x
b = y_0 - m*x_0
P = P1+P2+P3
P.show()
print
print "x_0 = ", x_0
print "y_0 = f(x_0) = ", y_0
print "m = f(x_0) = ", m
print "tangent line: y = (", m, ")*x + (", b, ")"
return
the way that the commas and quotes interact can be confusing. Dont let
that be a barrier for you nowit is not important to our progress here.
Next, I reissued the x = 0.5, x = 1.5, and x = 1.75 test cases. They
look much better now, so it is time for Stage 3.
@interact
def tangent_at_point( x_0 = slider(-2, 2, 0.1, -1.5,
label="x-coordinate") ):
y_0 = f( x_0 )
First, you can see that Ive added the @interact command, on a line by
itself, above the def command that starts our subroutine. This command
signals Sage that we are creating an interact.
Second, and this requires a bit of explaining, I have used the slider
command to change x0 from a numerical input into a slider that the user
can manipulate. The first two parameters tell Sage that the x0 variable will
be restricted to the interval 2 x 2. The third parameter tells Sage the
granularity of the slider. In this case, we want each move to represent 1/10.
Thus if the slider is at x0 = 0.5, the two positions to either side would be
0.4 and 0.6. The fourth parameter represents the initial condition. In this
case, the slider will start out with x0 set to 1.5, but the user can move it
around to other values. Finally, the fifth parameter (which is optional) will
give a human-readable label to the slider.
Third, inside of SageMathCloud, I am no longer going to call the sub-
routine with commands like tangent at point( -1.75 ). Instead, I will
type tangent at point(). This is because I am not passing x0 as a number
to the subroutine, but rather using a slider to change that value often.
At this point, we have an interactive subroutine inside of SageMath-
Cloud. We should take a moment to play around with it, and see how it
works. Note that when you click and drag the slider around, you must let
go of the mouse button (or touchpad) before the interactive subroutine will
react.
So you can see what it will look like, Ive put a screen capture of the
interact in Figure 3.
f (t) = A sin(!t)
(4) which they will be able to solve after completing that course (or
completing that unit of the course).
The course in this case is Calculus I and the unit is optimization. Here,
we present a problem where the dimensions for the design of an aquarium are
required. The goal is to make a 64,000 cubic inch aquarium, with length-to-
width ratio of 2.0, but minimum costs. The costs of the top of the aquarium
are 0.5 cents per square inch, the sides are 5 cents per square inch, and the
bottom is 1.3 cents per square inch. The design of the aquarium2 must meet
the two requirements of volume and length-to-width ratio (to the nearest
1%) but should do so with minimal cost.
Of course, this problem is easy to solve with calculus but the goal is to
show that it is hard to solve without it, by intuition alone. One imagines
a classroom full of students, most of whom wont be able to simultaneously
address the volume and length-to-width ratio requirements. Of those stu-
dents who have satisfied both requirements, most of them will stop at that
point, ignoring the cost minimization. Then one can ask students what costs
they managed to obtain, and it will become clear that the cost is not the
same for all students. Next, the professor might state the optimal solution
so that many of the students can see that it is indeed cheaper than their
own, but perhaps not by much. Last but not least, the professor should
solve the problem with explicit algebra and calculus, several lessons later,
when the unit on optimization has been completed.
show(P)
We see two new commands. First, selector will make a pull-down menu
with choices being the three polynomials shown in the code. The label will
2For a class with middle-aged students who are going back to school, the same
problem can be posed in the guise of designing a cheaply manufactured warehouse with
costs for the floor, roof, and walls.
292 6. BUILDING INTERACTIVE WEBPAGES WITH SAGE
be the word Polynomial: so that the user knows the purpose of the pull-
down. (I suppose in this case that was obvious, but perhaps in other cases
it is not obvious.)
Second, we have an optional parameter show grid that is defaulting to
False, just as we had verbose default to False on Page 246. Whenever you
have an optional parameter in a Sage interact that can be True or False,
Sage knows that you want to have a box that can be checked or unchecked.
The plot of our selected polynomial will be drawn with or without gridlines,
depending on whether show grid is True or False. The rest of the code is
nothing new for us.
Figure 4 has a screen capture of this applet, but note that the checkbox
has been eclipsed by the pull-down menu.
(signed) area that the applet computes to have the opposite sign, because
Z b Z a
f (x) dx = f (x) dx
a b
Second, Sage reacts badly if the area to be shaded has zero area. In other
words, if a = b, the fill-commands used by the integral plotting technique
are confused, and generate an error message. Therefore, I artificially modify
the width to have 10 12 more than it should. Therefore, the width is never
zero, and the complaint is suppressed.
Finally, I decided to add a large arrow. If the bounds are in the normal
order, left-to-right, then I draw a green arrow in that direction; if the bounds
are backwards, or right-to-left, then I draw a red arrow pointing right-to-
left. This will help explain to students what happens if you interchange the
bounds of integration.
As you can see, some of these changes are a bit unexpected. Therefore,
I thought it prudent to include all the code (for all the intermediate stages)
so that you can read how things progressed.
294 6. BUILDING INTERACTIVE WEBPAGES WITH SAGE
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>blah YourTitleGoesHere, for the first time</title>
<script src="https://sagecell.sagemath.org/static/jquery.min.js"></script>
<script src="https://sagecell.sagemath.org/embedded_sagecell.js"></script>
<script>
$(function () {
// Make *any* div with class compute a Sage cell
sagecell.makeSagecell({inputLocation: div.compute,
template: sagecell.templates.minimal,
evalButtonText: Launch the Interactive Applet Now});
});
</script>
</head>
<body style="width: 1000px;">
<hr>
<h2>Overview</h2>
<p>blah blah blah</p>
<p>yada yada yada</p>
<p>blah blah blah</p>
<h2>Instructions</h2>
<p>blah blah blah</p>
<p>yada yada yada</p>
<div class="compute">
<script type="text/x-sage">
##
## You should cut-and-paste your Sage interactive function here.
##
</script>
</div>
<h2>Discussion</h2>
<p>blah blah blah</p>
<p>yada yada yada</p>
<p>blah blah blah</p>
<hr>
Last modified on PutTheDateHere.
</body>
</html>
What to Do When
Frustrated!
Computers are unforgiving when it comes to syntax. For users unaccus-
tomed to that stricture, it can be very frustrating. Here I have listed for
you a checklist of tips that you should use when Sage is rejecting your code
for reasons that you cannot determine. I hope that these 16 questions will
cover most cases.
At this particular moment (July 18th, 2014) this will work in SageMath-
Cloud, but not in the Sage Cell Server. Note that the definition of g above
does not have an asterisk between the 3 and the first x nor between the 2
and the second x. Because we are in implicit multiplication mode, those
two missing asterisks are forgiven.
It is most likely that the error is in your code (the last lines printed)
or possibly in Sage (the next batch of lines). The packages in Sage (e.g.
Maxima, Singular, GAP, and so forth) are very well tested and debugged
those are the top two-thirds of the mess of lines. This is why you should
look at the last few lines to get information to help you figure out whats
wrong. Often the last line is the most informative.
site that you havent visited in this particular web session, and youll see the
re-authentication page. Once youve re-authenticated with whatever code is
needed, you can use Sage freely again, as normal.
Transitioning to
SageMathCloud
Chapter 1 of this book assumes you are using the Sage Cell Server. Thats
great for small and even some medium-sized tasks. However, you will want
to switch to SageMathCloud eventually. Generally, if you are writing code
of more than 20 lines, you definitely want to switch to SageMathCloud. If
you are writing code of between 1020 lines, you probably want to switch
to SageMathCloud anyway. The Sage Cell Server is meant for simple tasks.
have to know where that server was (and its URL). Then all your
files are still on your usual machine, perhaps in Wisconsinyoud
have to move those files yourself. All this would be a hassle. Cloud
computing is the exact oppositeif one server is busy, your compu-
tational job will automatically be sent somewhere else, and youd
never even know.
Simplicity: Since all the servers are administered by the SageMath-
Cloud community, small liberal arts colleges do not need to worry
about buying a server, maintaining it, or updating the software.
All the software is up-to-date all the time, and no university need
take any special step, nor purchase additional equipment.
Cost Savings: There are several reasons why Cloud Computing is
extremely cost eective. Normally, computing resources are not
used during the hours when college students and mathematicians
are asleep3 am to 9 am. Now that all the cloud machines around
the world are serving the entire world all the time, timezones no
longer matter. The problem with old way of doing thingswhere
major universities would each have their own serveris that you
cant buy 0.1 servers. The lowest cost would be to buy 1 server, but
perhaps a small liberal arts college only needs 0.05 servers worth of
computing power. By aggregating services, this eectcalled the
cost of indivisibility in mathematical economicsis mitigated.
Collaboration: SageMathCloud has many useful collaborative fea-
tures, such as making projects public/private, visible to other spe-
cific users, and online chat tools.
Checkpointing: Unless you delete a file, Sage retains not only all of
your files forever, but it also takes snapshots and has all previous
versions of all files. Therefore, if you screw something up, you can
revert to an old version.
A Sage worksheet is like a sequence of giant cells from the Sage Cell
Server. You can type some lines of code, and then press control-enter (which
is analogous to pressing Evaluate in the Sage Cell Server. When you
press control-enter, a horizontal line is drawn. Everything since the previous
horizontal line (or the top of the sheet) is then evaluated as if it were a Sage
cell on the Sage Cell Server.
Because Sage worksheets are files, you can have many of them, copy
them, rename them, move them, and delete them.
This is better explained with a video. The first few minutes of this
video are an overview of what Sage is about in general. After that, a demo
of SageMathCloud is given. The video was made by Prof. William Stein,
the founder and chief architect of Sage and the author of SageMathCloud.
https://www.youtube.com/watch?v=6UGvrVpP89Q
1Funding provided by the National Science Foundation under grant DUE 0817071.
C. OTHER RESOURCES FOR SAGE 307
URL as the above tutorial, but they are listed at the bottom of the
page as appendices to it.
http://www.sagemath.org/doc/prep/index.html
Books that Use Sage: At the time of the publication of this book,
there are 24 listed books on the Sage website that use Sage for
their examples. Of course, some of this are about exotic research-
oriented topics meant for PhD-students in mathematics. However,
several of them are entirely suitable for undergraduates. Here is
the URL with the entire collection.
http://www.sagemath.org/library-publications.html#books
We see here that there are rows of zeros, and we do not see the familiar
and welcome main diagonal of ones. The 4 4 identity matrix is miss-
ing. Therefore, we are on alert for the possibility of an infinite number of
solutions.
There is a systematic way of addressing this situation. First, were going
to identify special entries of the matrix called pivots or anchors. Then,
we will classify each variable as either free or determined. Third, we will
rewrite the system of equations with all of the determined variables on one
side of the equal signs, and all the free variables as well as constants on the
opposite side. Once this is done, we will have identified each of the infinitely
many solutions to this system of equations.
Were going to call the left-most non-zero entry of each row an anchor
or a pivot. Row 1 has as its pivot A11 and Row 2 has as its pivot A23 .
Since Row 3 and Row 4 have no non-zero entries (properly, we should say
because they are all-zero rows), they have no pivots. Often, when I work
with pencil and paper, I will circle or underline the entries of a matrix that
are pivots. In this case, I would circle or underline the entry in the top row,
first column (A11 ) and the entry in the second row, third column (A23 ).
As we have now learned, each column in a matrix represents a variable,
except the rightmost column, which represent the constants. Of course, each
column either contains a pivot or it does not contain a pivot. Any column
(but not the rightmost) is to be called eective and its variable called
determined if the column has a pivot. Likewise, any column (but not the1
rightmost) is to be called defective and its variable called free if the
column does not have a pivot.
The rule of the previous paragraph may appear to be rather arbitrary
and somewhat confusing, but let us just work with it once and see what it
does for us. We will go one column at a time.
In Column 1, we have a pivot. Therefore, Column 1 is eective and
w is a determined variable.
In Column 2, we do not have a pivot. Therefore, Column 2 is
defective and x is a free variable.
In Column 3, we have a pivot. Therefore, Column 3 is eective and
y is a determined variable.
In Column 4, we do not have a pivot. Therefore, Column 4 is
defective and z is a free variable.
See, that wasnt so bad, right? Now were going to take the RREF,
translate the (non-zero) rows back into algebra, and then move the constants
and free variables to the right of the equal sign, leaving only determined
variables on the left of the equal sign. First, the literal or non-interpreted
1For the very curious: the eective/defective terminology is not used on the rightmost
column because that column does not represent a variable at all. Thus it does not make
sense to discuss if the variable of that rightmost column is free or determined.
D.1. THE OPENING EXAMPLE 311
w=8-2*pi-4*sqrt(2)
x=pi
y=-3-3*sqrt(2)
z=sqrt(2)
print 20*w + 40*x + 2*y + 86*z
print 4*w + 8*x + 5*y + 31*z
print w + 2*x + 3*y + 13*z
print -8*w - 16*x - 4*y - 44*z
As you can see, we get the output that we wanted: 154, 17, 1, and 52.
3w 3y + 6z = 51
x + 4y + 5z = 19
w + x + 5y + 3z = 2
2w + 5x + 18y + 29z = 129
First, we identify the pivots. As you can see, I have marked them with
?s. Second, we must classify the variables as free or determined. In
this case, since w and x have pivots, thus they are determined variables;
likewise, y and z do not have pivots, so they are free variables. Now we
write down the uninterpreted literal translation of the RREF matrix into
algebra, skipping the all-zero rows
w y + 2z = 17
x + 4y + 5z = 19
D.2. ANOTHER EXAMPLE 313
Finally, we move the free variables (y and z) to the right of the equal
sign, and obtain
w = 17 + y 2z
x = 19 4y 5z
y is free
z is free
Perhaps if we were asked to find four distinct solutions, we could write:
(1) If y = 0 and z = 0 then w = 17 and x = 19.
(2) If y = 0 and z = 1 then w = 15 and x = 14.
(3) If y = 1 and z = 0 then w = 18 and x = 15.
(4) If y = 1 and z = 1 then w = 16 and x = 10.
Challenge Yourself:
Here are four easy examples which you can use to challenge yourself, to see
if youve got this right. The final few equations with the word free are
given at the end of this appendix. You should also generate 34 specific
2The word degenerate isin the modern eraextremely rude. However, at one time
it must have been polite, or at least socially acceptable. The word was used in the third
quarter of the twentieth century to describe any person who was significantly dierent
from societal norms. Here, a normal linear system of equations is one with a unique
solution. Any deviation from that expected behavior is termed degenerate.
314 D. LINEAR SYSTEMS WITH INFINITELY-MANY SOLUTIONS
solutions, and see if they actually work or not. We will provide a specific
solution where all the free variables are set to 1.
2 3 2 3
1 2 1 0 1 1 3 0 0 1
6 3 6 3 2 7 7 6 3 9 2 0 7 7
M1 = 6
4 2 4
7 M2 = 6 7
2 1 0 5 4 2 6 1 4 32 5
7 14 7 6 19 7 21 6 5 59
2 3 2 3
4 20 24 16 1 2 3 7
M3 = 4 7 35 42 28 5 C2 = 4 4 5 6 16 5
1 5 6 4 7 8 9 25
By the way, thats the same C2 that we saw back on Page 29. At that
time, we computed that C2.rref() equals
[ 1 0 -1 -1 ]
[ 0 1 2 4 ]
[ 0 0 0 0 ]
and then we stopped and said there are infinitely many solutions. How-
ever, now Id like you to produce equations with free and determined vari-
ables as weve done throughout this appendix.
Again, I have marked the pivots with ?s. As you can see, all the columns
are elementary and none are degenerate. All the variables are determined,
and none of them are free. For this reason, we have one and only one
solution:
0 0 0 0
As you can see, there are three pivotswhich I have marked with ?s.
Therefore, each of the variables is determined, and none of them are free.
Finally, we conclude that there is a single solution, with x = 5, y = 1, and
z = 8. Note there is one unique solution, despite the presence of a row of
all zeros.
D.4. Misconceptions
Now Id like to briefly address a few misconceptions that students often have
about this topic of infinitely many solutions to a linear system of equations.
A Major Misconception:
Frequently, students imagine that if there is a row of zeros, then there will be
infinitely many solutions. However, we saw in Section D.3.2, a case where
a matrix had no row of zerosbut it had infinitely many solutions. In
Section D.3.4, we saw a case where the matrix had a row of zeros, but it
had exactly one solution. Therefore, what does a matrix tell you, when one
of the rows is all zeros?
If you have the same number of variables as equations, then you can
use the rule of thumb from Section 1.5.8 on Page 28. Otherwise, the row
of zeros tells you absolutely nothing. Instead, you must identify the pivots,
and then determine which variables are free and which are determinedas
weve been doing throughout this appendix.
D.5. FORMAL DEFINITIONS OF REF AND RREF 317
As you can see, the column for each variable is zero everywhere, except
for a single one. A student with this misconception would imagine that each
variable is determined, and that none are free. This confused student would
say there is one single solution: x = 3, y = 2, and z = 0. However, thats
clearly false.
In particular, I draw your attention to the third column, where there is
a single 1 and all the entries are zero. That column looks to be elementary,
but because that lonesome 1 is not a pivot, the column is not elementary,
but is instead degenerate. Here you can see the genuine value of marking
the pivots with ?s. The pivots in this matrix are Q11 and Q22 , yet Q13 is
not a pivot. Clearly, column three has no pivot. Therefore, z is free. We
should write
x = 3 z
y = 2
z is free
intersect. The other minor case is when both lines are actually the same
line, and there is an infinite number of solutions.
When you have a system of three linear equations and three variables,
you are intersecting three planes in ordinary space. Usually, the three planes
will intersect at a common point, but once again, there are the minor cases.
This time there are 4 minor cases.
The first is that it is possible that the three planes never have a
point in common: much like two opposite walls of a rectangular
room and the roof of that room. Since the two opposite walls are
parallel, they never have a point in common.
The second is when the three planes have a line in common. Imag-
ine a hardcover book that doesnt have too many pages, partially
open, with very sti pages. The three planes can be any of the very
sti pages, or either of the covers. Furthermore, these planes have
the spine of the book (which is a line) in common.
The third or truly rare case for three variables is when all three
planes are actually the same plane, and any point in that plane
solves all three equations. However, that does not mean that every
point in three-dimensional space is a solution. Rather, a point has
to be in the plane to be a solution.
A fourth (non-sense) case is the following matrix:
2 3
0 0 0 0
4 0 0 0 0 5
0 0 0 0
where each of the three equations is actually the trivial equation:
0x + 0y + 0z = 0
and therefore every point in 3-dimensional space satisfies these
equations. The solution space is our entire 3-dimensional uni-
verse.
case, we use the matrix C2 which appeared on Page 29 and Page 314; for
the two degrees of freedom case, we use the matrix M3 from Page 314.
department chairs and Deans on that basis, and so they can use the difficulty
of using mandatory computer software as a basis for complaint. For example,
But, Dean XYZ, you dont understand, I couldnt even get the computer
program to install!
Index of Commands by
Name and by Section
Here we have a comprehensive index of all the commands in this book.
First, we present them sorted thematically (by section). Second, we present
them sorted alphabetically, by name. Many thanks to Thomas Suiter, who
compiled this index.
327
Section Command Description
328
1.12 numerical integral Calculates the integral numerically, outputting the best guess first and the
uncertainty second
1.12 partial fraction Computes the partial fractions of a complicated rational function
1.12 erf Standing for Error Function, sometimes called the Gaussian or Normal
Distribution
1.12 assume Allows user to declare an assumption
329
330
2.4.3 lcm Finds the least common multiple of two numbers (See also 4.6.1)
2.6.1 factorial Takes the factorial of any non-negative integer
2.6.2 mod Take modular reduction only of the nearest number (See also 4.6.6)
4.6.3 euler phi Returns how many positive integers (from 1 to n) are coprime to n.
4.6.4 sigma Returns the sum of the positive integers which divide the given positive
integer
4.6.4 len Returns the length of any list
4.6.6 mod Take modular reduction only of the nearest number (See also 2.6.2)
4.7 min Returns the smallest number in the list
331
4.7 max Returns the largest number in the list
332
4.7.1 floor Sometimes called The Greatest Integer Function, this function rounds x
down
4.7.1 ceil Sometimes called The Least Integer Function, this function rounds x up
4.7.2 binomial Computes the binomial coefficient or choose function for combinations
4.7.2 list Returns a list of what is being asked
4.7.2 Permutations The input is a list of items; the output is a list of all possible permutations
of that list.
4.7.3 sinh Calls the hyperbolic trigonometric function of sine in radians
4.7.4 cosh Calls the hyperbolic trigonometric function of cosine in radians
4.7.5 tanh Calls the hyperbolic trigonometric function of tangent in radians
4.7.5 coth Calls the hyperbolic trigonometric function of cotangent in radians
4.7.5 sech Calls the hyperbolic trigonometric function of secant in radians
4.7.5 csch Calls the hyperbolic trigonometric function of cosecant in radians
4.7.5 arcsinh Calls the inverse hyperbolic trigonometric function of sine in radians
4.7.5 arccosh Calls the inverse hyperbolic trigonometric function of cosine in radians
4.7.5 arctanh Calls the inverse hyperbolic trigonometric function of tangent in radians
4.7.5 arccoth Calls the inverse hyperbolic trigonometric function of cotangent in radians
4.7.5 arcsech Calls the inverse hyperbolic trigonometric function of secant in radians
4.7.5 arccsch Calls the inverse hyperbolic trigonometric function of cosecant in radians
4.7.5 asinh Shorthand notation for the arcsinh function
4.7.5 acosh Shorthand notation for the arccosh function
4.7.5 atanh Shorthand notation for the arctanh function
4.7.5 acoth Shorthand notation for the arccoth function
4.7.5 asech Shorthand notation for the arcsech function
4.7.5 acsch Shorthand notation for the arccsch function
4.8 limit Used to take the limit of a function
F. INDEX OF COMMANDS BY NAME AND BY SECTION
4.9 scatter plot Plots all of the predefined data points onto a graph (see Section 4.9 also)
4.10 find fit Finds the best fit line for a list of data points
4.11 hex Converts the number into hexadecimal
4.11 bin Converts the number into binary
4.11 oct Converts the number into octal
4.11 int Rounds down to the nearest integer
4.12 sudoku Finds a solution to the sudoku puzzle
4.13 timeit Times how long it takes Sage to calculate the solution
4.15 latex Returns the solution written in LATEX
4.16.2 eigenvalues Calculates the eigenvalues corresponding to a linear system of equations
4.16.2 eigenvectors right Given A, returns a vector ~v such that A~v = k~v for some scalar constant k.
4.16.2 eigenvectors left Given A, returns a vector ~v such that ~v A = k~v for some scalar constant k.
4.16.2 charpoly Calculates the characteristic polynomial
4.16.2 minpoly Calculates the minimum polynomial
4.16.3 as sum of permutations This function is one of 14 built-in matrix factorizations.
4.16.3 cholesky This function is one of 14 built-in matrix factorizations.
4.16.3 frobenius This function is one of 14 built-in matrix factorizations.
4.16.3 gram schmidt This function is one of 14 built-in matrix factorizations.
4.16.3 hessenberg form This function is one of 14 built-in matrix factorizations.
4.16.3 hermite form This function is one of 14 built-in matrix factorizations.
F. INDEX OF COMMANDS BY NAME AND BY SECTION
6.1 @interact Tells Sage you want an interact (interactive webpage) created
6.1 slider Creates a slider for a subroutines input in an interactive webpage
6.5 selector Creates a small pull-down menu in an interactive webpage, that a user can
choose an item from
F. INDEX OF COMMANDS BY NAME AND BY SECTION
C implicit multiplication Allows you to use 5x+6y in place of the usual 5*x + 6*y
335
Section Command Description
336
6.1 @interact Tells Sage you want an interact (interactive webpage) created
1.4 abs Returns the absolute value of a real number
1.3 acos Shorthand notation for the arccos function
4.7.5 acosh Shorthand notation for the arccosh function
1.3 acot Shorthand notation for the arccot function
4.7.5 acoth Shorthand notation for the arccoth function
1.3 acsc Shorthand notation for the arccsc function
4.7.5 acsch Shorthand notation for the arccsch function
4.21.1 add constraint Used to add the constraints to a linear program
5.7.5 and Compares two logic statements to check if both statements are true
5.7.1 append Adds a new item to the end of the list
1.3 arccos Calls the inverse trigonometric function of cosine in radians
4.7.5 arccosh Calls the inverse hyperbolic trigonometric function of cosine in radians
1.3 arccot Calls the inverse trigonometric function of cotangent in radians
4.7.5 arccoth Calls the inverse hyperbolic trigonometric function of cotangent in radians
1.3 arccsc Calls the inverse trigonometric function of cosecant in radians
4.7.5 arccsch Calls the inverse hyperbolic trigonometric function of cosecant in radians
1.3 arcsec Calls the inverse trigonometric function of secant in radians
4.7.5 arcsech Calls the inverse hyperbolic trigonometric function of secant in radians
1.3 arcsin Calls the inverse trigonometric function of sine in radians
4.7.5 arcsinh Calls the inverse hyperbolic trigonometric function of sine in radians
1.3 arctan Calls the inverse trigonometric function of tangent in radians
4.7.5 arctanh Calls the inverse hyperbolic trigonometric function of tangent in radians
3.1.3 arrow Draws an arrow directly on a graph
4.16.3 as sum of permutations This function is one of 14 built-in matrix factorizations.
F. INDEX OF COMMANDS BY NAME AND BY SECTION
1.3 asec Shorthand notation for the arcsec function
4.7.5 asech Shorthand notation for the arcsech function
1.3 asin Shorthand notation for the arcsin function
4.7.5 asinh Shorthand notation for the arcsinh function
1.12 assume Allows user to declare an assumption
1.3 atan Shorthand notation for the arctan function
4.7.5 atanh Shorthand notation for the arctanh function
4.4.3 augment Adds onto a predefined matrix
3.1.1 axes labels Labels the axes directly on a graph
4.11 bin Converts the number into binary
4.7.2 binomial Computes the binomial coefficient or choose function for combinations
5.6.3 break Exits the current loop statement
4.7.1 ceil Sometimes called The Least Integer Function, this function rounds x up
4.16.2 charpoly Calculates the characteristic polynomial
4.16.3 cholesky This function is one of 14 built-in matrix factorizations.
4.20 continued fraction Computes the continued fraction expansion of a real number.
3.5 contour plot Takes a function with two variables and plots contour curves (level sets) of
that function
1.3 cos Calls the trigonometric function cosine in radians
4.7.4 cosh Calls the hyperbolic trigonometric function of cosine in radians
1.3 cot Calls the trigonometric function cotangent in radians
F. INDEX OF COMMANDS BY NAME AND BY SECTION
equation
4.4.6 det Calculates the determinant of a predefined matrix
1.11 di Takes the derivative by specifying the function in terms predefined vari-
able(s)
1.7 divisors Returns a list of all the positive integers that divide into the original integer
4.5 dot product Calculates the dot product of a set of vectors
4.4.3 echelon form A half-completed version of RREF
4.16.2 eigenvalues Calculates the eigenvalues corresponding to a linear system of equations
4.16.2 eigenvectors left Given A, returns a vector ~v such that ~v A = k~v for some scalar constant k.
4.16.2 eigenvectors right Given A, returns a vector ~v such that A~v = k~v for some scalar constant k.
5.5.2 else Used in conjunction with the if-then statement, it handles when the if
statement is false
1.12 erf Standing for Error Function, sometimes called the Gaussian or Normal
Distribution
4.6.3 euler phi Returns how many positive integers (from 1 to n) are coprime to n.
1.2 exp An abbreviated notation when dealing with exponentials, namely ex
1.7 expand Gives the expanded form of a polynomial (or rational function) without
parentheses
1.7 factor Gives a factored version of a polynomial or an integer
2.6.1 factorial Takes the factorial of any non-negative integer
4.10 find fit Finds the best fit line for a list of data points
1.9 find root A numerical approximation of f (x) = 0
4.7.1 floor Sometimes called The Greatest Integer Function, this function rounds x
down
5.1.1 for Used to create a for loop statement
4.16.3 frobenius This function is one of 14 built-in matrix factorizations.
F. INDEX OF COMMANDS BY NAME AND BY SECTION
4.22.1 function Declares a new unknown function
1.7 gcd Computes the greatest common divisor of two polynomials or numbers
4.21.1 get values Used to obtain the values of variables in a linear program
4.16.3 gram schmidt This function is one of 14 built-in matrix factorizations.
4.16.3 hermite form This function is one of 14 built-in matrix factorizations.
4.16.3 hessenberg form This function is one of 14 built-in matrix factorizations.
4.11 hex Converts the number into hexadecimal
4.4.2 identity matrix Creates the identity matrix of size n
5.4.1 if Used for creating if-then statements
C implicit multiplication Allows you to use 5x+6y in place of the usual 5*x + 6*y
3.4 implicit plot Takes a function with two variables and plots the graph f (x, y) = 0
5.7.3 in Returns true or false, to test if an element is in a given set, or not.
4.11 int Rounds down to the nearest integer
1.12 integral Takes the integral by specifying the function in terms predefined variable(s)
1.12 integrate A synonym for integral
4.4.4 inverse Computes the inverse of a predefined matrix
4.23.3 inverse laplace Calculates the inverse Laplace transform
4.6 is prime Test the number for primality
4.16.3 jordan form This function is one of 14 built-in matrix factorizations.
4.23.1 laplace Calculates the Laplace transform
4.15 latex Returns the solution written in LATEX
F. INDEX OF COMMANDS BY NAME AND BY SECTION
2.4.3 lcm Finds the least common multiple of two numbers (See also 4.6.1)
4.6.1 lcm Finds the least common multiple of two numbers (See also 2.4.3)
4.4.5 left kernel Computes the set of vectors n such that ~nA = ~0, for a matrix A
4.4.5 left nullity Computes the dimension of the set of vectors n such that ~nA = ~0, for a
matrix A.
4.6.4 len Returns the length of any list
339
5.7.10 lhs Given an equation, this returns the left hand side of that equation as an
340
expression
4.8 limit Used to take the limit of a function
4.7.2 list Returns a list of what is being asked
1.2 log Computes any logarithm, but takes the natural logarithm by default
4.16.3 LU This function is one of 14 built-in matrix factorizations.
1.5.3 matrix Used to define a matrix, given the number of rows, number of columns, and
its entries
4.7 max Returns the largest number in the list
4.7 min Returns the smallest number in the list
4.18.1 minimize Finds the minima of a function
4.16.2 minpoly Calculates the minimum polynomial
4.21.1 MixedIntegerLinearProgram Used to initialize either a linear program or mixed integer linear program
2.6.2 mod Take modular reduction only of the nearest number (See also 4.6.6)
4.6.6 mod Take modular reduction only of the nearest number (See also 2.6.2)
1.2 N Returns a decimal approximation
4.21.1 new variable Used to create an infinite set of variables in a linear program
4.6 next prime Finds the next prime number greater than n
3.7.2 norm Computes the norm (or length) of a vector
4.6.2 nth prime Used to find the nth prime number
3.9.2 nth root A method of finding the nth real root (see Section 3.9.2)
1.2 numerical approx Returns a real number, if possible. Longhand for the command n
1.12 numerical integral Calculates the integral numerically, outputting the best guess first and the
uncertainty second
4.11 oct Converts the number into octal
5.7.5 or Compares two logic statements to check if either-or statements are true
3.6 parametric plot Takes two or three functions and plots a parametric curve
F. INDEX OF COMMANDS BY NAME AND BY SECTION
1.12 partial fraction Computes the partial fractions of a complicated rational function
4.7.2 Permutations The input is a list of items; the output is a list of all possible permutations
of that list.
1.4 plot Plots a given single-variable function in the coordinate plane
3.8 plot loglog Plots a given single-variable function in the coordinate plane with logarith-
mic scales
4.22.3 plot slope field Generates a slope field plot of the desired function
3.7 plot vector field Takes two functions with two dierent variables and plots vector arrows
3.7.1 plot3d Creates a 3D plot of a two-variable function
1.4 point Used to identify/mark a single point in a plot, by making a large dot there
3.3 polar plot Used to graph a function with polar coordinates
4.6 prime range Returns all of the prime numbers between the desired range
1.5.4 print Used to print information to the screen for the user
5.7.3 prod Multiplies all of the elements in the list
4.16.3 QR This function is one of 14 built-in matrix factorizations.
5.5.1 raise Used to cause an exception when dealing with errors
5.1.1 range Used as a shortcut for making a list of numbers
4.16.3 rational form This function is one of 14 built-in matrix factorizations.
3.9.2 real nth root [Currently proposed but does not yet exist] Computes the real nth root of a
number
5.7.3 remove Removes an item from the list
F. INDEX OF COMMANDS BY NAME AND BY SECTION
matrix A.
1.5.3 rref Computes the reduced row echelon form of the given matrix
5.5.1 RuntimeError Used to specify if there is an error when using the subroutine
3.8 scatter plot Plots all of the predefined data points onto a graph (see Section 4.9 also)
4.9 scatter plot Plots all of the predefined data points onto a graph (see Section 4.9 also)
1.10 search doc Searches Sage for all of the documentation strings regarding the specified
command
1.3 sec Calls the trigonometric function secant in radians
4.7.5 sech Calls the hyperbolic trigonometric function of secant in radians
6.5 selector Creates a small pull-down menu in an interactive webpage, that a user can
choose an item from
4.21.1 set objective Used to set the objective to a linear program
1.4.2 show Used when superimposing a large number of plots on top of one another
5.7.3 shue Randomizes all of the elements in the list
4.6.4 sigma Returns the sum of the positive integers which divide the given positive
integer
3.9.2 sign Returns either a negative or positive 1 depending on if x is negative or
positive, respectively
1.3 sin Calls the trigonometric function sine in radians
4.7.3 sinh Calls the hyperbolic trigonometric function of sine in radians
6.1 slider Creates a slider for a subroutines input in an interactive webpage
4.16.3 smith form This function is one of 14 built-in matrix factorizations.
1.8.1 solve Returns a symbolic solution to an equation or system of equations
4.4.3 solve left Solves the matrix-vector problem ~xA = ~b where ~x is unknown.
4.4.3 solve right Solves the matrix-vector problem A~x = ~b where ~x is unknown.
1.2 sqrt Computes the square root
F. INDEX OF COMMANDS BY NAME AND BY SECTION
4.12 sudoku Finds a solution to the sudoku puzzle
4.19 sum Used to take the summation of an expression (first shown in 3.5.1)
3.5.1 sum Used to take the summation of an expression (properly shown in 4.19)
4.16.3 symplectic form This function is one of 14 built-in matrix factorizations.
1.3 tan Calls the trigonometric function tangent in radians
4.7.5 tanh Calls the hyperbolic trigonometric function of tangent in radians
4.17.1 taylor Calculates the Taylor Polynomial approximation of a function
3.1.3 text Used to add words onto a graph
4.13 timeit Times how long it takes Sage to calculate the solution
4.16.4 transpose Finds the transpose of a particular matrix
1.8.1 var Declares a new variable to represent some unknown quantity
3.7.2 vector Creates a single mathematical vector
4.16.3 weak popov form This function is one of 14 built-in matrix factorizations.
5.6.1 while Used when creating a while loop statement
4.16.3 zigzag form This function is one of 14 built-in matrix factorizations.
F. INDEX OF COMMANDS BY NAME AND BY SECTION
343