Subsections

1. Using SAGE

Though much of SAGE is implemented using Python, no Python background is needed to read this tutorial. (Some background on Python will be needed by the heavy SAGE user, but this is not the place for that.) For those who just want to just try out SAGE, this is the place to start. For example:

sage: 2 + 2
      4
sage: factor(1887087625)
      5^3 * 197^2 * 389
sage: VectorSpace(QQ, 4)
      Vector space of dimension 4 over Rational Field
sage: A = MatrixSpace(QQ, 4)(range(16)); A
      [ 0  1  2  3]
      [ 4  5  6  7]
      [ 8  9 10 11]
      [12 13 14 15]
sage: factor(A.charpoly())
      x^2 * (x^2 - 30*x - 80)
sage: EllipticCurve([1,2,3,4,5]).anlist(10)
      [0, 1, 1, 0, -1, -3, 0, -1, -3, -3, -3]

1.1 Installation

See the document Installing SAGE at [SA] for instructions on installing SAGE on your computer. Here we merely make two comments.

  1. The SAGE download file comes with ``everything including batteries''. In other words, although SAGE uses Python, IPython, PARI, GMP, and so on, you do not need to install them separately as they are included with the SAGE distribution.

  2. The pre-compiled binary version of SAGE (found on the SAGE website) should be easier and quicker to install than the source code version. Just unpack the file and run sage. Unfortunately, it is typically not as up-to-date as the source version.

1.2 Ways to Use SAGE

You can use SAGE either via an interactive shell, or you can write Python programs that use the SAGE library. To use SAGE as a Python module, set the shell environmental variables LD_LIBRARY_PATH, SAGE_HOME, PYTHONPATH correctly (see bin/sage), then run the Python 2.4 interpreter included with SAGE (bin/python), and type from all import * into the interpreter, or include it in your Python script.

In this tutorial we assume you start the SAGE interpreter using the sage command. This starts a customized version of the IPython shell, and imports many functions and classes, so they are ready to use from the command prompt. Further customization is possible by editing the $SAGE_HOME/conf/ipythonrc file. Upon starting SAGE you get output similar to the following:

------------------------------------------------------------------------
  SAGE Version ..., Export Date: ...
  Distributed under the terms of the GNU General Public License (GPL)
  IPython shell -- for help type <object>?, <object>??, %magic, or help
------------------------------------------------------------------------
sage:
To quit SAGE either press Ctrl-D or type quit or exit.

1.3 Input and Output

SAGE via IPython logs all SAGE input. In fact, at any point, you may type %hist to get a listing of all input lines typed so far. You can type ? at the SAGE prompt to find out more about IPython. Here is a piece of this information: ``IPython offers numbered prompts ... with input and output caching. All input is saved and can be retrieved as variables (besides the usual arrow key recall). The following GLOBAL variables always exist (so don't overwrite them!)'':

  _: stores previous input.
  __: next previous.
  ___: next-next previous.
  _ih : a list of all input _ih[n] is the input from line n.
  _oh : a list of all outpu

Here is an example:

sage: factor(100)
 _1 = 2^2 * 5^2
sage: kronecker_symbol(3,5)
 _2 = -1
sage: %hist
1: factor(ZZ(100))
2: kronecker_symbol(ZZ(3),ZZ(5))
sage: _oh
 _4 = {1: 2^2 * 5^2, 2: -1, 4: <Recursion on dict with id=-1212995276>}
sage: _i1
 _5 = 'factor(ZZ(100))\n'
sage: eval(_i1)
 _6 = 2^2 * 5^2
sage: %hist
1: factor(ZZ(100))
2: kronecker_symbol(ZZ(3),ZZ(5))
3: ipmagic("%hist ")
4: _oh
5: _i1
6: eval(_i1)
sage: _ih
 _8 = ['\n', 'factor(ZZ(100))\n', 'kronecker_symbol(ZZ(3),ZZ(5))\n', 'ipmagic("%hist ")\n', '_oh\n', '_i1\n', 'eval(_i1)\n', 'ipmagic("%hist ")\n', '_ih\n']

We omit the output numbering in the rest of this tutorial and the other SAGE documentation.

Any UNIX shell command can be executed from SAGE by prefacing it by an exclamation point (!). For example,

sage: !ls
auto  example  example.syc  glossary.tex  t  tmp  tut.log  tut.tex
returns the listing of the current directory.

Next we illustrate how to load programs written in a separate file into SAGE. Create a file called example.sage with the following content:

print "Hello World"
print 2^3

1.4 Loading and Attaching SAGE files

Read in and execute example.sage file using the load command.

sage: load "example.sage"
Hello World
8

You can also attach a SAGE file to a running session using the attach command:

sage: attach "example.sage"
Hello World
8
Now if you change example.sage and enter one blank line into SAGE, then the contents of example.sage will be automatically reloaded into SAGE.

When SAGE loads example.sage it converts it to Python, which is then executed by the Python interpreter. This conversion is minimal; it mainly involves wrapping integer literals in ZZ(), floating point literals in RR(), replacing ^'s by **'s, and replacing e.g., R.2 by R.gen(2). The converted version of example.sage is contained in the same directory as example.sage and is called example.sage.py. This file contains the following code:

print "Hello World"
print ZZ(2)**ZZ(3)
Note that integer literals are wrapped and the ^ is replaced by a **. (In Python ^ means ``exclusive or'' and ** means ``exponentiation''.)

Note: This rather limited preparsing is implemented in sage/misc/interpreter.py.

1.5 Ignoring Prompts: Copy and Paste

Suppose you are reading a session of SAGE or Python computations and want to copy them into SAGE. But there are annoying >>> or sage: prompts to worry about. In fact, you can copy and paste an example, including the prompts if you want, into SAGE. In other words, by default the SAGE parser strips any leading >>> or sage: prompt before passing it to Python. For example,

sage: 2^10
      1024
sage: sage: 2^10
      1024
sage: >>> 2^10
      1024

1.6 Timing Commands

If you place the time comand at the beginning of an input line, the time the command takes to run will be displayed after the output. For example, we can compare the running time for a certain exponentiation operation using three large integer arithmetic packages. Note that the timings below will probably be much different on your computer, or even between different versions of SAGE. First, native Python:

sage: time a = int(1938)^int(99484)
CPU times: user 0.66 s, sys: 0.00 s, total: 0.66 s
Wall time: 0.66
This means that 0.66 seconds total were taken, and the ``Wall time'', i.e., the amount of time that elapsed on your wall clock, is also 0.66 seconds. If your computer is heavily loaded with other programs the wall time may be much larger than the CPU time.

Next we time exponentiation using the native SAGE Integer type, which is implemented (in Pyrex) using the GMP library:

sage: time a = 1938^99484
CPU times: user 0.04 s, sys: 0.00 s, total: 0.04 s
Wall time: 0.04
Finally using the PARI C-library interface:

sage: time a = pari(1938)^pari(99484)
CPU times: user 0.05 s, sys: 0.00 s, total: 0.05 s
Wall time: 0.05
GMP is better, but only slightly (as expected, since the version of PARI built for SAGE uses GMP for integer arithmetic).

You can also time a block of commands using the cputime command, as illustrated below:

sage: t = cputime()
sage: a = int(1938)^int(99484)
sage: b = 1938^99484
sage: c = pari(1938)^pari(99484)
sage: print cputime(t)                
      0.64                                     # may vary

sage: cputime?
...
    Return the time in CPU second since SAGE started, or with optional
    argument t, return the time since time t.
    INPUT:
        t -- (optional) float, time in CPU seconds
    OUTPUT:
        float -- time in CPU seconds

1.7 Errors and Exceptions

When you make a syntax error, you will see what Python calls an ``exception''. It even tries to suggest what it is that it that raised the exception. Often you see the name of the exception, e.g., NameError or ValueError (see the Python Reference Manual [Py] for a complete list of exceptions). For example,

sage: 3_2
------------------------------------------------------------
   File "<console>", line 1
     ZZ(3)_2
           ^
SyntaxError: invalid syntax

sage: EllipticCurve([0,infinity])
------------------------------------------------------------
Traceback (most recent call last):
  File "<console>", line 1, in ?
  File "/home/wdj/.../ellcurve.py", line 139, in __new__
    return EllipticCurve_RationalField(*args, **kwds)
  File "/home/wdj/.../ellcurve.py", line 661, in __init__
    EllipticCurve_generic.__init__(self, [Q(x) for x in ainvs])
  File "/home/wdj/.../rational_field.py", line 79, in __call__
    return sage.rings.rational.Rational(x)
  File "_rational.pyx", line 82, in _rational.Rational.__init__
  File "_rational.pyx", line 116, in _rational.Rational.__set_value
TypeError: Unable to coerce Infinity (<class 'sage...Infinity'>) to Rational

The interactive debugger is sometimes useful for understanding what went wrong. You can toggle it being on or off using %pdb (the default is off). The prompt (Pdb) appears if an exception is raised and the debugger is on. From within the debugger, you can print the state of any local variable, and move up and down the execution stack. For example,

sage: %pdb
Automatic pdb calling has been turned ON
sage: EllipticCurve([1,infinity])
------------------------------------------------------------
Traceback (most recent call last):
  File "<console>", line 1, in ?
  File "/home/was/sage/dist/sage/source/../local/lib/python2.4/site-packages/sage/schemes/hypersurfaces/plane_curves/elliptic/constructor.py", line 105, in EllipticCurve
    return ell_rational_field.EllipticCurve_rational_field(x, y)
  File "/home/was/sage/local/lib/python2.4/site-packages/sage/schemes/hypersurfaces/plane_curves/elliptic/ell_rational_field.py", line 81, in __init__
    ell_generic.EllipticCurve.__init__(self, [Q(x) for x in ainvs])
  File "/home/was/sage/local/lib/python2.4/site-packages/sage/rings/rational_field.py", line 97, in __call__
    return sage.rings.rational.Rational(x)
  File "_rational.pyx", line 96, in _rational.Rational.__init__
  File "_rational.pyx", line 147, in _rational.Rational.__set_value
TypeError: Unable to coerce Infinity (<class 'sage.rings.infinity.Infinity'>) to Rational

> /home/was/sage/sage-doc/tut/_rational.pyx(147)_rational.Rational.__set_value()
(Pdb)
For a list of commands in the debugger type ? at the (Pdb) prompt:

(Pdb) ?

Documented commands (type help <topic>):
========================================
EOF    break  condition  disable  help    list  q       step     w
a      bt     cont       down     ignore  n     quit    tbreak   whatis
alias  c      continue   enable   j       next  r       u        where
args   cl     d          exit     jump    p     return  unalias
b      clear  debug      h        l       pp    s       up

Type Ctrl-D or quit to return to SAGE.


1.8 Tab Completion

First create the three dimensional vector space $V=\mathbf{Q}^3$ .

sage: V = VectorSpace(QQ,3)
sage: V              
      Vector space of dimension 3 over Rational Field

Type the beginning of a line, then Ctrl-p to go back to each line you have entered that begins in that way. This works even if you completely exit SAGE and restart later. You can also do a reverse search through the history using Ctrl-r.

Another IPython feature (that uses readline) is that it is easy to list all member functions for $V$ using tab completion. Just type V., then type the [tab key] key on your keyboard:

sage: V.[tab key]
V._VectorSpace_generic__base_field
V._VectorSpace_generic__degree
V._VectorSpace_generic__is_sparse
V._VectorSpace_generic__set_vector_class
V._VectorSpace_generic__vector_class
V._echelon_coordinates
V.ambient_space
V.base_field
V.base_ring
V.basis
V.coordinates
V.degree
V.dimension
V.echelonized_basis
V.gen
V.gens
V.is_ambient
V.is_dense
V.is_full
V.is_sparse
V.list
V.matrix
V.ngens
V.random
V.random_element
V.subspace
V.subspace_with_basis
V.vector
V.vector_space
V.zero_vector
sage: V.

If you type the first few letters of a function, then [tab key], you get only functions that begin as indicated.

sage: V.i[tab key]
V.is_ambient  V.is_dense    V.is_full     V.is_sparse
sage: V.is_

1.9 Integrated Help System

SAGE contains an integrated help facility, which is actually a feature implemented by IPython. Type a function name followed by ? for the documentation for that function. The documentation contains (or will contain!) the file in which the function is defined, a description of each input argument, a description of each output argument, and examples illustrating usage.

Another useful feature is that if f is a Python function, then typing f?? displays the source code that defines f.

sage: V = VectorSpace(QQ,10)
sage: V
      Vector space of dimension 10 over Rational Field

sage: V.subspace?
Type:           instancemethod
Base Class:     <type 'instancemethod'>
...
Definition:     V.subspace(self, gens)
Docstring:
    Create a subspace of self.

    INPUT:
        gens -- a list of vector in self
    OUTPUT:
        VectorSpace -- the subspace spanned by the vectors in the 
        list gens. The basis for the subspace is always put in 
        reduced row echelon form.
    EXAMPLES:
        >>> import sage.rings.rings as rings
        >>> V = VectorSpace(rings.RationalField(), 3)
        >>> B = V.basis()
        >>> W = V.subspace([B[0]+B[1], 2*B[1]-B[2]])
        >>> W
        Vector space of degree 3, dimension 2 over Rational Field
        Basis matrix:
        [   1    0  1/2]
        [   0    1 -1/2]
You may also type help(command_name) or help(class) for a man page like help file about a given class. This documentation is automatically extracted from the source code.

sage: help(VectorSpace)
Help on class VectorSpace ...

class VectorSpace(__builtin__.object)
 |  Create a Vector Space.
 |
 |  Two create an ambient space over a field with given dimension
 |  using the calling syntax ...
 :
 :
When you type q to exit the help system, your session appears just as it was. The help listing does not clutter up your session, unlike the output of function_name?.

sage: help(VectorSpace)
...
sage:

1.10 Data Types

sage: V = VectorSpace(QQ,10)
sage: type(V)
      <class 'sage.modules.free_module.FreeModule_ambient_field'>

Only certain functions can be called on $V$ . In most other math software systems, these would be called using the notation foo(V,...). In SAGE, the functions belong to the class of $V$ , and are called using an object-oriented syntax like in Java or C++, i.e., V.foo(...). This helps keep the global namespace from being polluted with thousands of functions.

In many (but not all) cases functional notation is also supported for convenience and because mathematical expressions might look confusing using object-oriented notation:

sage: 2.sqrt()
      1.4142135623730951
sage: sqrt(2)
      1.4142135623730951
sage: V = VectorSpace(QQ,2)
sage: V.basis()
      [(1, 0), (0, 1)]
sage: basis(V)
      [(1, 0), (0, 1)]
sage: M = MatrixSpace(GF(7), 2)
sage: M
      Full MatrixSpace of 2 by 2 dense matrices over Finite field of size 7
sage: A = M([1,2,3,4])
sage: A
      [1 2]
      [3 4]
sage: powers = [A^i for i in range(2,100)]
sage: powers.index(A)
      47
sage: A^49    #the range of powers was shifted by 2, so 47 shifts to 49.
      [1 2]
      [3 4]
sage: A.charpoly()
      x^2 + 2*x + 5
sage: charpoly(A)
      x^2 + 2*x + 5

To list all member functions for $A$ , use tab completion. Just type A., then type the [tab key] key on your keyboard, as explained in Section 1.8.

Other data types include lists, whose elements are indexed starting from 0 :

sage: L = [factor(n) for n in range(20)]
sage: print L
      [(1), (1), 2, 3, 2^2, 5, 2 * 3, 7, 2^3, 3^2, 2 * 5, 11, 2^2 * 3, 13, 2 * 7, 3 * 5, 2^4, 17, 2 * 3^2, 19]
sage: L[0]
      (1)
sage: L[12]
      2^2 * 3
sage: type(L[12])
      <class 'sage.structure.factorization.Factorization'>

List slicing is a wonderful feature. If L is a list, then L[m:n] returns the sublist of L obtained by starting at the $m$ th element and stoping at the $ (n-1)$ st element, as illustrated below. blue

sage: L = [factor(n) for n in range(20)]
sage: L[5:10]
      [5, 2 * 3, 7, 2^3, 3^2]
sage: print L[:5]
      [(1), (1), 2, 3, 2^2]
sage: L[15:5]
      []
sage: L[15:]
      [3 * 5, 2^4, 17, 2 * 3^2, 19]

1.11 Control Statements and Comparisons

We have seen a few examples already of some common uses of for loops. In Python, a for loop has an indented structure, such as

>>> for i in range(5):
       print(i)
   
      0
      1
      2
      3
      4
Note the colon at the end of the for statement (there is no ``do'' or ``od'' as in GAP or Maple), and the indentation before the ``body'' of the loop, namely print(i). This indentation is important. In SAGE, the indentation is automatically put in for you when you hit enter after a ``:'', as illustrated below.

sage: for i in range(5):
   ....:    print(i)  # now hit enter twice
   ....:
      0
      1
      2
      3
      4
sage:

The symbol = is used for assignment. The symbol == is used to check for equality:

sage: for i in range(15):
   ....:    if gcd(i,15)==1:
   ....:        print(i)
   ....:
      1
      2
      4
      7
      8
      11
      13
      14
Programming in SAGE is not too hard if you keep in mind the indentation requirement for if and for statements:

sage: def legendre(a,p):
   ....:    is_sqr_modp=-1
   ....:    for i in range(p):
   ....:        if a % p == i^2 % p:
   ....:            is_sqr_modp=1
   ....:    return is_sqr_modp
   ....:
sage: legendre(2,7)
      1
sage: legendre(3,7)
      -1
Of course this is not an efficient implementation of the Legendre symbol! It is meant to illustrate various aspects of Python/SAGE programming. The function kronecker, which comes with SAGE, computes the Legendre symbol efficiently via a C-library call to PARI.

Finally, we note that comparisons, such as ==, !=, <=, >=, >, <, between numbers will automatically convert both numbers into the same type if possible:

sage: 2 < 3.1; 3.1 <= 1; 2 < 3.1 <= 1
      True
      False
      False
sage: 2/3 < 3/2;   3/2 < 3/1
      True
      True
Almost any two objects may be compared; there is no assumption that the objects are equipped with a total or partial ordering.
sage: 2 < 3.1+0.0*i; 3.1+2*i<4+3*i; 4+3*i < 3.1+2*i
      True
      True
      False
When comparing objects of different types in SAGE, in most cases SAGE tries to find a coercion of both objects to a common parent (with a preference for the parent of the object on the left) and if successful the comparison is performed between the coerced objects; if not successful the objects are considered not equal (more precisely the left object is less than the right object). For testing whether two variables reference the same object use is. For example:
sage: 1 is 2/2
      False
sage: 1 is 1
      False
sage: 1 == 2/2
      True

The first is False, because the object on the left is an integer, and the one on the right is a rational, so they are not the same object. The second is False, because the 1's are constructed separately, so are not the same object (even though they are considered equal). The third is True, since the rational on the right can be coerced into the integers.

See About this document... for information on suggesting changes.