SAGE is not at version 1.0 yet, and should still be considered a work in active progress. The main reason you should try to use SAGE today is so that you can give feedback and contribute to its development, since SAGE will fill a community need. Here is a selection of what is available now.
sage: R = PolynomialRing(Q) sage: x = R.0 sage: R = PolynomialRing(Q, "x") sage: x = R.0 # same as R.gen() or R.gen(0) sage: x in R True sage: f = 2*x^7 + 3*x^2 - 15/19 sage: f^2 4*x^14 + 12*x^9 - 60/19*x^7 + 9*x^4 - 90/19*x^2 + 225/361 sage: g = (x^5+10*x+2)*R.cyclotomic_polynomial(7)*x^5 sage: g x^16 + x^15 + x^14 + x^13 + 11*x^12 + 13*x^11 + 13*x^10 + 12*x^9 + 12*x^8 + 12*x^7 + 12*x^6 + 2*x^5 sage: factor(g) [(x, 5), (x^5 + 10*x + 2, 1), (x^6 + x^5 + x^4 + x^3 + x^2 + x + 1, 1)]
sage: S = PolynomialRing(Q, "y") sage: y = S.0 sage: x == y False sage: R == S False sage: R(y) x sage: R(y^2 - 17) x^2 - 17
sage: T = PolynomialRing(Q, "x") sage: R == T True sage: R.0 == T.0 True
SAGE currently has no support for power series, though such support will be added very soon.
Here is ane example of computing with an elliptic curve.
sage: E = EllipticCurve([0,0,1,-1,0]) sage: E y^2 + y = x^3 - x sage: P = E([0,0]) sage: 10*P (161/16, -2065/64) sage: 20*P (683916417/264517696, -18784454671297/4302115807744) sage: E.conductor() 37
We can compute the coefficients of the -series or modular form
attached to the elliptic curve. This computation uses the PARI
C-library, which is the fastest implementation I know:
sage: E = EllipticCurve([0,0,1,-1,0]) sage: print E.anlist(30) [0, 1, -2, -3, 2, -2, 6, -1, 0, 6, 4, -5, -6, -2, 2, 6, -4, 0, -12, 0, -4, 3, 10, 2, 0, -1, 4, -9, -2, 6, -12] sage: time v = E.anlist(10000) # on Thinkpad T42p with 1.8Ghz Pentium-M Time: 0.05 seconds sage: time v = E.anlist(100000) Time: 0.64 seconds
Elliptic curves can be constructed using their Cremona labels. This preloads the elliptic curve with information about its rank, conductor, etc.
sage: E = EllipticCurve("37B2") sage: E Elliptic Curve defined by y^2 + y = x^3 + x^2 - 1873*x - 31833 over Rational Field sage: E = EllipticCurve("389A") sage: E Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field sage: E.rank() 2 sage: E = EllipticCurve("5077A") sage: E.rank() 3
We can also access the compressed database directly.
sage: import sage.tables.elliptic_curves sage: db = sage.tables.elliptic_curves.Database() sage: db. db._db db.changed db.dump_as_dict db.optimal_curves db._dbname db.clone db.dump_as_dict_intervals db.pack db._root db.commit db.has_key db.read_only db._storage db.conn db.import_allcurves db.rebuild db._thresh db.curve db.import_degphi db.restore_from_dict db.abort db.curves db.keys db.restore_from_dict_all db.as_dict db.delete_all db.name db.root sage: db.curves(37) [37A1: invs=[0, 0, 1, -1, 0], rank=1, tors=1, cp={37: 1}, 37B1: invs=[0, 1, 1, -23, -50], rank=0, tors=3, cp={37: 3}, 37B2: invs=[0, 1, 1, -1873, -31833], rank=0, tors=1, cp={37: 1}, 37B3: invs=[0, 1, 1, -3, 1], rank=0, tors=3, cp={37: 1}] sage: db.optimal_curves(37) [37A1: invs=[0, 0, 1, -1, 0], rank=1, tors=1, cp={37: 1}, 37B1: invs=[0, 1, 1, -23, -50], rank=0, tors=3, cp={37: 3}] sage: E = db.curves(37)[0] sage: E. E.a_invariants E.iso_class E.rank E.tamagawa_product E.traces E.conductor E.number E.tamagawa E.torsion
Use help(dims) to see what functions are available for computing dimensions of spaces of modular forms.
sage: help(dims) Help on module sage.modular.dims in sage.modular: ... FUNCTIONS ... dimension_cusp_forms(group, k=2) The dimension of the space of cusp forms for the congruence subgroup group. ...
sage: dims.dimension_cusp_forms(Gamma0(11),2) 1 sage: dims.dimension_cusp_forms(Gamma0(1),12) 1 sage: dims.dimension_cusp_forms(Gamma1(389),2) 6112
Next we illustrate computation of Hecke operators on a space of modular
symbols of level and weight
.
sage: M = ModularSymbols(1,12) sage: M.basis() [(1 0 0), (0 1 0), (0 0 1)] sage: t2 = M.T(2) sage: t2 Linear function defined by matrix: [ -24 0 0] [ 0 -24 0] [4860 0 2049] sage: f = t2.charpoly(); f x^3 - 2001*x^2 - 97776*x - 1180224 sage: factor(f) [(x - 2049, 1), (x + 24, 2)] sage: M.T(11).charpoly().factor() [(x - 285311670612, 1), (x - 534612, 2)]
sage: MS(11,2) Full Modular Symbols space for Gamma_0(11) of weight 2 and dimension 3 over Rational Field sage: MS(Gamma1(11),2) Full Modular Symbols space for Gamma_1(11) of weight 2 and dimension 11 over Rational Field sage: M = MS(Gamma1(11),2) sage: M.T(2).charpoly() x^11 - 8*x^10 + 20*x^9 + 10*x^8 - 145*x^7 + 229*x^6 + 58*x^5 - 360*x^4 + 70*x^3 - 515*x^2 + 1804*x - 1452 sage: M.T(2).charpoly().factor() [(x - 3, 1), (x + 2, 2), (x^4 - 7*x^3 + 19*x^2 - 23*x + 11, 1), (x^4 - 2*x^3 + 4*x^2 + 2*x + 11, 1)]
sage: G = DirichletGroup(13) sage: e = G.0^2 sage: M = ModularSymbols(e,2) sage: M Full Modular Symbols space of level 13, weight 2, character [zeta_12^2] and dimension 4 over Cyclotomic Field of order 12 and degree 4 sage: M.T(2).charpoly() x^4 + (-zeta_12^2 - 1)*x^3 + (-8*zeta_12^2)*x^2 + (10*zeta_12^2 - 5)*x + 21*zeta_12^2 - 21 sage: M.T(2).charpoly().factor() [(x + -2*zeta_12^2 - 1, 1), (x + -zeta_12^2 - 2, 1), (x + zeta_12^2 + 1, 2)]
Decomposition and computation of -expansions is currently not
finished, but a very high priority. Also, the machinery for these
computations has not been sufficiently optimized, and there are surely
some places where computations take much longer than necessary.
Part of SAGE is a Python-based extension class that uses the PARI C library to provide functionality similar to that provided by the GP PARI interpreter, except with more robust memory management, garbage collection, automatic increasing of stack size and prime table, etc.; it is slower but more robust than GP. This will be the foundation for the elementary and algebraic number theory functionality of SAGE. In addition, this Python-based extension class will be released separately from SAGE and not depend on SAGE. See the file sage/pari/py_pari.pyx for more details.
First we create a PARI list from a Python list.
sage: v = pari([1,2,3,4,5]) sage: v [1, 2, 3, 4, 5]
sage: type(v) <type 'py_pari.gen'> sage: v.type() 't_VEC'
sage: v[0] 1 sage: v[4] 5
sage: v[:3] [1, 2, 3] sage: v[2:4] [3, 4]
In PARI, to create an elliptic curve we enter ellinit([1,2,3,4,5]). SAGE is similar, except that ellinit is a method that can be called on any PARI object, e.g., our t_VEC v.
sage: e = v.ellinit() sage: e.type() 't_VEC'
sage: e.elltors() [1, [], []] sage: e.ellglobalred() [10351, [1, -1, 0, -1], 1] sage: f = e.ellchangecurve([1,-1,0,-1]) sage: f[:5] [1, -1, 0, 4, 3]
The full functionality of GP/PARI will (eventually) be available in this way, this is not meant to be the way SAGE is used. Instead, when people are implementing SAGE and discover that something has already been implemented in PARI, they can use it without any robustness penalties. For example, computing the conductor of an elliptic curve in SAGE is better accomplished by typing the following which is implemented by creating the PARI elliptic curve and calling ellglobalred:
sage: E = EllipticCurve([1,2,3,4,5]) sage: E Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field sage: E.conductor() 10351
It is taking some time to implement py_pari since the author must understand almost every single PARI C-library function, write a wrapper around it, and provide example usage. (Volunteers needed!) Also, there are some subtle issues that arise because PARI and Python both fight over trapping signals.
Create a space of matrices.
sage: M = MatrixSpace(Q,3) sage: M Full MatrixSpace of 3 by 3 dense matrices over Rational Field
sage: B = M.basis() sage: len(B) 9 sage: B[1] [0 1 0] [0 0 0] [0 0 0]
sage: A = M(range(9)); A [0 1 2] [3 4 5] [6 7 8]
sage: A.reduced_row_echelon_form() [ 1 0 -1] [ 0 1 2] [ 0 0 0] sage: A^20 [ 2466392619654627540480 3181394780427730516992 3896396941200833493504] ... sage: A.kernel() Vector space of degree 3, dimension 1 over Rational Field Basis matrix: [ 1 -2 1] sage: kernel(A) # example of functional notation
SAGE has support for optimized sparse linear algebra over
and
.
sage: M = MatrixSpace(Q, 100, sparse=True) sage: A = M.random_element(prob = 0.05) sage: len(A.nonzero_positions()) 536 sage: time E = A.reduced_row_echelon_form() Time: 0.02 seconds
sage: M = MatrixSpace(Q, 100, 150, sparse=True) sage: A = M.random_element(prob = 0.05) sage: len(A.nonzero_positions()) 695 sage: time E = A.reduced_row_echelon_form() Time: 1.81 seconds sage: len(E.nonzero_positions()) 4357
was@form:~$ sage ... sage: db.save? ... sage: f = x^10 + 3*x + 1 sage: db.save(f, "f") was@form:~$ ls -l f -rw-r--r-- 1 was was 585 Apr 10 15:30 f was@form:~$ sage ... sage: g = db.load("f") sage: g x^10 + 3*x + 1
One goal for SAGE V1.0 is that every object can be saved to a file and
loaded from a file. This is currently not the case, because some
types that are implemented as C extensions require special support for
saving and loading, and this hasn't been completed yet (as of April
2005). For example, matrices over can be saved but not
over
:
sage: M = MatrixSpace(Q, 2) sage: A = M([1,2,3,4]) sage: db.save(A, "A") ... TypeError: can't pickle Matrix_rational objects sage: M = MatrixSpace(Z, 2) sage: A = M([1,2,3,4]) sage: db.save(A, "A") sage: db.load("A") [1 2] [3 4]
There is also support for creating bzip2 compressed object-oriented databases for SAGE. See the source code in sage/tables/ for some examples (further documentation is needed here).
See About this document... for information on suggesting changes.