ICERM Sage demo

112 days ago by jen

ICERM Complex and Arithmetic Dynamics Semester

Introduction to Sage 

February 1, 2012

Jennifer Balakrishnan (Harvard)

@interact #based on code by Harald Schilly def mandel_plot(expo = slider(-10,10,0.1,2), \ formula = ['mandel','ff'],\ iterations=slider(1,100,1,30), \ zoom_x = range_slider(-2,2,0.01,(-2,1)), \ zoom_y = range_slider(-2,2,0.01,(-1.5,1.5))): var('z c') f(z,c) = z^expo + c ff_m = fast_callable(f, vars=[z,c], domain=CDF) # messing around with fast_callable for i in range(int(iterations)/3): f(z,c) = f(z,c)^expo+c ff = fast_callable(f, vars=[z,c], domain=CDF) def mandel(z): c = z for i in range(iterations): z = ff_m(z,c) if abs(z) > 2: return z return z print 'z <-- z^%s + c' % expo # calling ff three times, otherwise fast_callable exceeds a recursion limit if formula is 'ff': func = lambda z: ff(ff(ff(z,z),z),z) elif formula is 'mandel': func = mandel complex_plot(func, zoom_x,zoom_y, plot_points=300, axes = False,ticks=[[],[]] ).show(frame=True, \ aspect_ratio=1,figsize=[4,4]) 
       
expo 
formula 
iterations 
zoom_x 
zoom_y 

Click to the left again to hide and once more to show the dynamic interactive window

During these two 1-hour talks, we'll give an overview of the computer algebra system Sage.  Since Sage is built on the programming language Python, some of the discussion will naturally involve Python. For more Python-related tutorials, check out the Beginner's Guide to Python.  

These notes will focus on some basic structures in Sage, some functions of mathematical interest, and some tools that might be helpful to know about as you write your own code.

Programming is best learned actively, so you are strongly encouraged to follow along on your own computer and try some of these examples yourself. To make this possible, we begin by explaining how to run Sage on your own computer. There are two natural ways to do this.

  • Since Sage is free for everyone, you may install Sage on your own computer and run it locally using the command line. Go to http://www.sagemath.org and follow the links to download and install Sage. (Warning: this is a bit tricky if you run Windows.)
  • Besides the command line, Sage also offers a graphical interface, the Sage Notebook, in which you use your web browser to access a Sage server on some possibly different machine. For example, this presentation is being served from a computer at ICERM running a Sage server. But you don't have to set up your own server to run Sage; there is a public notebook server on which anyone can create an account and run Sage! This is by far the easiest way to try out Sage right now. To do this, please go to http://www.sagenb.org and create an account. (For those of you with a wired connection to the ICERM notebook server, you can also create an account there: https://10.9.160.16:8000.)
  • Notebook worksheets can be published so that anyone can see them in a static form, even without running Sage. For instance, see http://sagenb.org/home/pub/4181/ for a published copy of this worksheet. Better yet, if you've created a notebook server account, you can click "Login to edit a copy" and then play with a copy of the worksheet yourself!

So, if you have a computer, start by getting a copy of this worksheet to follow along and edit. We'll be running the worksheet using the notebook interface, though of course, you can copy the relevant functions into the command line.

Using the Sage notebook

If you have successfully started a notebook session, you should see something that looks much like this window.

The box below is called a cell, and can be used to evaluate any Sage command. For example, try clicking on the cell, typing 2+2, and clicking "evaluate". (A shortcut for "evaluate" is Shift+Enter.)

2+2 
       
4
4

You'll see the answer appear in blue below the cell, and then a new cell is generated so that you can type another command. You can also go back and edit the previous cell, but the answer won't change until you evaluate again. You can even insert new cells between existing cells: if you click on the blue bar that shows up when you mouse between two existing cells, a new cell will pop up in between.

If you Shift-click instead, you get a text box like this, which supports some formatting and even basic TeX commands (e.g., x^2 vs. x^2). Once you click "save changes," you can double click back on the text box to resume editing.

For basic code-commenting, use the # symbol.

2+2 # this should evaluate to 4 
       
4
4

Besides individual calculator-style expressions, a cell can contain a sequence of instructions. The last expression is evaluated and printed; you can also add "print" commands to force additional printing.

x = 5 y = 7 print x+y x*y 
       
12
35
12
35

Each cell evaluation remembers any definitions from cells that were evaluated previously, including variables and functions.

Note: you will see a thin red line by the side of the cell if the cell has not yet been evaluated.

x+y 
       
12
12

Warning: Sage will let you evaluate cells out of order. It is the order of evaluation that counts, not the order of appearance in the worksheet.

If you try to evaluate a cell which contains a mistake, such as trying to use a variable which is not defined, Sage will give you an error message. You can click on the output to see a more verbose error message, which may help you isolate the problem if it occurs in a large cell.

Below we assign a value to a variable, print it, delete it, and observe the ensuing error:

a = 2 print "a = ", a del a a 
       
a =  2
Traceback (click to the left of this block for traceback)
...
NameError: name 'a' is not defined
a =  2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "_sage_input_8.py", line 10, in <module>
    exec compile(u'open("___code___.py","w").write("# -*- coding: utf-8 -*-\\n" + _support_.preparse_worksheet_cell(base64.b64decode("YSA9IDIKcHJpbnQgImEgPSAiLCBhCmRlbCBhCmE="),globals())+"\\n"); execfile(os.path.abspath("___code___.py"))
  File "", line 1, in <module>
    
  File "/tmp/tmplKlVTv/___code___.py", line 6, in <module>
    exec compile(u'a
  File "", line 1, in <module>
    
NameError: name 'a' is not defined

Basic Python/Sage objects

Here we discuss some basic Python/Sage objects. These will all be things that can be assigned to variables, which we have already seen how to do in the case of integers.

Note that variables do not need to be declared before being used; in particular, there is no need to specify in advance what type of object is going to be assigned to a given variable.

So far our variable names have only been one character long. However, this is not required: you may use any sequence of letters, numbers, and the underscore _ as a variable name as long as it starts with a letter and does not coincide with a Python reserved wood (such as "print"). 

square_root_of_2 = sqrt(2) print square_root_of_2^4 
       
4
4

Besides integers, some other basic types of objects include rational numbers, real numbers, and complex numbers (where capital I denotes the chosen square root of -1). These support the usual arithmetic operations.

print 7 % 3 ## modular reduction print 7 // 3 ## integer division print 10/6 ## returns a rational number print exp(2.7) print (2+I)*(3+I) 
       
1
2
5/3
14.8797317248728
5*I + 5
1
2
5/3
14.8797317248728
5*I + 5

Another basic object type is strings, which are enclosed in either single or double quotes. One common operation on strings is concatenation.

'3' + '4' 
       
'34'
'34'

Arrays

Besides simple types like numbers and strings, one also has compound types like arrays. Arrays can be specified using square brackets (the entries need not be all of one type).

print [3, 4] + [5, 'six'] ## plus sign denotes composition 
       
[3, 4, 5, 'six']
[3, 4, 5, 'six']

One also uses square brackets to access the individual entries of an array, or even to assign them. Two important things to note:

  • Python indexes starting from 0, not 1.
  • You may also use negative indices: -n denotes the n-th term from the end.
u = [2, 3, 4] print u[0] ## first element print u[-1] ## last element u[1] = 1 ## modify an existing entry print u[-2] ## should equal u[1] u[3] = 5 ## this won't work 
       
2
4
1
Traceback (click to the left of this block for traceback)
...
IndexError: list assignment index out of range
2
4
1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "_sage_input_14.py", line 10, in <module>
    exec compile(u'open("___code___.py","w").write("# -*- coding: utf-8 -*-\\n" + _support_.preparse_worksheet_cell(base64.b64decode("dSA9IFsyLCAzLCA0XQpwcmludCB1WzBdICMjIGZpcnN0IGVsZW1lbnQKcHJpbnQgdVstMV0gIyMgbGFzdCBlbGVtZW50CnVbMV0gPSAxICMjIG1vZGlmeSBhbiBleGlzdGluZyBlbnRyeQpwcmludCB1Wy0yXSAjIyBzaG91bGQgZXF1YWwgdVsxXQp1WzNdID0gNSAjIyB0aGlzIHdvbid0IHdvcms="),globals())+"\\n"); execfile(os.path.abspath("___code___.py"))
  File "", line 1, in <module>
    
  File "/tmp/tmpSPNxLH/___code___.py", line 8, in <module>
    exec compile(u"u[_sage_const_3 ] = _sage_const_5  ## this won't work" + '\n', '', 'single')
  File "", line 1, in <module>
    
IndexError: list assignment index out of range

Some other ways to construct arrays are the following.

  • One can concatenate existing arrays using the + operator (see above).
  • One can modify in place entries of an existing array (see above).
  • One can form slices of an existing array by picking out a range of values. This is the safest way to make a copy of an array (see below).
  • Some functions return arrays, such as the "range" function.
  • One can use list comprehensions to apply a function to each term of one array to make a new array. There is also the option to put in a conditional statement to pick out only some of the terms of the original array (using == for equality, rather than = which means assignment). 
u = [2,3,4,5] print u[1:3] ## left index is included, right index is not print u[:4] ## left index defaults to 0 print u[1:] ## right index defaults to the length of the array print range(5) ## range(n) includes 0, excludes n print range(3,13) ## specify left and right endpoints as for slices print [x^2 for x in u if x%2==1] 
       
[3, 4]
[2, 3, 4, 5]
[3, 4, 5]
[0, 1, 2, 3, 4]
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
[9, 25]
[3, 4]
[2, 3, 4, 5]
[3, 4, 5]
[0, 1, 2, 3, 4]
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
[9, 25]

Warning: arrays are copied by reference, not by value. This is in fact true for all Python/Sage objects, but the fact that arrays can be modified after they are created (that is, they are mutable) creates a real danger.

a = [1,2,3] b = a ## does not create a new array! b[1] = -1 print "a = ", a ## has now been modified c = a[:] ## this does create a new array c[-1] = 4 print "a = ", a print "c = ", c 
       
a =  [1, -1, 3]
a =  [1, -1, 3]
c =  [1, -1, 4]
a =  [1, -1, 3]
a =  [1, -1, 3]
c =  [1, -1, 4]

Conditional evaluation

Like most programming languages, Python supports conditional evaluation via such mechanisms as for loops, while loops, and if-then-else constructions. Here is an example.

for i in range(5): if i%2 == 0: print i, "is an even", else: print i, "is an odd", print "number" print "loop complete" 
       
0 is an even number
1 is an odd number
2 is an even number
3 is an odd number
4 is an even number
loop complete
0 is an even number
1 is an odd number
2 is an even number
3 is an odd number
4 is an even number
loop complete

Let's step through this example in detail.

  • The first line creates the for loop. The range is created using the "range" function described above.
  • Everything within the for loop is indented. This is not optional! Python uses this indentation to figure out where the loop starts and ends. The notebook will help you: after you type the "for" line (ending with the colon), the next line will be indented appropriately.
  • The "if" command takes a Boolean expression. As we saw before,  == denotes equality, as opposed to a single = which denotes an assignment.
  • The "else" command is optional. Again, the indentation tells Python where the if and else clauses begin and end.
  • The "print" command can take multiple arguments, and adds a line break unless you end it with a comma.

Functions

By now, you have probably noticed that much Python functionality is provided via callable functions, such as "range". Sage extends this functionality by specifying many new advanced mathematical functions.

prime_pi(1000) ## The number of primes up to 1000 
       
168
168

Sage includes a couple of useful techniques for inquiring about functions. One of these is tab completion: if you type part of the name of a function and hit Tab, Sage will attempt to complete the name of the function. On one hand, this can save a lot of typing.

charac 
       
Traceback (click to the left of this block for traceback)
...
NameError: name 'charac' is not defined
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "_sage_input_19.py", line 10, in <module>
    exec compile(u'open("___code___.py","w").write("# -*- coding: utf-8 -*-\\n" + _support_.preparse_worksheet_cell(base64.b64decode("Y2hhcmFj"),globals())+"\\n"); execfile(os.path.abspath("___code___.py"))
  File "", line 1, in <module>
    
  File "/tmp/tmp7jczNd/___code___.py", line 2, in <module>
    exec compile(u'charac
  File "", line 1, in <module>
    
NameError: name 'charac' is not defined

Perhaps more usefully, if more than one completion is possible, Sage will show you all possible completions; this can be a useful way to find out about what is available in Sage. (This technique is even more possible when applied to object methods; see below.)

ran 
       
Traceback (click to the left of this block for traceback)
...
NameError: name 'ran' is not defined
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "_sage_input_20.py", line 10, in <module>
    exec compile(u'open("___code___.py","w").write("# -*- coding: utf-8 -*-\\n" + _support_.preparse_worksheet_cell(base64.b64decode("cmFu"),globals())+"\\n"); execfile(os.path.abspath("___code___.py"))
  File "", line 1, in <module>
    
  File "/tmp/tmpIk_tza/___code___.py", line 2, in <module>
    exec compile(u'ran
  File "", line 1, in <module>
    
NameError: name 'ran' is not defined

Another important inquiry technique is introspection: if one evaluates the name of a function followed by a ?, Python will show you a bit of documentation about that function. For instance, if you have forgotten how to specify a range other than 0, ..., n-1, we can use introspection on the range function.

range? 
       

Type: <type 'builtin_function_or_method'>

Definition: range( [noargspec] )

Docstring:


range([start,] stop[, step]) -> list of integers

Return a list containing an arithmetic progression of integers.
range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.
When step is given, it specifies the increment (or decrement).
For example, range(4) returns [0, 1, 2, 3].  The end point is omitted!
These are exactly the valid indices for a list of 4 elements.

Type: <type 'builtin_function_or_method'>

Definition: range( [noargspec] )

Docstring:


range([start,] stop[, step]) -> list of integers

Return a list containing an arithmetic progression of integers.
range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.
When step is given, it specifies the increment (or decrement).
For example, range(4) returns [0, 1, 2, 3].  The end point is omitted!
These are exactly the valid indices for a list of 4 elements.

Python and Sage also allow for user-defined functions. As with variables, these may be defined in one cell and then used in later cell evaluations. (These will not admit introspection unless you do some extra work, except for source code viewing, but they will admit tab completion.)

def twist_multiply(a, b): return a+b + a*b 
       
twist_multiply(2, 3) 
       
11
11
twist_multiply? 
       

File: /tmp/tmpWCmBmG/___code___.py

Type: <type 'function'>

Definition: twist_multiply(a, b)

Docstring:


x.__init__(...) initializes x; see x.__class__.__doc__ for signature

File: /tmp/tmpWCmBmG/___code___.py

Type: <type 'function'>

Definition: twist_multiply(a, b)

Docstring:


x.__init__(...) initializes x; see x.__class__.__doc__ for signature
twist_multiply?? 
       

File: /tmp/tmpWCmBmG/___code___.py

Source Code (starting at line 2):

def twist_multiply(a, b):
    return a+b + a*b

File: /tmp/tmpWCmBmG/___code___.py

Source Code (starting at line 2):

def twist_multiply(a, b):
    return a+b + a*b

Mathematical objects in Sage

One important difference between Python and some lower-level programming languages like C is that Python is object-oriented. That is, besides the variables and functions that one can define globally, one can also create objects with their own variables and functions attached to them. In Sage, this framework is used to implement the construction of mathematical objects in a rigorous fashion which corresponds pretty well to the way mathematicians are used to thinking about these objects. For example, one can create such objects as the ring of integers and the field of rational numbers.

Z = IntegerRing() Q = RationalField() 
       

Here are some ways to initialize the field of complex numbers:

print CC #the complex field with 53 bits of precision C1000 = ComplexField(1000); print C1000 #adjusting precision 
       
Complex Field with 53 bits of precision
Complex Field with 1000 bits of precision
Complex Field with 53 bits of precision
Complex Field with 1000 bits of precision

We can initialize elements of these fields:

print CC(sqrt(2)) print C1000(sqrt(2)) 
       
1.41421356237309
1.4142135623730950488016887242096980785696718753769480731766797379907324\
784621070388503875343276415727350138462309122970249248360558507372126441\
214970999358314132226659275055927557999505011527820605714701095599716059\
702745345968620147285174186408891986095523292304843087143214508397626036\
2799525140799
1.41421356237309
1.41421356237309504880168872420969807856967187537694807317667973799073247846210703885038753432764157273501384623091229702492483605585073721264412149709993583141322266592750559275579995050115278206057147010955997160597027453459686201472851741864088919860955232923048430871432145083976260362799525140799

Here are examples of some fields of arithmetic interest:

print ZZ print QQ print GF(5) print GF(25,names='a') R.<x> = QQ['x'] F.<b> = NumberField(x^2+3); print F print Qp(7,6) 
       
Integer Ring
Rational Field
Finite Field of size 5
Finite Field in a of size 5^2
Number Field in b with defining polynomial x^2 + 3
7-adic Field with capped relative precision 6
Integer Ring
Rational Field
Finite Field of size 5
Finite Field in a of size 5^2
Number Field in b with defining polynomial x^2 + 3
7-adic Field with capped relative precision 6

One can then feed these into more complicated constructions, like the ring of polynomials in a single variable.

R.<x> = QQ['x'] 
       

In this example, we have created a polynomial ring over the rationals with a distinguished generator, to which we have assigned the name x. We can now generate elements of the ring R simply by writing down expressions in x.

 

poly = x^3 + 1 print poly.parent() print poly.parent() == R 
       
Univariate Polynomial Ring in x over Rational Field
True
Univariate Polynomial Ring in x over Rational Field
True

The "parent" command here is an example of a method of the object poly.

Now that we can make polynomials over the rationals, what can we do with them? An excellent way to find out is to use tab completion: if one types "poly." and then hits Tab, one is presented a list of all of the methods associated to poly.

poly.factor() ## can also be invoked as factor(poly) 
       
(x + 1) * (x^2 - x + 1)
(x + 1) * (x^2 - x + 1)

In the previous example, the "factor" method did not require any additional arguments. In other examples, one or more arguments may be required.

poly.xgcd(x-2) ## extended GCD; can also be invoked as xgcd(poly, x-2) 
       
(1, 1/9, -1/9*x^2 - 2/9*x - 4/9)
(1, 1/9, -1/9*x^2 - 2/9*x - 4/9)

This syntax might seem a bit strange: the extended GCD operation is essentially symmetric in its variables, so calling it in an asymmetric fashion may be counterintuitive. There is an extremely good reason for using the object-oriented syntax, namely tab completion. One can for instance type "poly." and his Tab to see the list of all of the methods associated to poly!

poly. 
       
Traceback (click to the left of this block for traceback)
...
SyntaxError: invalid syntax
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "_sage_input_34.py", line 10, in <module>
    exec compile(u'open("___code___.py","w").write("# -*- coding: utf-8 -*-\\n" + _support_.preparse_worksheet_cell(base64.b64decode("cG9seS4="),globals())+"\\n"); execfile(os.path.abspath("___code___.py"))
  File "", line 1, in <module>
    
  File "/tmp/tmphSviir/___code___.py", line 2
    poly.
        ^
SyntaxError: invalid syntax

As for bare functions, one can also type a few characters and get only the methods that start with the characters you type. For example, if you can't remember whether the method for factoring a polynomial is called "factor", "factorize", "factorise", "factorization", or "factorisation", you can check by doing a tab completion:

poly.factor 
       
<built-in method factor of
sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flin\
t object at 0x68fc398>
<built-in method factor of sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint object at 0x68fc398>

There can sometimes be some ambiguity about what the correct parent of a mathematical object should be. For instance, 3/4 is a rational number, but it can also be viewed as a polynomial over the rationals, e.g., when one wants to add or multiply it with another such polynomial. For the most part, Sage will take care of this for you automatically.

poly2 = poly + 3/4 print poly2.parent() 
       
Univariate Polynomial Ring in x over Rational Field
Univariate Polynomial Ring in x over Rational Field

Sometimes, however, one needs to make this change of parent explicit, e.g., in case one wants to call a method which exists for polynomials but not for rationals. For example, this fails:

poly2 = 3/4 poly2.coefficients() 
       
Traceback (click to the left of this block for traceback)
...
AttributeError: 'sage.rings.rational.Rational' object has no attribute
'coefficients'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "_sage_input_37.py", line 10, in <module>
    exec compile(u'open("___code___.py","w").write("# -*- coding: utf-8 -*-\\n" + _support_.preparse_worksheet_cell(base64.b64decode("cG9seTIgPSAzLzQKcG9seTIuY29lZmZpY2llbnRzKCk="),globals())+"\\n"); execfile(os.path.abspath("___code___.py"))
  File "", line 1, in <module>
    
  File "/tmp/tmpxoEHq5/___code___.py", line 4, in <module>
    exec compile(u'poly2.coefficients()
  File "", line 1, in <module>
    
  File "element.pyx", line 331, in sage.structure.element.Element.__getattr__ (sage/structure/element.c:2868)
  File "parent.pyx", line 327, in sage.structure.parent.getattr_from_other_class (sage/structure/parent.c:3193)
AttributeError: 'sage.rings.rational.Rational' object has no attribute 'coefficients'

This change of parent (called coercion) is usually accomplished by the following syntax, which looks like plugging the element into the new parent viewed as a function.

poly2 = R(3/4) poly2.coefficients() 
       
[3/4]
[3/4]

Here we create a multivariate polynomial ring over \mathbb{Q}, initialize some functions, and compute a resultant:

P.<x,y> = PolynomialRing(QQ,2) a = x+y b = x^3-y^3 c = a.resultant(b); print c d = a.resultant(b,y); print d c == a.resultant(b,x) 
       
-2*y^3
2*x^3
True
-2*y^3
2*x^3
True

We can create rational functions by starting with polynomials:

R.<x> = QQ['x'] f = x + 1 g = x + 2 h = f/g; h 
       
(x + 1)/(x + 2)
(x + 1)/(x + 2)
h.parent() 
       
Fraction Field of Univariate Polynomial Ring in x over Rational Field
Fraction Field of Univariate Polynomial Ring in x over Rational Field

We can create a power series expansion by coercing each polynomial into the relevant power series ring:

S.<x> = QQ[['x']] newh = S(f)/S(g); newh 
       
1/2 + 1/4*x - 1/8*x^2 + 1/16*x^3 - 1/32*x^4 + 1/64*x^5 - 1/128*x^6 +
1/256*x^7 - 1/512*x^8 + 1/1024*x^9 - 1/2048*x^10 + 1/4096*x^11 -
1/8192*x^12 + 1/16384*x^13 - 1/32768*x^14 + 1/65536*x^15 - 1/131072*x^16
+ 1/262144*x^17 - 1/524288*x^18 + 1/1048576*x^19 + O(x^20)
1/2 + 1/4*x - 1/8*x^2 + 1/16*x^3 - 1/32*x^4 + 1/64*x^5 - 1/128*x^6 + 1/256*x^7 - 1/512*x^8 + 1/1024*x^9 - 1/2048*x^10 + 1/4096*x^11 - 1/8192*x^12 + 1/16384*x^13 - 1/32768*x^14 + 1/65536*x^15 - 1/131072*x^16 + 1/262144*x^17 - 1/524288*x^18 + 1/1048576*x^19 + O(x^20)

Suppose you need to copy the above power series into a paper. Sage can do that for you too!

latex(newh) 
       
\frac{1}{2} + \frac{1}{4}x - \frac{1}{8}x^{2} + \frac{1}{16}x^{3} -
\frac{1}{32}x^{4} + \frac{1}{64}x^{5} - \frac{1}{128}x^{6} +
\frac{1}{256}x^{7} - \frac{1}{512}x^{8} + \frac{1}{1024}x^{9} -
\frac{1}{2048}x^{10} + \frac{1}{4096}x^{11} - \frac{1}{8192}x^{12} +
\frac{1}{16384}x^{13} - \frac{1}{32768}x^{14} + \frac{1}{65536}x^{15} -
\frac{1}{131072}x^{16} + \frac{1}{262144}x^{17} - \frac{1}{524288}x^{18}
+ \frac{1}{1048576}x^{19} + O(x^{20})
\frac{1}{2} + \frac{1}{4}x - \frac{1}{8}x^{2} + \frac{1}{16}x^{3} - \frac{1}{32}x^{4} + \frac{1}{64}x^{5} - \frac{1}{128}x^{6} + \frac{1}{256}x^{7} - \frac{1}{512}x^{8} + \frac{1}{1024}x^{9} - \frac{1}{2048}x^{10} + \frac{1}{4096}x^{11} - \frac{1}{8192}x^{12} + \frac{1}{16384}x^{13} - \frac{1}{32768}x^{14} + \frac{1}{65536}x^{15} - \frac{1}{131072}x^{16} + \frac{1}{262144}x^{17} - \frac{1}{524288}x^{18} + \frac{1}{1048576}x^{19} + O(x^{20})

Plotting

Sage has many more mathematical features than we can introduce here (but which are well-documented). We'll say just a few things here about plotting; check out the online documentation for more examples.

var('x') ## Define a symbolic variable named x a = plot(sin(x*6)^2 * e^-(x*x),x,-3,3,fill=True,fillcolor='blue'); a 
       
b = plot(e^-(x*x),x,-3,3,fill=True,fillcolor='yellow');b 
       
a+b 
       
var('x,y') plot3d(sin(pi*(x^2+y^2))/2,(x,-1,1),(y,-1,1)) 
       
v = [plot(sin(a*x), (x,0,10)) for a in [0,0.2,..,pi]] print len(v) z = animate(v, xmin=0,xmax=10,ymin=-1,ymax=1) #makes a single animated GIF file z.show(delay=50) 
       
16
16
complex_plot? 
       

File: /sagenb/sage_install/sage-4.7.2/devel/sage/sage/misc/lazy_import.pyx

Type: <type ‘sage.misc.lazy_import.LazyImport’>

Definition: complex_plot(f, xrange, yrange, **options, plot_points=100, interpolation=’catrom’)

Docstring:

complex_plot takes a complex function of one variable, f(z) and plots output of the function over the specified xrange and yrange as demonstrated below. The magnitude of the output is indicated by the brightness (with zero being black and infinity being white) while the argument is represented by the hue (with red being positive real, and increasing through orange, yellow, ... as the argument increases).

complex_plot(f, (xmin, xmax), (ymin, ymax), ...)

INPUT:

  • f – a function of a single complex value x + iy
  • (xmin, xmax) – 2-tuple, the range of x values
  • (ymin, ymax) – 2-tuple, the range of y values

The following inputs must all be passed in as named parameters:

  • plot_points – integer (default: 100); number of points to plot in each direction of the grid
  • interpolation – string (default: 'catrom'), the interpolation method to use: 'bilinear', 'bicubic', 'spline16', 'spline36', 'quadric', 'gaussian', 'sinc', 'bessel', 'mitchell', 'lanczos', 'catrom', 'hermite', 'hanning', 'hamming', 'kaiser'

EXAMPLES:

Here we plot a couple of simple functions:

sage: complex_plot(sqrt(x), (-5, 5), (-5, 5))
sage: complex_plot(sin(x), (-5, 5), (-5, 5))
sage: complex_plot(log(x), (-10, 10), (-10, 10))
sage: complex_plot(exp(x), (-10, 10), (-10, 10))

A function with some nice zeros and a pole:

sage: f(z) = z^5 + z - 1 + 1/z
sage: complex_plot(f, (-3, 3), (-3, 3))

Here is the identity, useful for seeing what values map to what colors:

sage: complex_plot(lambda z: z, (-3, 3), (-3, 3))

The Riemann Zeta function:

sage: complex_plot(zeta, (-30,30), (-30,30))

Extra options will get passed on to show(), as long as they are valid:

sage: complex_plot(lambda z: z, (-3, 3), (-3, 3), figsize=[1,1])
sage: complex_plot(lambda z: z, (-3, 3), (-3, 3)).show(figsize=[1,1]) # These are equivalent

TESTS:

Test to make sure that using fast_callable functions works:

sage: f(x) = x^2
sage: g = fast_callable(f, domain=CC, vars='x')
sage: h = fast_callable(f, domain=CDF, vars='x')
sage: P = complex_plot(f, (-10, 10), (-10, 10))
sage: Q = complex_plot(g, (-10, 10), (-10, 10))
sage: R = complex_plot(h, (-10, 10), (-10, 10))
sage: S = complex_plot(exp(x)-sin(x), (-10, 10), (-10, 10))
sage: P; Q; R; S

Test to make sure symbolic functions still work without declaring a variable. (We don’t do this in practice because it doesn’t use fast_callable, so it is much slower.)

sage: complex_plot(sqrt, (-5, 5), (-5, 5))

File: /sagenb/sage_install/sage-4.7.2/devel/sage/sage/misc/lazy_import.pyx

Type: <type ‘sage.misc.lazy_import.LazyImport’>

Definition: complex_plot(f, xrange, yrange, **options, plot_points=100, interpolation=’catrom’)

Docstring:

complex_plot takes a complex function of one variable, f(z) and plots output of the function over the specified xrange and yrange as demonstrated below. The magnitude of the output is indicated by the brightness (with zero being black and infinity being white) while the argument is represented by the hue (with red being positive real, and increasing through orange, yellow, ... as the argument increases).

complex_plot(f, (xmin, xmax), (ymin, ymax), ...)

INPUT:

  • f – a function of a single complex value x + iy
  • (xmin, xmax) – 2-tuple, the range of x values
  • (ymin, ymax) – 2-tuple, the range of y values

The following inputs must all be passed in as named parameters:

  • plot_points – integer (default: 100); number of points to plot in each direction of the grid
  • interpolation – string (default: 'catrom'), the interpolation method to use: 'bilinear', 'bicubic', 'spline16', 'spline36', 'quadric', 'gaussian', 'sinc', 'bessel', 'mitchell', 'lanczos', 'catrom', 'hermite', 'hanning', 'hamming', 'kaiser'

EXAMPLES:

Here we plot a couple of simple functions:

sage: complex_plot(sqrt(x), (-5, 5), (-5, 5))
sage: complex_plot(sin(x), (-5, 5), (-5, 5))
sage: complex_plot(log(x), (-10, 10), (-10, 10))
sage: complex_plot(exp(x), (-10, 10), (-10, 10))

A function with some nice zeros and a pole:

sage: f(z) = z^5 + z - 1 + 1/z
sage: complex_plot(f, (-3, 3), (-3, 3))

Here is the identity, useful for seeing what values map to what colors:

sage: complex_plot(lambda z: z, (-3, 3), (-3, 3))

The Riemann Zeta function:

sage: complex_plot(zeta, (-30,30), (-30,30))

Extra options will get passed on to show(), as long as they are valid:

sage: complex_plot(lambda z: z, (-3, 3), (-3, 3), figsize=[1,1])
sage: complex_plot(lambda z: z, (-3, 3), (-3, 3)).show(figsize=[1,1]) # These are equivalent

TESTS:

Test to make sure that using fast_callable functions works:

sage: f(x) = x^2
sage: g = fast_callable(f, domain=CC, vars='x')
sage: h = fast_callable(f, domain=CDF, vars='x')
sage: P = complex_plot(f, (-10, 10), (-10, 10))
sage: Q = complex_plot(g, (-10, 10), (-10, 10))
sage: R = complex_plot(h, (-10, 10), (-10, 10))
sage: S = complex_plot(exp(x)-sin(x), (-10, 10), (-10, 10))
sage: P; Q; R; S

Test to make sure symbolic functions still work without declaring a variable. (We don’t do this in practice because it doesn’t use fast_callable, so it is much slower.)

sage: complex_plot(sqrt, (-5, 5), (-5, 5))
@interact #by Harald Schilly def mandel_plot(expo = slider(-10,10,0.1,2), \ formula = ['mandel','ff'],\ iterations=slider(1,100,1,30), \ zoom_x = range_slider(-2,2,0.01,(-2,1)), \ zoom_y = range_slider(-2,2,0.01,(-1.5,1.5))): var('z c') f(z,c) = z^expo + c ff_m = fast_callable(f, vars=[z,c], domain=CDF) # messing around with fast_callable for i in range(int(iterations)/3): f(z,c) = f(z,c)^expo+c ff = fast_callable(f, vars=[z,c], domain=CDF) def mandel(z): c = z for i in range(iterations): z = ff_m(z,c) if abs(z) > 2: return z return z print 'z <-- z^%s + c' % expo # calling ff three times, otherwise fast_callable exceeds a recursion limit if formula is 'ff': func = lambda z: ff(ff(ff(z,z),z),z) elif formula is 'mandel': func = mandel complex_plot(func, zoom_x,zoom_y, plot_points=300, axes = False,ticks=[[],[]] ).show(frame=True, \ aspect_ratio=1,figsize=[8,8]) 
       
expo 
formula 
iterations 
zoom_x 
zoom_y 

Click to the left again to hide and once more to show the dynamic interactive window

@interact #by Harald Schilly def julia_plot(expo = slider(-10,10,0.1,2), \ iterations=slider(1,100,1,30), \ c_real = slider(-2,2,0.01,0.5), \ c_imag = slider(-2,2,0.01,0.5), \ zoom_x = range_slider(-2,2,0.01,(-1.5,1.5)), \ zoom_y = range_slider(-2,2,0.01,(-1.5,1.5))): var('z') I = CDF.gen() f(z) = z^expo + c_real + c_imag*I ff_j = fast_callable(f, vars=[z], domain=CDF) def julia(z): for i in range(iterations): z = ff_j(z) if abs(z) > 2: return z return z print 'z <-- z^%s + (%s+%s*I)' % (expo, c_real, c_imag) C = complex_plot(julia, zoom_x,zoom_y, plot_points=300, axes = False,ticks=[[],[]] ).show(frame=True, \ aspect_ratio=1,figsize=[5,5]) 
       
expo 
iterations 
c_real 
c_imag 
zoom_x 
zoom_y 

Click to the left again to hide and once more to show the dynamic interactive window

julia_plot(-7,30,0.5,0.5,(-1.5,1.5), (-1.5,1.5)) 
       
z <-- z^-7 + (0.500000000000000+0.500000000000000*I)
z <-- z^-7 + (0.500000000000000+0.500000000000000*I)
 
       

What else can Sage do?

  • Communicate with other mathematical software. Sage itself ships with many well-regarded free software packages, such as Pari (number theory), Gap (group theory), Singular (commutative algebra), R (statistics), etc. Sage can also communicate with nonfree packages such as Mathematica, Maple, Matlab, and Magma if you have them installed. This means that you can access the power of many software packages while (mostly) only having to deal with one well-designed programming language!
  • Communicate with TeX at various levels. For instance, any Sage object has a method that returns its representation in TeX. An even more spectacular example is SageTeX, a TeX package that allows your TeX document to pass inputs to Sage and retrieve the answers
  • Annotate worksheets by inserting formatted text and even TeX code between the cells, as in this presentation.

 For more on Sage, there are tutorials and documentation available here: http://www.sagemath.org/doc/

Become a Sage developer!