Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download

All published worksheets from http://sagenb.org

Views: 168727
Image: ubuntu2004

Algebraic number theory and related topics

at RIMS, 2010/12/6-10

Sage for Number Theorists

Iwao KIMURA (University of Toyama)

 

This is a Sage notebook which I gave a demonstration of doing math (number theory) by Sage.

As a calculator

1+1 # as a calculator. Shift + Enter == Evaluate
\newcommand{\Bold}[1]{\mathbf{#1}}2
factorial(100) # long integer
\newcommand{\Bold}[1]{\mathbf{#1}}93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
factor(2^2^5+1) # prime factorization of the 5-th Fermat number (composite number).
\newcommand{\Bold}[1]{\mathbf{#1}}641 \cdot 6700417
a = 2 # variable.
a
\newcommand{\Bold}[1]{\mathbf{#1}}2
a = "2" # variable does not have a type (values have.)
a == 2
\newcommand{\Bold}[1]{\mathbf{#1}}{\rm False}
a == "2"
\newcommand{\Bold}[1]{\mathbf{#1}}{\rm True}
type(a) # inspect the type of value contained in a
\newcommand{\Bold}[1]{\mathbf{#1}}\hbox{ [removed] }
type(2)
\newcommand{\Bold}[1]{\mathbf{#1}}\hbox{ [removed] }
a = [2]
type(a)
\newcommand{\Bold}[1]{\mathbf{#1}}\hbox{ [removed] }
parent(2)
\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Z}
parent('2')
\newcommand{\Bold}[1]{\mathbf{#1}}\hbox{ [removed] }

2D Plotting

plot(sin(1/x), (0,pi))
def zeta_plot(x): """ parametric plot of Riemann zeta function on the critical line. 1/2 + t*I, 0<= t <= x. """ t=var('t') parametric_plot((lambda t: real(zeta(1/2+t*I)), lambda t: imaginary(zeta(1/2+t*I))), (t, 0, x)).show()
zeta_plot(50.0)

Interactive plotting

A = matrix([[1,1],[-1,1]]) D = [vector([0,0]), vector([1,0])] @interact def f(A = matrix([[1,1],[-1,1]]), D = '[[0,0],[1,0]]', k=(3..17)): print "Det = ", A.det() D = matrix(eval(D)).rows() def Dn(k): ans = [] for d in Tuples(D, k): s = sum(A^n*d[n] for n in range(k)) ans.append(s) return ans G = points([v.list() for v in Dn(k)]) show(G, frame=True, axes=False)

3D graphic

t = Tachyon(xres=640,yres=480, camera_center=(5,0,0)) t.light((4,3,2), 0.2, (1,1,1)) t.texture('t2', ambient=0.1, diffuse=0.9, specular=0.5, opacity=0.8, color=(1,0, 0)) t.texture('t3', ambient=0.1, diffuse=0.9, specular=0.5, opacity=0.7, color=(0,1, 0)) t.texture('t4', ambient=0.1, diffuse=0.9, specular=0.5, opacity=0.6, color=(0,0, 1)) t.texture('t5', ambient=0.1, diffuse=0.9, specular=0.5, opacity=0.9, color=(0,1, 1)) for k in range(2,6): t.sphere((0,0.25*k, (0.25*k)^2), 0.4, 't%s'%(k)) t.show()

Taken from somewhere...

 

There are a lot of good looking pictures or plotting drawn by Sage.

t = Tachyon(xres=1024,yres=768, camera_center=(3,0.2,0), raydepth=8) t.light((4,3,2), 0.2, (1,1,1)) t.texture('t0', ambient=0.1, diffuse=0.9, specular=0.5, opacity=1.0, color=(1.0,0,0)) t.texture('t1', ambient=0.1, diffuse=0.9, specular=0.3, opacity=1.0, color=(0,1.0,0)) t.texture('t2', ambient=0.2,diffuse=0.7, specular=0.5, opacity=0.7, color=(0,0,1.0)) t.texture('white', color=(1,1,1)) t.plane((0,0,-1), (0,0,1), 'white') t.plane((0,-20,0), (0,1,0), 'white') t.plane((-20,0,0), (1,0,0), 'white') k=0 for i in srange(-1,2,0.05): k += 1 t.sphere((i, i^2 - 0.5*i, 0.5*i^3), 0.1, 't%s'%(k%3)) t.cylinder((0,0,0), (0,0,1), 0.05,'t1') t.show()

Another 3D plotting...

 

3D interactive graphics are drawn by JMol (Java applet).

u, v = var('u,v') fx = (3+sin(v)+cos(u))*cos(2*v) fy = (3+sin(v)+cos(u))*sin(2*v) fz = sin(u)+2*cos(v) parametric_plot3d([fx, fy, fz], (u, 0, 2*pi), (v, 0, 2*pi), frame=False, color="red")

Tiny examples of functions (defining and invoking functions)

# Function definition def is_even(n): return n % 2 == 0
is_even(4)
\newcommand{\Bold}[1]{\mathbf{#1}}{\rm True}
is_even(5)
\newcommand{\Bold}[1]{\mathbf{#1}}{\rm False}
# generate even numbers up to n def evens(n): v = [] for i in xrange(1, n + 1): if is_even(i): v.append(i) return v
evens(10)
\newcommand{\Bold}[1]{\mathbf{#1}}\left[2, 4, 6, 8, 10\right]

But this is done by... (Python's "list comprehension")

[x for x in xrange(2,11,2)]
\newcommand{\Bold}[1]{\mathbf{#1}}\left[2, 4, 6, 8, 10\right]

Cython

---Interface to C---

The example is to compute n-th Harmonic number, the sum of 1/m, m=1,...,n. (cf. Prof. M. Kida's talk on Magma at this workshop, 2008/Dec).

Firstly, pure Sage (Python) version:

def harmonic(n): r = 0 for m in xrange(1, n+1): r += 1/m return r

One can measure the time to compute something by timeit().

timeit('harmonic(5*10^4)');
5 loops, best of 3: 2.04 s per loop

Writing Cython code, one can incorporate C/C++ code into Sage.

The same routine written in C with GMP.

%cython r""" Study of using cython. sage: load study_pyrex.pyx This is as fast as one which written in Python/Sage. """ cdef extern from "gmp.h": ctypedef void* mpz_t ctypedef void* mpq_t void mpz_init(mpz_t integer) void mpq_init(mpq_t rational) void mpq_set_ui(mpq_t r, unsigned long a, unsigned long b) void mpq_inv(mpq_t inverted_num, mpq_t num) void mpq_add(mpq_t r, mpq_t a, mpq_t b) char *mpq_get_str(char *str, int base, mpq_t num) cdef extern from "stdlib.h": void free(void *ptr) def harmonic(int n): cdef mpq_t r # register cdef mpq_t t # tmp var cdef unsigned long c cdef char *s mpq_init(r) mpq_init(t) _sig_on for c from 1 <= c <= n: mpq_set_ui(t, 1L, c) # t <- 1/c mpq_add(r, r, t) # r <- r+(1/c) s = mpq_get_str(NULL, 10, r) _sig_off from sage.rings.rational import Rational u = Rational(s) free(s) return u
harmonic?

File: /home/iwao/sage-4.5.3-linux-32bit-ubuntu_10.04_lts-i686-Linux/devel/sage/_home_iwao__sage_sage_notebook_sagenb_home_admin_3_code_sage31_spyx_0.pyx

Type: <type 'builtin_function_or_method'>

Definition: harmonic( [noargspec] )

Docstring:

C/Cython version seems 120% faster than original Sage version.

timeit('harmonic(5*10^4)')
5 loops, best of 3: 1.68 s per loop

The same function can be written without using loop (sum of list version) , this is a bit faster than

original for loop version, but slower than C/Cython version.

timeit('sum([1/x for x in xrange(1, 5*10^4+1)])')
5 loops, best of 3: 1.97 s per loop

Rings, Fields and Polynomials

QQ # the field of rational numbers
\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Q}
ZZ # the ring of rational integers
\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Z}
RR # the field of real numbers
\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{R}
CC # the field of complex numbers
\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{C}
Q7 = Qp(7); Q7 # the field of p-adic numbers, here p = 7
\newcommand{\Bold}[1]{\mathbf{#1}}\QQ_{7}
F7 = FiniteField(7); F7 # the field of 7-elements.
\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{F}_{7}

We can construct the ring of polynomials over Q by several way.

R.<x> = PolynomialRing(QQ); R # univariate polynomial ring over Q, indeterminate is x.
\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Q}[x]
R = QQ['x']; R # the same thing as above. TMWTDI.
\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Q}[x]
R.<x> = QQ[]; R # This works!
\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Q}[x]

What is 'x'?

parent(x)
\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Q}[x]
f = 2*x^2+3*x+1; f
\newcommand{\Bold}[1]{\mathbf{#1}}2 x^{2} + 3 x + 1
factor(f) # polynomial factorization
\newcommand{\Bold}[1]{\mathbf{#1}}\left(2\right) \cdot (x + \frac{1}{2}) \cdot (x + 1)
S = Q7['x']; S
\newcommand{\Bold}[1]{\mathbf{#1}}\QQ_{7}[x]
f7 = S(2*x^2+3*x+1); f7 # same polynomial, but over Q7.
\newcommand{\Bold}[1]{\mathbf{#1}}\left(2 + O(7^{20})\right) x^{2} + \left(3 + O(7^{20})\right) x + 1 + O(7^{20})
factor(f7) # -1/2 to be 7-adic number.
\newcommand{\Bold}[1]{\mathbf{#1}}\left(2 + O(7^{20})\right) \cdot (\left(1 + O(7^{20})\right) x + 1 + O(7^{20})) \cdot (\left(1 + O(7^{20})\right) x + 4 + 3 \cdot 7 + 3 \cdot 7^{2} + 3 \cdot 7^{3} + 3 \cdot 7^{4} + 3 \cdot 7^{5} + 3 \cdot 7^{6} + 3 \cdot 7^{7} + 3 \cdot 7^{8} + 3 \cdot 7^{9} + 3 \cdot 7^{10} + 3 \cdot 7^{11} + 3 \cdot 7^{12} + 3 \cdot 7^{13} + 3 \cdot 7^{14} + 3 \cdot 7^{15} + 3 \cdot 7^{16} + 3 \cdot 7^{17} + 3 \cdot 7^{18} + 3 \cdot 7^{19} + O(7^{20}))

Automatic Coercions!

see http://sagemath.blogspot.com/2010/11/brief-history-and-motivation-behind.html

f(x)Q[x]f(x)\in\mathbf{Q}[x], f7(x)Q7[x]f7(x)\in\mathbf{Q}_7[x].

f+f7
\newcommand{\Bold}[1]{\mathbf{#1}}\left(4 + O(7^{20})\right) x^{2} + \left(6 + O(7^{20})\right) x + 2 + O(7^{20})
fcyc = R.cyclotomic_polynomial(7); fcyc # the 7-th cyclotomic polynomial over Q
\newcommand{\Bold}[1]{\mathbf{#1}}x^{6} + x^{5} + x^{4} + x^{3} + x^{2} + x + 1
factor(fcyc)
\newcommand{\Bold}[1]{\mathbf{#1}}(x^{6} + x^{5} + x^{4} + x^{3} + x^{2} + x + 1)
fcyc.is_irreducible()
\newcommand{\Bold}[1]{\mathbf{#1}}{\rm True}
S(fcyc)
\newcommand{\Bold}[1]{\mathbf{#1}}\left(1 + O(7^{20})\right) x^{6} + \left(1 + O(7^{20})\right) x^{5} + \left(1 + O(7^{20})\right) x^{4} + \left(1 + O(7^{20})\right) x^{3} + \left(1 + O(7^{20})\right) x^{2} + \left(1 + O(7^{20})\right) x + 1 + O(7^{20})
factor(S(fcyc))
\newcommand{\Bold}[1]{\mathbf{#1}}(\left(1 + O(7^{20})\right) x^{6} + \left(1 + O(7^{20})\right) x^{5} + \left(1 + O(7^{20})\right) x^{4} + \left(1 + O(7^{20})\right) x^{3} + \left(1 + O(7^{20})\right) x^{2} + \left(1 + O(7^{20})\right) x + 1 + O(7^{20}))
factor(PolynomialRing(F7,'x')(fcyc))
\newcommand{\Bold}[1]{\mathbf{#1}}(x + 6)^{6}

Number Theory

Some standard functionality for algebraic number fields are supplied by Sage. One can invoke pari-gp.

Note that the computation in Sage are done rigorously, in another word, not assuming any unproven hypothesis.

One can specify some parameter to assume some heuristics.

k=QuadraticField(-23, 'd'); k # an imaginary quadratic field
\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Q}[\sqrt{-23}]/(\sqrt{-23}^{2} + 23)
k.discriminant() # its discriminant
\newcommand{\Bold}[1]{\mathbf{#1}}-23
k.class_number() # its class number
\newcommand{\Bold}[1]{\mathbf{#1}}3
kk=QuadraticField(-974, 'd'); kk
\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Q}[\sqrt{-974}]/(\sqrt{-974}^{2} + 974)
kk.class_number()
\newcommand{\Bold}[1]{\mathbf{#1}}36
C=kk.class_group(); C
\newcommand{\Bold}[1]{\mathbf{#1}}AbelianGroup(2,[12,3])\mathrm{AbelianGroup}( 2, [12, 3] )
C.elementary_divisors()
\newcommand{\Bold}[1]{\mathbf{#1}}\left[3, 12\right]
F=QuadraticField(199,'d'); F # a real quadratic field
\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Q}[\sqrt{199}]/(\sqrt{199}^{2} - 199)
F.discriminant() # its discriminant
\newcommand{\Bold}[1]{\mathbf{#1}}796
F.class_number() # its class number
\newcommand{\Bold}[1]{\mathbf{#1}}1
F.units() # its unit group (non-fundamental?)
\newcommand{\Bold}[1]{\mathbf{#1}}\left[1153080099 \sqrt{199} - 16266196520\right]
e = F.units()[0]; e
\newcommand{\Bold}[1]{\mathbf{#1}}1153080099 \sqrt{199} - 16266196520
-1/e # fundamental
\newcommand{\Bold}[1]{\mathbf{#1}}1153080099 \sqrt{199} + 16266196520

One can invoke pari-gp inside Sage.

pari-gp's quadunit() returns the fundamental unit of real quadratic fields.

%gp quadunit(4*199)
16266196520 + 1153080099*w

Cyclotomic fields

k=CyclotomicField(7); k
\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Q}(\zeta_{7})
print k.class_number(), k.units()
1 [zeta7^5 + 1, zeta7^5 + zeta7]

List of subfields of Q(ζ7)\mathbf{Q}(\zeta_7). But the display of outputs seems buggy...(the results is correct).

k.subfields()
\newcommand{\Bold}[1]{\mathbf{#1}}\left[\left(\Bold{Q}[\zeta_{70}]/(\zeta_{70} + 1), \hbox{Ring morphism: From: Number Field in zeta70 with defining polynomial x + 1 To: Cyclotomic Field of order 7 and degree 6 Defn: -1 |--> -1}, \mbox{\mathrm{None}}\right), \left(\Bold{Q}[\zeta_{71}]/(\zeta_{71}^{2} + \zeta_{71} + 2), \hbox{Ring morphism: From: Number Field in zeta71 with defining polynomial x^2 + x + 2 To: Cyclotomic Field of order 7 and degree 6 Defn: zeta71 |--> zeta7^4 + zeta7^2 + zeta7}, \mbox{\mathrm{None}}\right), \left(\Bold{Q}[\zeta_{72}]/(\zeta_{72}^{3} + \zeta_{72}^{2} - 2 \zeta_{72} - 1), \hbox{Ring morphism: From: Number Field in zeta72 with defining polynomial x^3 + x^2 - 2*x - 1 To: Cyclotomic Field of order 7 and degree 6 Defn: zeta72 |--> -zeta7^5 - zeta7^4 - zeta7^3 - zeta7^2 - 1}, \mbox{\mathrm{None}}\right), \left(\Bold{Q}[\zeta_{73}]/(\zeta_{73}^{6} + \zeta_{73}^{5} + \zeta_{73}^{4} + \zeta_{73}^{3} + \zeta_{73}^{2} + \zeta_{73} + 1), \hbox{Ring morphism: From: Number Field in zeta73 with defining polynomial x^6 + x^5 + x^4 + x^3 + x^2 + x + 1 To: Cyclotomic Field of order 7 and degree 6 Defn: zeta73 |--> zeta7}, \hbox{Ring morphism: From: Cyclotomic Field of order 7 and degree 6 To: Number Field in zeta73 with defining polynomial x^6 + x^5 + x^4 + x^3 + x^2 + x + 1 Defn: zeta7 |--> zeta73}\right)\right]
fcyc # the 7-th cylotomic polynomial over Q
\newcommand{\Bold}[1]{\mathbf{#1}}x^{6} + x^{5} + x^{4} + x^{3} + x^{2} + x + 1
S.<x>=PolynomialRing(k,'x'); S # the univariate polynomial ring over the 7-th cyclotomic field Q(zeta7)
\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Q}(\zeta_{7})[x]
S.cyclotomic_polynomial(7).factor() # try to factor the 7-th cylotomic polynomial over Q(zeta7)
\newcommand{\Bold}[1]{\mathbf{#1}}(x - \zeta_{7}) \cdot (x - \zeta_{7}^{2}) \cdot (x - \zeta_{7}^{3}) \cdot (x - \zeta_{7}^{4}) \cdot (x - \zeta_{7}^{5}) \cdot (x + \zeta_{7}^{5} + \zeta_{7}^{4} + \zeta_{7}^{3} + \zeta_{7}^{2} + \zeta_{7} + 1)

Dirichlet Characters

One can easily construct a group of Dirichlet characters of given conductor.

DG23 = DirichletGroup(23); DG23
\newcommand{\Bold}[1]{\mathbf{#1}}\hbox{Group of Dirichlet characters of modulus 23 over Cyclotomic Field of order 22 and degree 10}
DG23.gens()
\newcommand{\Bold}[1]{\mathbf{#1}}\left(Dirichlet character modulo 23 of conductor 23 mapping 5ζ225 \mapsto \zeta_{22}\right)
g=DG23.gen(); g
\newcommand{\Bold}[1]{\mathbf{#1}}Dirichlet character modulo 23 of conductor 23 mapping 5ζ225 \mapsto \zeta_{22}
g.bernoulli(1)
\newcommand{\Bold}[1]{\mathbf{#1}}-\frac{6}{23} \zeta_{22}^{9} + \frac{14}{23} \zeta_{22}^{8} + \frac{6}{23} \zeta_{22}^{7} - \frac{2}{23} \zeta_{22}^{6} + \frac{12}{23} \zeta_{22}^{5} - \frac{10}{23} \zeta_{22}^{4} - \frac{8}{23} \zeta_{22}^{3} - \frac{14}{23} \zeta_{22}^{2} - \frac{18}{23} \zeta_{22} - \frac{16}{23}

By the analytic class number formula for an imaginary abelian field, we can compute

the relative class number of Q(ζ23)\mathbf{Q}(\zeta_23). (w=223w=2*23, Q=1Q=1):

h(Q(ζ23))=wQχXB1,χ2.h(\mathbf{Q}(\zeta_{23}))=wQ\prod_{\chi\in X^-}-\frac{B_{1,\chi}}{2}.

Dr. T. Taniguchi (Gakushuin) will give a lecture on sophisticated way to compute

the relative class numbers of pp-th cyclotomic fields on 2010/Dec/26 at Kanazawa.

2*23*prod([-c.bernoulli(1)/2 for c in DG23 if c.is_odd()])
\newcommand{\Bold}[1]{\mathbf{#1}}3

For a number field, Sage provides class_number() function, but this fails sadly ;_;

NumberField(R.cyclotomic_polynomial(23),'a').class_number(proof=False)
\newcommand{\Bold}[1]{\mathbf{#1}}3

This is because, as said before, Sage try to compute without any unproven hypothesis.

If one specify 'proof=False' option, Sage (in fact, pari library) computes class numbers

using Heuristic bound for the norm of generators of ideal class group. The result may not

be correct, but almost ok.

Table of Number Fields

Install extra package:

install_package('database_jones_numfield-v4')

JonesDatabase??

File: /home/iwao/sage-4.5.3-linux-32bit-ubuntu_10.04_lts-i686-Linux/local/lib/python2.6/site-packages/sage/databases/jones.py

Source Code (starting at line 80):

class JonesDatabase:
    def __init__(self):
        self.root = None

    def __repr__(self):
        return "John Jones's table of number fields with bounded ramification and degree <= 6"

    def _load(self, path, filename):
        print filename
        i = 0
        while filename[i].isalpha():
            i += 1
        j = len(filename)-1
        while filename[j].isalpha() or filename[j] in [".", "_"]:
            j -= 1
        S = [eval(z) for z in filename[i:j+1].split("-")]
        S.sort()
        data = open(path + "/" + filename).read()
        data = data.replace("^","**")
        x = PolynomialRing(RationalField(), 'x').gen()
        v = eval(data)
        s = tuple(S)
        if self.root.has_key(s):
            self.root[s] += v
            self.root[s].sort()
        else:
            self.root[s] = v


    def _init(self, path):
        """
        Create the database from scratch from the PARI files on John Jones's
        web page, downloaded (e.g., via wget) to a local directory, which
        is specified as path above.

        INPUT:


        -  ``path`` - (default works on William Stein install.)
           path must be the path to Jones's Number_Fields directory
           http://hobbes.la.asu.edu/Number_Fields These files should have
           been downloaded using wget.


        EXAMPLE: This is how to create the database from scratch, assuming
        that the number fields are in the default directory above: From a
        cold start of Sage::

                sage: J = JonesDatabase()
                sage: J._init()   # not tested
                ...
            This takes about 5 seconds.
        """
        n = 0
        x = PolynomialRing(RationalField(),'x').gen()
        self.root = {}
        self.root[tuple([])] = [x-1]
        if not os.path.exists(path):
            raise IOError, "Path %s does not exist."%path
        for X in os.listdir(path):
            if X[-4:] == "solo":
                Z = path + "/" + X
                print X
                for Y in os.listdir(Z):
                    if Y[-3:] == ".gp":
                        self._load(Z, Y)
        if not os.path.exists(JONESDATA):
            os.makedirs(JONESDATA)
        save(self.root, JONESDATA+ "/jones.sobj")

    def unramified_outside(self, S, d=None, var='a'):
        """
        Return all fields in the database of degree d unramified
        outside S. If d is omitted, return fields of any degree up to 6.
        The fields are ordered by degree and discriminant.

        INPUT:


        -  ``S`` - list or set of primes, or a single prime

        -  ``d`` - None (default, in which case all fields of degree <= 6 are returned)
           or a positive integer giving the degree of the number fields returned.

        -  ``var`` - the name used for the generator of the number fields (default 'a').

        EXAMPLES::

            sage: J = JonesDatabase()             # optional - jones_database
            sage: J.unramified_outside([101,109]) # optional - jones_database
            [Number Field in a with defining polynomial x - 1,
             Number Field in a with defining polynomial x^2 - 101,
             Number Field in a with defining polynomial x^2 - 109,
             Number Field in a with defining polynomial x^3 - x^2 - 36*x + 4,
             Number Field in a with defining polynomial x^4 - x^3 + 13*x^2 - 19*x + 361,
             Number Field in a with defining polynomial x^4 - x^3 + 14*x^2 + 34*x + 393,
             Number Field in a with defining polynomial x^5 + 2*x^4 + 7*x^3 + 4*x^2 + 11*x - 6,
             Number Field in a with defining polynomial x^5 + x^4 - 6*x^3 - x^2 + 18*x + 4,
             Number Field in a with defining polynomial x^5 - x^4 - 40*x^3 - 93*x^2 - 21*x + 17]
        """
        try:
            S = list(S)
        except TypeError:
            S = [S]
        Z = []
        for X in powerset(S):
            Z += self.ramified_at(X, d=d, var=var)
        Z = [(k.degree(), k.discriminant().abs(), k.discriminant() > 0, k) for k in Z]
        Z.sort()
        return [z[-1] for z in Z]

    def __getitem__(self, S):
        return self.get(S)

    def get(self, S, var='a'):
        """
        Return all fields in the database ramified exactly at
        the primes in S.

        INPUT:

        -  ``S`` - list or set of primes, or a single prime

        -  ``var`` - the name used for the generator of the number fields (default 'a').

        EXAMPLES::

            sage: J = JonesDatabase()              # optional - jones_database
            sage: J.get(163, var='z')              # optional - jones_database
            [Number Field in z with defining polynomial x^2 + 163,
             Number Field in z with defining polynomial x^3 - x^2 - 54*x + 169,
             Number Field in z with defining polynomial x^4 - x^3 - 7*x^2 + 2*x + 9]
            sage: J.get([3, 4])                    # optional - jones_database
            Traceback (most recent call last):
            ...
            ValueError: S must be a list of primes
        """
        if self.root is None:
            if os.path.exists(JONESDATA+ "/jones.sobj"):
                self.root = load(JONESDATA+ "/jones.sobj")
            else:
                raise RuntimeError, "You must install the Jones database optional package."
        try:
            S = list(S)
        except TypeError:
            S = [S]
        if not all([p.is_prime() for p in S]):
            raise ValueError, "S must be a list of primes"
        S.sort()
        s = tuple(S)
        if not self.root.has_key(s):
            return []
        return [NumberField(f, var, check=False) for f in self.root[s]]

    def ramified_at(self, S, d=None, var='a'):
        """
        Return all fields in the database of degree d ramified exactly at
        the primes in S.  The fields are ordered by degree and discriminant.

        INPUT:

        -  ``S`` - list or set of primes

        -  ``d`` - None (default, in which case all fields of degree <= 6 are returned)
           or a positive integer giving the degree of the number fields returned.

        -  ``var`` - the name used for the generator of the number fields (default 'a').

        EXAMPLES::

            sage: J = JonesDatabase()              # optional - jones_database
            sage: J.ramified_at([101,109])         # optional - jones_database
            []
            sage: J.ramified_at([109])             # optional - jones_database
            [Number Field in a with defining polynomial x^2 - 109,
             Number Field in a with defining polynomial x^3 - x^2 - 36*x + 4,
             Number Field in a with defining polynomial x^4 - x^3 + 14*x^2 + 34*x + 393]
            sage: J.ramified_at(101)               # optional - jones_database
            [Number Field in a with defining polynomial x^2 - 101,
             Number Field in a with defining polynomial x^4 - x^3 + 13*x^2 - 19*x + 361,
             Number Field in a with defining polynomial x^5 + 2*x^4 + 7*x^3 + 4*x^2 + 11*x - 6,
             Number Field in a with defining polynomial x^5 + x^4 - 6*x^3 - x^2 + 18*x + 4,
             Number Field in a with defining polynomial x^5 - x^4 - 40*x^3 - 93*x^2 - 21*x + 17]
            sage: J.ramified_at((2, 5, 29), 3, 'c') # optional - jones_database
            [Number Field in c with defining polynomial x^3 - x^2 - 8*x - 28,
             Number Field in c with defining polynomial x^3 - x^2 + 10*x + 102,
             Number Field in c with defining polynomial x^3 - x^2 + 97*x - 333,
             Number Field in c with defining polynomial x^3 - x^2 - 48*x - 188]
        """
        Z = self.get(S, var=var)
        if d == None:
            Z = [(k.degree(), k.discriminant().abs(), k.discriminant() > 0, k) for k in Z]
        else:
            Z = [(k.discriminant().abs(), k.discriminant() > 0, k) for k in Z if k.degree() == d]
        Z.sort()
        return [z[-1] for z in Z]
J=JonesDatabase(); J
\newcommand{\Bold}[1]{\mathbf{#1}}\hbox{John Jones's table of number fields with bounded ramification and degree < = 6}
for f in J.unramified_outside(2): print f
Number Field in a with defining polynomial x - 1 Number Field in a with defining polynomial x^2 + 1 Number Field in a with defining polynomial x^2 + 2 Number Field in a with defining polynomial x^2 - 2 Number Field in a with defining polynomial x^4 + 1 Number Field in a with defining polynomial x^4 - 2*x^2 + 2 Number Field in a with defining polynomial x^4 - 2*x^2 - 1 Number Field in a with defining polynomial x^4 - 2 Number Field in a with defining polynomial x^4 - 4*x^2 + 2 Number Field in a with defining polynomial x^4 + 2 Number Field in a with defining polynomial x^4 + 4*x^2 + 2

Finite Fields

p = next_prime(10^5); p # the prime next to 10^5
\newcommand{\Bold}[1]{\mathbf{#1}}100003
F = FiniteField(p); F # the finite field of p elements
\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{F}_{100003}
b=F.multiplicative_generator(); b # a primitive root mod p
\newcommand{\Bold}[1]{\mathbf{#1}}2
F(3).log(b) # the discrete log of 3 w. r. t. b
\newcommand{\Bold}[1]{\mathbf{#1}}86449
b^86449
\newcommand{\Bold}[1]{\mathbf{#1}}3

One can get a finite field with p-power elements.

FF = FiniteField(p^2, 'a'); FF
\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{F}_{100003^{2}}

Elliptic Curves

E = EllipticCurve([-82, 0]); E # if only 2 arg's a, b are given, then it means y^2 = x^3 + ax + b.
\newcommand{\Bold}[1]{\mathbf{#1}}y^2 = x^3 - 82x
E.discriminant().factor() # good red. outside 2, 41.
\newcommand{\Bold}[1]{\mathbf{#1}}2^{9} \cdot 41^{3}
E.gens() # generator of rational points.
\newcommand{\Bold}[1]{\mathbf{#1}}\left[\left(-9 : 3 : 1\right), \left(-8 : 12 : 1\right), \left(-1 : 9 : 1\right)\right]
E.rank() # the Mordell-Weil rank is 3.
\newcommand{\Bold}[1]{\mathbf{#1}}3
E.has_cm() # this is CM elliptic curve.
\newcommand{\Bold}[1]{\mathbf{#1}}{\rm True}
L=E.lseries(); L
\newcommand{\Bold}[1]{\mathbf{#1}}\hbox{Complex L-series of the Elliptic Curve defined by y^2 = x^3 - 82*x over Rational Field}
L.taylor_series(a=1) # Taylor expansion at 1. Note that first 2 coeff's are so small, that this series seems to have order 3 at 1.
\newcommand{\Bold}[1]{\mathbf{#1}}\left(1.19494180421891 \times 10^{-22}\right)z + \left(-4.86468940988621 \times 10^{-22}\right)z^{2} + 17.7891345770978z^{3} - 72.4207775497614z^{4} + 161.461585497778z^{5} + O(z^{6})
E.analytic_rank() # Sage says so.
\newcommand{\Bold}[1]{\mathbf{#1}}3
E.analytic_rank?

File: /home/iwao/sage-4.5.3-linux-32bit-ubuntu_10.04_lts-i686-Linux/local/lib/python2.6/site-packages/sage/schemes/elliptic_curves/ell_rational_field.py

Type: <type ‘instancemethod’>

Definition: E.analytic_rank(algorithm=’cremona’)

Docstring:

Return an integer that is probably the analytic rank of this elliptic curve.

INPUT:

  • algorithm -
    • ‘cremona’ (default) - Use the Buhler-Gross algorithm as implemented in GP by Tom Womack and John Cremona, who note that their implementation is practical for any rank and conductor \leq 10^{10} in 10 minutes.
    • ‘sympow’ -use Watkins’s program sympow
    • ‘rubinstein’ - use Rubinstein’s L-function C++ program lcalc.
    • ‘magma’ - use MAGMA
    • ‘all’ - compute with all other free algorithms, check that the answers agree, and return the common answer.

Note

If the curve is loaded from the large Cremona database, then the modular degree is taken from the database.

Of the three above, probably Rubinstein’s is the most efficient (in some limited testing I’ve done).

Note

It is an open problem to prove that any particular elliptic curve has analytic rank \geq 4.

EXAMPLES:

sage: E = EllipticCurve('389a')
sage: E.analytic_rank(algorithm='cremona')
2
sage: E.analytic_rank(algorithm='rubinstein')
2
sage: E.analytic_rank(algorithm='sympow')
2
sage: E.analytic_rank(algorithm='magma')    # optional - magma
2
sage: E.analytic_rank(algorithm='all')
2

TESTS:

When the input is horrendous, some of the algorithms just bomb out with a RuntimeError:

sage: EllipticCurve([1234567,89101112]).analytic_rank(algorithm='rubinstein')
...
RuntimeError: unable to compute analytic rank using rubinstein algorithm ('unable to convert x (= 6.19283e+19 and is too large) to an integer')
sage: EllipticCurve([1234567,89101112]).analytic_rank(algorithm='sympow')
...
RuntimeError: failed to compute analytic rank

One can give an elliptic curves by its label.

E=EllipticCurve('15a2'); E
\newcommand{\Bold}[1]{\mathbf{#1}}y^2 + xy + y = x^3 + x^2 - 135x - 660
E.has_cm()
\newcommand{\Bold}[1]{\mathbf{#1}}{\rm False}
E.two_descent()
3 points of order 2: [-58:25:8], [-7:3:1], [13:-7:1] **************************** * Using 2-isogeny number 1 * **************************** Using 2-isogenous curve [0,164,0,6400,0] (minimal model [1,1,1,-10,-10]) ------------------------------------------------------- First step, determining 1st descent Selmer groups ------------------------------------------------------- After first local descent, rank bound = 0 rk(S^{phi}(E'))= 0 rk(S^{phi'}(E))= 2 ------------------------------------------------------- Second step, determining 2nd descent Selmer groups ------------------------------------------------------- ...skipping since we already know rank=0 After second local descent, rank bound = 0 rk(phi'(S^{2}(E)))= 0 rk(phi(S^{2}(E')))= 2 rk(S^{2}(E))= 2 rk(S^{2}(E'))= 2 Third step, determining E(Q)/phi(E'(Q)) and E'(Q)/phi'(E(Q)) ------------------------------------------------------- 1. E(Q)/phi(E'(Q)) ------------------------------------------------------- (c,d) =(-82,81) (c',d')=(164,6400) This component of the rank is 0 ------------------------------------------------------- 2. E'(Q)/phi'(E(Q)) ------------------------------------------------------- This component of the rank is 0 ------------------------------------------------------- Summary of results: ------------------------------------------------------- rank(E) = 0 #E(Q)/2E(Q) = 4 Information on III(E/Q): #III(E/Q)[phi'] = 1 #III(E/Q)[2] = 1 Information on III(E'/Q): #phi'(III(E/Q)[2]) = 1 #III(E'/Q)[phi] = 1 #III(E'/Q)[2] = 1 Searching for points (bound = 8)...done: found points of rank 0 and regulator 1 Processing points found during 2-descent...done: now regulator = 1 Saturating (bound = -1)...done: points were already saturated.
\newcommand{\Bold}[1]{\mathbf{#1}}{\rm True}
E.gens()
\newcommand{\Bold}[1]{\mathbf{#1}}\left[\right]
E.torsion_subgroup()
\newcommand{\Bold}[1]{\mathbf{#1}}\hbox{Torsion Subgroup isomorphic to Z/2 + Z/2 associated to the Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 135*x - 660 over Rational Field}

Invoke mwrank from Sage.

Prof. H. Nakamura (Okayama U.) asked me how to compute the rational points of

the elliptic curve y2=x320122xy^2 = x^3 - 2012^2 x by mwrank. If it has non-trivial rational point, then 20122012 is a congruent number.

The answer is...

E2012=EllipticCurve([-2012^2,0]); E2012
\newcommand{\Bold}[1]{\mathbf{#1}}y^2 = x^3 - 4048144x
E2012.a_invariants()
\newcommand{\Bold}[1]{\mathbf{#1}}\left(0, 0, 0, -4048144, 0\right)
E2012.discriminant()
\newcommand{\Bold}[1]{\mathbf{#1}}4245685614537534078976
factor(_)
\newcommand{\Bold}[1]{\mathbf{#1}}2^{18} \cdot 503^{6}
Emw=E2012.mwrank(options='-v 2 -b 15'); Emw
WARNING: Output truncated!
\newcommand{\Bold}[1]{\mathbf{#1}}\hbox{Curve [0,0,0,-4048144,0] : Working with minimal curve [0,0,0,-253009,0] via [u,r,s,t] = [2,0,0,0] 3 points of order 2: [-503:0:1], [0:0:1], [503:0:1] **************************** * Using 2-isogeny number 1 * **************************** (c,d) =(-1509,506018) (c',d')=(3018,253009) Using 2-isogenous curve [0,3018,0,253009,0] (minimal model [0,0,0,-2783099,1781689378]) ------------------------------------------------------- First step, determining 1st descent Selmer groups ------------------------------------------------------- Finding els gens for E (c= -1509, d= 506018) Support (length 3): [ -1 2 503 ] Adding (torsion) els generator #1: d1 = 2 Adding (torsion) els generator #2: d1 = 503 After els sieving, nelsgens = 2 2-rank of S^{phi}(E') = 2 (els)gens: [ 2 503 ] Finding els gens for E' (c'= 3018, d'= 253009) Support (length 2): [ -1 503 ] Adding els generator #1: d1 = -503 After els sieving, nelsgens = 1 2-rank of S^{phi'}(E) = 1 (els)gens: [ -503 ] After first local descent, rank bound = 1 rk(S^{phi}(E'))= 2 rk(S^{phi'}(E))= 1 ------------------------------------------------------- Second step, determining 2nd descent Selmer groups ------------------------------------------------------- Finding els2 gens for E (c= -1509, d= 506018) which lift to S^2(E) Adding (torsion) els2 generator #1: d1 = 2 Adding (torsion) els2 generator #2: d1 = 503 After els2 sieving, nels2gens = 2 2-rank of phi'(S^2(E)) = 2 (els2)gens: [ 2 503 ] Finding els2 gens for E' (c'= 3018, d'= 253009) which lift to S^2(E') Adding els2 generator #1: d1 = -503 After els2 sieving, nels2gens = 1 2-rank of phi(S^2(E')) = 1 (els2)gens: [ -503 ] After second local descent, rank bound = 1 rk(phi'(S^{2}(E)))= 2 rk(phi(S^{2}(E')))= 1 rk(S^{2}(E))= 3 rk(S^{2}(E'))= 2 **************************** * Using 2-isogeny number 2 * **************************** (c,d) =(0,-253009) ... Adding gls generator #1: d1 = 503 After second global descent, this component of the rank = 1 After gls sieving, nglsgens = 1 shortfall in rank from first descent = 1 shortfall in rank from second descent = 0 (gls)gens: [ 503 ] ------------------------------------------------------- Summary of results: ------------------------------------------------------- rank(E) = 1 #E(Q)/2E(Q) = 8 Information on III(E/Q): #III(E/Q)[phi'] = 1 #III(E/Q)[2] = 1 Information on III(E'/Q): #phi'(III(E/Q)[2]) = 1 #III(E'/Q)[phi] = 1 #III(E'/Q)[2] = 1 ------------------------------------------------------- List of points on E = [0,0,0,-253009,0]: I. Points on E mod phi(E') --none (modulo torsion). II. Points on phi(E') mod 2E Point [994307871645569627047428600416268913587328092332888130249253692413707056:4967608849400271416394655945252424440618658426542146432595803800874670020:1928317088832685492020566294646267423214258259206809092654393913813973], height = 106.721376885791 ------------------------------------------------------- Computing full set of 2 coset representatives for 2E(Q) in E(Q) (modulo torsion), and sorting into height order....done. Used descent via 2-isogeny with isogenous curve E' = [0,0,0,-2783099,-1781689378] Rank = 1 Rank of S^2(E) = 3 Rank of S^2(E') = 2 Rank of S^phi(E') = 2 Rank of S^phi'(E) = 1 Searching for points (bound = 8)...done: found points of rank 0 and regulator 1 Processing points found during 2-descent...done: 2-descent increases rank to 1, now regulator = 106.721376885791 Saturating (bound = 100)...done: points were already saturated. Transferring points from minimal curve [0,0,0,-253009,0] back to original curve [0,0,0,-4048144,0] Generator 1 is [3977231486582278508189714401665075654349312369331552520997014769654828224:39740870795202171331157247562019395524949267412337171460766430406997360160:1928317088832685492020566294646267423214258259206809092654393913813973]; height 106.721376885791 Regulator = 106.721376885791 The rank and full Mordell-Weil basis have been determined unconditionally. (1 seconds)}
get_systems('E2012.mwrank(options=\'-b 20 -x 12\')')
\newcommand{\Bold}[1]{\mathbf{#1}}\left[\hbox{mwrank}\right]
from sage.misc.citation import get_systems
E2012.analytic_rank()
\newcommand{\Bold}[1]{\mathbf{#1}}1
P=E2012([3977231486582278508189714401665075654349312369331552520997014769654828224,39740870795202171331157247562019395524949267412337171460766430406997360160,1928317088832685492020566294646267423214258259206809092654393913813973]); P
\newcommand{\Bold}[1]{\mathbf{#1}}\left(\frac{31953717079782403877426365136043401188458986438592}{15492409457317760025384676078081128557650708009} : \frac{39740870795202171331157247562019395524949267412337171460766430406997360160}{1928317088832685492020566294646267423214258259206809092654393913813973} : 1\right)
P[1]^2-P[0]^3+2012^2*P[0]
\newcommand{\Bold}[1]{\mathbf{#1}}0

The curve comes from "congruent number problem". 2012 is a congruent

number, and the right triangle associate with it is given by aa, bb and cc below.

a=P[1]/P[0]; a
\newcommand{\Bold}[1]{\mathbf{#1}}\frac{78366906299544891487468759852203246736490979835}{7842891235242432171391119745421505829682831394}
b=2*2012*P[0]/P[1]; b
\newcommand{\Bold}[1]{\mathbf{#1}}\frac{62743129881939457371128957963372046637462651152}{155799018488160818066538289964618780788252445}
c=(P[0]^2+2012^2)/P[1];c
\newcommand{\Bold}[1]{\mathbf{#1}}\frac{492238988669800304416700185089132231594105335620020162787295071274798563955460480753337934737}{1221914756560170125637172838524413935284120398357943486069854035440064998055224740843258330}
a^2+b^2-c^2
\newcommand{\Bold}[1]{\mathbf{#1}}0
a*b/2
\newcommand{\Bold}[1]{\mathbf{#1}}2012
a+.0, b+.0, c+.0
\newcommand{\Bold}[1]{\mathbf{#1}}\left(9.99209398026575, 402.718389953832, 402.842330880355\right)

Let draw the triangle!

from sage.plot.polygon import Polygon
P=polygon2d([[0,0], [a,0], [a,b]]); P

Please note that the xx and yy axises. The true form of this right triangle is...

P.set_aspect_ratio(1); P

S. Stein (Sage project leader) described the congruent number problem, Elliptic curves and Sage. See

http://modular.math.washington.edu/simuw06/

The author (I. K.) thanks Mr. S. Yokoyama (Kyushu) for bringing this documents to his attention.

Cremona's table

Install extra package:

install_package('database_cremona_ellcurve-20071019.p0')

CD=CremonaDatabase(); CD
\newcommand{\Bold}[1]{\mathbf{#1}}\hbox{Cremona's database of elliptic curves}
CD.random()
\newcommand{\Bold}[1]{\mathbf{#1}}y^2 = x^3 + x^2 + 208x - 2732

Elliptic Curves over real quadratic fields

Mr. S. Yokoyama (Kyushu) asked me how to find a point on a curve

y2=x3+1728εdy^2 = x^3 + 1728\varepsilon_d, where εd\varepsilon_d is the fundamental unit of a real quadratic Q(d)\mathbf{Q}(\sqrt{d}) for

some specific dd.

 

Q43.<a>=QuadraticField(43); Q43
\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Q}[\sqrt{43}]/(\sqrt{43}^{2} - 43)
eps = UnitGroup(Q43).fundamental_units()[0]; 1/eps
\newcommand{\Bold}[1]{\mathbf{#1}}-531 \sqrt{43} - 3482
%gp quadunit(4*43)
3482 + 531*w
E = EllipticCurve(Q43, [0, 1728*eps]); E
\newcommand{\Bold}[1]{\mathbf{#1}}y^2 = x^3 + \left(917568 \sqrt{43} - 6016896\right)

D. Simon's algebraic descent code (written in pari-gp) is included in Sage.

dscnt = E.simon_two_descent(verbose=1); dscnt
courbe elliptique : Y^2 = x^3 + Mod(917568*y - 6016896, y^2 - 43) points triviaux sur la courbe = [[1, 1, 0]] *** at top-level: ans=bnfellrank(K,[0,0,0, *** ^-------------------- *** in function bnfellrank: ...eqtheta,rnfeq,bbnf];rang= *** bnfell2descent_gen(b *** ^-------------------- *** in function bnfell2descent_gen: ...riv,r=nfsqrt(nf,norm(zc)) *** [1];if(DEBUGLEVEL_el *** ^-------------------- *** array index (1) out of allowed range [none].
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("ZHNjbnQgPSBFLnNpbW9uX3R3b19kZXNjZW50KHZlcmJvc2U9MSk7IGRzY250"),globals())+"\\n"); execfile(os.path.abspath("___code___.py"))' + '\n', '', 'single') File "", line 1, in <module> File "/tmp/tmpRMRIcu/___code___.py", line 3, in <module> exec compile(u'dscnt = E.simon_two_descent(verbose=_sage_const_1 ); dscnt' + '\n', '', 'single') File "", line 1, in <module> File "/usr/local/sage2/local/lib/python2.6/site-packages/sage/schemes/elliptic_curves/ell_number_field.py", line 277, in simon_two_descent maxprob=maxprob, limbigprime=limbigprime) File "/usr/local/sage2/local/lib/python2.6/site-packages/sage/schemes/elliptic_curves/gp_simon.py", line 114, in simon_two_descent ans[2] = [inv_transform(F(P)) for P in ans[2]] File "/usr/local/sage2/local/lib/python2.6/site-packages/sage/schemes/elliptic_curves/ell_generic.py", line 620, in __call__ return plane_curve.ProjectiveCurve_generic.__call__(self, *args, **kwds) File "/usr/local/sage2/local/lib/python2.6/site-packages/sage/schemes/generic/scheme.py", line 222, in __call__ return self.point(args) File "/usr/local/sage2/local/lib/python2.6/site-packages/sage/schemes/generic/scheme.py", line 256, in point return self._point_class(self, v, check=check) File "/usr/local/sage2/local/lib/python2.6/site-packages/sage/schemes/elliptic_curves/ell_point.py", line 303, in __init__ raise TypeError, "Coordinates %s do not define a point on %s"%(list(v),curve) TypeError: Coordinates [-377788/93025*a - 1952448/93025, -205379776/28372625*a - 1032512096/28372625, 1] do not define a point on Elliptic Curve defined by y^2 = x^3 + (917568*a-6016896) over Number Field in a with defining polynomial x^2 - 43
E(dscnt[2][0])
\newcommand{\Bold}[1]{\mathbf{#1}}\left(-\frac{377788}{93025} \sqrt{41} - \frac{1952448}{93025} : -\frac{205379776}{28372625} \sqrt{41} - \frac{1032512096}{28372625} : 1\right)
E.rank()
\newcommand{\Bold}[1]{\mathbf{#1}}2
E.gens()
\newcommand{\Bold}[1]{\mathbf{#1}}\left[\left(-\frac{377788}{93025} \sqrt{41} - \frac{1952448}{93025} : -\frac{205379776}{28372625} \sqrt{41} - \frac{1032512096}{28372625} : 1\right)\right]
E(Q41)
\newcommand{\Bold}[1]{\mathbf{#1}}\hbox{Abelian group of points on Elliptic Curve defined by y^2 = x^3 + (8640*a+55296) over Number Field in a with defining polynomial x^2 - 41}

Modular Forms

dimension_cusp_forms(Gamma0(11),2) # the dim of elliptic cusp forms of level 11, wt 2.
\newcommand{\Bold}[1]{\mathbf{#1}}1
dimension_cusp_forms(Gamma0(1), 12) # the dim of elliptic cusp forms of level 1, wt 12.
\newcommand{\Bold}[1]{\mathbf{#1}}1
S=CuspForms(Gamma0(11), 2); S
\newcommand{\Bold}[1]{\mathbf{#1}}\hbox{Cuspidal subspace of dimension 1 of Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(11) of weight 2 over Rational Field}
S.basis() # Ramanujan's tau.
\newcommand{\Bold}[1]{\mathbf{#1}}\left[q - 2q^{2} - q^{3} + 2q^{4} + q^{5} + O(q^{6})\right]

Sage has huge amount of functions related to elliptic curves, modular forms of one variables and modular abelian varieties.

For those who interested in these features, the author recommend to read the section of Sage tutorial

http://sagemath.org/doc/tutorial/tour_advanced.html#elliptic-curves and W. Stein's book "

Modular Forms, a Computational Approach (Graduate Studies in Mathematics)", AMS 2007.

Misc: LaTeX output, File I/O

Miscellaneous topics. The cell which begin with %latex is rendered by LaTeX.

One can store Sage objects into files and restore them.

%latex {\Large $\zeta(s) = \sum_{n=1}^{\infty}\frac{1}{n^s}$, $\Re(s)>1$.} % LaTeX formatting.
latex('QQ')
\newcommand{\Bold}[1]{\mathbf{#1}}\hbox{\hbox{QQ}}

Store the results of computation into a file.

S.dump(SAGE_TMP+'Level11wt2CuspForms')

Load stored computation and compare it with original one.

S == load(SAGE_TMP+'Level11wt2CuspForms')
\newcommand{\Bold}[1]{\mathbf{#1}}{\rm True}

Thats's all!

Thank you for your attention.

The list of Sage's extra-packages. These are not installed by default but can be installed by

install_package() command.

for d in optional_packages(): print d
['database_cremona_ellcurve-20071019.p0', 'database_gap-4.4.12.p0', 'database_jones_numfield-v4', 'database_odlyzko_zeta', 'gap_packages-4.4.12.p0'] ['ace-5.0.p0', 'biopython-1.55.p0', 'cbc-2.3.p2', 'cunningham_tables-1.0', 'database_kohel-20060803', 'database_sloane_oeis-2005-12', 'database_stein_watkins_mini.p0', 'database_symbolic_data-20070206', 'extra_docs-20070208', 'fricas-1.0.9', 'fricasaldor-1.0.9', 'gdbm-1.8.3', 'ginv-1.9-20080723', 'glpk-4.42.p0', 'gmpy-1.0.1', 'gnuplotpy-1.8', 'graphviz-2.16.1.p0', 'guppy-0.1.8', 'java3d-20070901', 'jsmath_image_fonts-1.4.p3', 'kash3-2008-07-31', 'knoboo-20080411', 'libcocoa-0.9930', 'libogg-1.1.4', 'libtheora-1.1.1', 'lie-2.2.2.p3', 'lrs-4.2b.p1', 'mpc-0.8.3-dev-svn793', 'mpi4py-1.1.0', 'nauty-24', 'nzmath-1.0.0', 'openmpi-1.1.4', 'openssl-1.0.0.p0', 'p_group_cohomology-2.0', 'phc-2.3.53.p0', 'pycryptoplus-20100809-git', 'pyopenssl-0.8', 'pyx-0.10', 'qhull-2010.1', 'sage-mode-0.6', 'trac-0.11.5.p0', 'valgrind-3.3.1']