Grand Tour - part 1 system:sage

The Sage Library -- a Grand Tour -- Part 1

June 2009

William Stein

{{{id=242| def ls(module): #auto os.system('ls $SAGE_ROOT/devel/sage/sage/%s'%module) ls('') /// __init__.py coding geometry logic parallel stats __init__.pyc combinat graphs matrix plot structure algebras crypto groups media probability symbolic all.py databases gsl misc quadratic_forms tests all_cmdline.py ext homology modular rings version.py all_notebook.py finance interfaces modules schemes calculus functions lfunctions monoids server categories games libs numerical sets }}} {{{id=4| /// }}}

The Sage library consists of well over 350,000 lines of new code written by Sage developers.  It provides a unified interface to most existing mathematical software and fills in the many gaps in functionality of open source mathematical software.

 

Major Documentation Milestone: As of Sage-4.0.1, 77.3% of functions in the library have docstrings that include doctests illustrating their functionality.  This includes private "single underscore" methods, and represents over 94,752 lines of input, which gets regularly tested.

 

The Sage library is divided up into the following 39 major modules, and in this talk we will give a tour of the following subset of them:

Part 1

Categories

A category is a collection of objects and morphisms, which satisfy certain axioms.  They are a useful organizing principle in Sage.

The Sage categories package defines many categories: Elements, Sequences, Objects, Sets, GSets, PointedSets, SetsWithPartialMaps, SimplicialComplexes, Semigroups, Monoids, Groupoid, Groups, AbelianSemigroups, AbelianMonoids, AbelianGroups, Rings, CommutativeRings, Fields, FiniteFields, NumberFields, Algebras, CommutativeAlgebras, MonoidAlgebras, GroupAlgebras, MatrixAlgebras, RingModules, Modules, FreeModules, VectorSpaces, HeckeModules, RingIdeals, Ideals, CommutativeRingIdeals, AlgebraModules, AlgebraIdeals, CommutativeAlgebraIdeals, ChainComplexes, Schemes, ModularAbelianVarieties

The categories code was original written by David Kohel and William Stein.  Robert Bradshaw and others actually made some limited use of it in improving the Sage coercion model. 

PROJECT: An exciting recent development is that French mathematician Nicolas Thiery (director of the Sage-combinat project) has put a massive amount of work into greatly improving and using the categories code to usefully organize many generic algorithms.  His code will soon be included in Sage.

{{{id=245| ls('categories') /// __init__.py category_types.py map.pxd action.c functor.c map.pyx action.pxd functor.pxd morphism.c action.pyx functor.pyx morphism.pxd all.py homset.py morphism.pyx category.py map.c pushout.py }}} {{{id=101| C = VectorSpaces(RR); C /// Category of vector spaces over Real Field with 53 bits of precision }}} {{{id=99| C(QQ^3) /// Vector space of dimension 3 over Real Field with 53 bits of precision }}} {{{id=98| (QQ^3).category() /// Category of vector spaces over Rational Field }}} {{{id=102| Integers(7).category() /// Category of rings }}} {{{id=103| Primes().category() /// Category of sets }}} {{{id=384| sage: Hom(ZZ^3, ZZ^5) /// Set of Morphisms from Ambient free module of rank 3 over the principal ideal domain Integer Ring to Ambient free module of rank 5 over the principal ideal domain Integer Ring in Category of free modules over Integer Ring }}} {{{id=13| /// }}}

Algebras

This module contains code mainly for noncommutative algebras, include free algebras, quotients of free algebras by relations, group algebras, quaternion algebras, and the Steenrod algebra.

The free algebras functionality was implemented by David Kohel in 2005, and has been hardly touched since.  It could use a major overhaul.

David Loeffler recently wrote the group algebras functionality, which allows one to compute in a natural ring associated to a group.

Jon Bober, William Stein (me), and a few other people wrote the quaternion algebras functionality from scratch in February and March of 2009.  It's highly optimized code, and there are some natural ways to extend it to more general cases.

The Steenrod algebra code is a relatively recent major new package by John Palmierri that provides powerful tools for the study of algebraic topology.

PROJECT: It would be good if the algebras directory had much better or comprehensive support for a wider range of noncommutative algebras. For example, Singular -- a component of Sage -- has powerful specialized code ("plural") for working with certain classes of noncommutative rings.  This should all be made nicely available in Sage.

{{{id=243| ls('algebras') /// __init__.py quatalg algebra.py quaternion_algebra.py algebra_element.py quaternion_algebra_element.py all.py steenrod_algebra.py free_algebra.py steenrod_algebra_bases.py free_algebra_element.py steenrod_algebra_element.py free_algebra_quotient.py steenrod_milnor_multiplication.py free_algebra_quotient_element.py steenrod_milnor_multiplication_odd.py group_algebra.py }}} {{{id=89| K. = FreeAlgebra(QQ,3); K /// Free Algebra on 3 generators (x, y, z) over Rational Field }}} {{{id=90| z^2*x*y*x*z + (2/3)*z*y*y /// 2/3*z*y^2 + z^2*x*y*x*z }}} {{{id=94| /// }}}

A group ring

{{{id=88| S = SymmetricGroup(3); R=GroupAlgebra(S, QQ) /// }}} {{{id=168| R /// Group algebra of group "SymmetricGroup(3)" over base ring Rational Field }}} {{{id=95| S.gens() /// [(1,2,3), (1,2)] }}} {{{id=169| a = R(S.0) + (2/3)*R(S.1); a /// 2/3*(1,2) + (1,2,3) }}} {{{id=171| a*a /// 4/9*() + 2/3*(2,3) + (1,3,2) + 2/3*(1,3) }}} {{{id=170| /// }}}

A quaternion algebra

{{{id=86| A. = QuaternionAlgebra(93938,39292902020); A /// Quaternion Algebra (93938, 39292902020) with base ring Rational Field }}} {{{id=165| i^2 /// 93938 }}} {{{id=166| j^2 /// 39292902020 }}} {{{id=167| (1+i+j)*(j-2*i) /// 39292714144 - 2*i + j + 3*k }}} {{{id=106| A.ramified_primes() /// [5, 13, 3613, 1964645101] }}} {{{id=107| i*j /// k }}} {{{id=105| a = 1+9393*i+392903*j-393923298304823904*k a*a /// -572768004828494291666114999674938501059466982679817 + 18786*i + 785806*j - 787846596609647808*k }}} {{{id=91| timeit('a*a') /// 625 loops, best of 3: 3.41 µs per loop }}} {{{id=92| /// }}} {{{id=9| /// }}}

Monoids

A monoid is just like a group, but without the axiom that every element has an inverse.  Sage has code that David Kohel wrote several years ago for working with monoids.

PROJECT: This code has not been touched in years, so it would likely be easy to improve, optimize, and extend it.

{{{id=273| ls('monoids') /// __init__.py free_monoid_element.py all.py monoid.py free_abelian_monoid.py string_monoid.py free_abelian_monoid_element.py string_monoid_element.py free_monoid.py string_ops.py }}} {{{id=342| S = HexadecimalStrings(); S /// Free hexadecimal string monoid }}} {{{id=343| x = S.gen(0); y = S.gen(10); z = S.gen(15) x*y^3*z /// 0aaaf }}} {{{id=388| /// }}} {{{id=59| /// }}}

Rings

 

The huge rings module implements much of the underlying arithmetic in Sage.  It is most complicated and mature module in Sage.

Algebraic rings:   All of the standard rings, such as $\mathbf{Z}$, $\mathbf{Q}$, finite fields $\mathbf{F}_{p^n}$, and polynomial and power series rings over any other ring in Sage. Substantial code for number fields, and threes models of $p$-adic numbers: capped relative, capped absolute, fixed modulus.  The algebraic closure of $\mathbf{Q}$ and its maximal totally real subfield are also implemented, using intervals.

Numerical:  Real and complex numbers of any fixed precision.  Double precisions reals and complex (for speed).   Rings that model $\mathbf{R}$ and $\mathbf{C}$ with intervals (interval arithmetic).

At any given time, some parts of the code are very mature, and others are being actively improved.  

PROJECT: The $p$-adics and numbers fields are currently actively being improved by David Roe, John Cremona, Kiran Kedlaya, and others.  

PROJECT: Function fields are not sufficiently well supported yet.

PROJECT: Substantial work needs to be put into optimizing arithmetic with relative numbers fields.  (Nick Alexander has worked some on this recently).

PROJECT: Groebner basis functionality is in the rings/polynomial directory, and currently mainly uses Singular.   There is a huge need in Sage for an optimized F4 implementation, and we hope that this will eventually get developed by somebody (the EU has just funded Singular, which is part of Sage, to do this).

{{{id=282| ls('rings') /// __init__.py integral_domain_element.py all.py laurent_series_ring.py arith.py laurent_series_ring_element.c bernmm laurent_series_ring_element.pxd bernmm.cpp laurent_series_ring_element.pyx bernmm.pyx memory.c bernoulli_mod_p.cpp memory.pyx bernoulli_mod_p.pyx misc.py big_oh.py monomials.py coerce_python.py morphism.c commutative_algebra.py morphism.pxd commutative_algebra_element.py morphism.pyx commutative_ring.py mpfi.pxi commutative_ring_element.py noetherian_ring.py complex_double.c notes complex_double.h number_field complex_double.pxd padics complex_double.pyx pari_ring.py complex_double_api.h polynomial complex_field.py power_series_mpoly.c complex_interval.c power_series_mpoly.pxd complex_interval.pxd power_series_mpoly.pyx complex_interval.pyx power_series_poly.c complex_interval_field.py power_series_poly.pxd complex_number.c power_series_poly.pyx complex_number.pxd power_series_ring.py complex_number.pyx power_series_ring_element.c contfrac.py power_series_ring_element.pxd dedekind_domain.py power_series_ring_element.pyx dedekind_domain_element.py principal_ideal_domain.py euclidean_domain.py principal_ideal_domain_element.py euclidean_domain_element.py qqbar.py fast_arith.c quotient_ring.py fast_arith.pxd quotient_ring_element.py fast_arith.pyx rational.c field.py rational.h field_element.py rational.pxd finite_field.py rational.pxi finite_field_element.py rational.pyx finite_field_ext_pari.py rational_field.py finite_field_givaro.cpp real_double.c finite_field_givaro.pxd real_double.pxd finite_field_givaro.pyx real_double.pxi finite_field_morphism.py real_double.pyx finite_field_ntl_gf2e.cpp real_interval_field.py finite_field_ntl_gf2e.pxd real_lazy.c finite_field_ntl_gf2e.pyx real_lazy.pxd finite_field_prime_modn.py real_lazy.pyx fraction_field.py real_mpfi.c fraction_field_element.c real_mpfi.pxd fraction_field_element.pyx real_mpfi.pyx homset.py real_mpfr.c ideal.py real_mpfr.pxd ideal_monoid.py real_mpfr.pyx infinity.py real_rqdf.cpp integer.c real_rqdf.pxd integer.h real_rqdf.pyx integer.pxd residue_field.c integer.pyx residue_field.pxd integer_mod.c residue_field.pyx integer_mod.pxd ring.c integer_mod.pyx ring.pxd integer_mod_ring.py ring.pyx integer_ring.c ring_element.py integer_ring.pxd rqdf_fix.h integer_ring.pyx solaris_fix.h integer_ring_python.py stdint.h integral_domain.py tests.py }}} {{{id=339| ls('rings/number_field') /// __init__.py number_field_ideal.py all.py number_field_ideal_rel.py class_group.py number_field_morphisms.c galois_group.py number_field_morphisms.pyx maps.py number_field_rel.py morphism.py order.py number_field.py small_primes_of_degree_one.py number_field_base.c totallyreal.c number_field_base.pxd totallyreal.pyx number_field_base.pyx totallyreal_data.c number_field_element.cpp totallyreal_data.pxd number_field_element.pxd totallyreal_data.pyx number_field_element.pyx totallyreal_dsage.py number_field_element_quadratic.cpp totallyreal_phc.py number_field_element_quadratic.pxd totallyreal_rel.py number_field_element_quadratic.pyx unit_group.py }}} {{{id=340| ls('rings/polynomial') /// __init__.py polynomial_element.pyx all.py polynomial_element_generic.py complex_roots.py polynomial_fateman.py convolution.py polynomial_gf2x.cpp cyclotomic.c polynomial_gf2x.pxd cyclotomic.pyx polynomial_gf2x.pyx groebner_fan.py polynomial_integer_dense_flint.cpp infinite_polynomial_element.py polynomial_integer_dense_flint.pxd infinite_polynomial_ring.py polynomial_integer_dense_flint.pyx laurent_polynomial.c polynomial_integer_dense_ntl.cpp laurent_polynomial.pxd polynomial_integer_dense_ntl.pxd laurent_polynomial.pyx polynomial_integer_dense_ntl.pyx laurent_polynomial_ring.py polynomial_modn_dense_ntl.cpp multi_polynomial.c polynomial_modn_dense_ntl.pxd multi_polynomial.pxd polynomial_modn_dense_ntl.pyx multi_polynomial.pyx polynomial_quotient_ring.py multi_polynomial_element.py polynomial_quotient_ring_element.py multi_polynomial_ideal.py polynomial_real_mpfr_dense.c multi_polynomial_ideal_libsingular.cpp polynomial_real_mpfr_dense.pyx multi_polynomial_ideal_libsingular.pyx polynomial_ring.py multi_polynomial_libsingular.cpp polynomial_ring_constructor.py multi_polynomial_libsingular.pxd polynomial_singular_interface.py multi_polynomial_libsingular.pyx polynomial_template.pxi multi_polynomial_ring.py polynomial_template_header.pxi multi_polynomial_ring_generic.c polynomial_zmod_flint.c multi_polynomial_ring_generic.pxd polynomial_zmod_flint.pxd multi_polynomial_ring_generic.pyx polynomial_zmod_flint.pyx padics real_roots.c pbori.cpp real_roots.pxd pbori.pxd real_roots.pyx pbori.pyx symmetric_ideal.py polydict.c symmetric_reduction.c polydict.pxd symmetric_reduction.pxd polydict.pyx symmetric_reduction.pyx polynomial_compiled.c term_order.py polynomial_compiled.pxd toy_buchberger.py polynomial_compiled.pyx toy_d_basis.py polynomial_element.c toy_variety.py polynomial_element.pxd }}} {{{id=337| parent(2/3) /// Rational Field }}} {{{id=338| var('x') K. = NumberField([x^3+x+1, x^4+13*x^2-2]); K /// Number Field in a with defining polynomial x^3 + x + 1 over its base field }}} {{{id=336| RDF /// Real Double Field }}} {{{id=335| @interact def _(number=(2..20)): html('

%s Random Rings

'%number) i=0 for R in sage.rings.tests.random_rings(1): print R #show(R) i += 1 if i > number: break ///
number 
}}}

Working in $\overline{\mathbf{Q}}$.

{{{id=381| R. = QQbar[]; R /// Univariate Polynomial Ring in X over Algebraic Field }}} {{{id=389| f = X^3 + 2*X - 17; r = f.roots(); r /// [(2.312973501144772?, 1), (-1.156486750572386? - 2.452016478890065?*I, 1), (-1.156486750572386? + 2.452016478890065?*I, 1)] }}} {{{id=390| g = X^2 + 13; s = g.roots(); s /// [(-3.605551275463990?*I, 1), (3.605551275463990?*I, 1)] }}} {{{id=391| t = r[0][0] + s[0][0]; t /// 2.312973501144772? - 3.605551275463990?*I }}} {{{id=392| t.minpoly() /// x^6 + 43*x^4 - 34*x^3 + 511*x^2 + 1258*x + 1862 }}} {{{id=395| /// }}} {{{id=71| /// }}}

Structure

The structure module

  • defines the SageObject base class for most objects in Sage
  • provides the base classes for all elements and parent structures
  • implements much of the coercion model
  • formal sums, sequences, and factorizations
  • the proof object, which allows you to determine whether or not certain classes of algorithms are only required to succeed with high probability or can assume conjectures (such as GRH),
  • .. and much more.

After having undergone at least 3 major and painful revisions, the structure module is fairly mature at this point.  It will gradually improve as the coercion model in Sage is slightly tweaked, as categories are improved, etc.

{{{id=297| ls('structure') /// __init__.py generators.pyx all.py gens_py.py category_object.c mutability.c category_object.pxd mutability.pxd category_object.pyx mutability.pyx coerce.c mutability_py.py coerce.pxd nonexact.py coerce.pxi parent.c coerce.pyx parent.pxd coerce_actions.c parent.pyx coerce_actions.pxd parent_base.c coerce_actions.pyx parent_base.pxd coerce_dict.c parent_base.pyx coerce_dict.pxd parent_gens.c coerce_dict.pyx parent_gens.pxd coerce_maps.c parent_gens.pyx coerce_maps.pxd parent_old.c coerce_maps.pyx parent_old.pxd element.c parent_old.pyx element.pxd proof element.pyx sage_object.c element_py.py sage_object.pxd element_verify.py sage_object.pyx factorization.py sequence.py factory.c test.sobj factory.pyx unique_representation.py formal_sum.py wrapper_parent.c generators.c wrapper_parent.pxd generators.pxd wrapper_parent.pyx }}} {{{id=191| sage.structure.element.Element /// }}} {{{id=193| sage.structure.parent.Parent /// }}} {{{id=192| Sequence([2/3,3,8]).universe() /// Rational Field }}} {{{id=194| FormalSum([(3, Mod(5,3)), (-2, 'hello')]) /// -2*hello + 3*2 }}} {{{id=196| proof.all(False) proof.all() /// {'polynomial': False, 'other': False, 'elliptic_curve': False, 'number_field': False, 'linear_algebra': False, 'arithmetic': False} }}} {{{id=197| proof.all(True); proof.all() /// {'polynomial': True, 'other': True, 'elliptic_curve': True, 'number_field': True, 'linear_algebra': True, 'arithmetic': True} }}}

A coercion example:

Notice that the sum below is in the parent of neither the left or right hand ring.  These natural nontrivial coercions are done systematically throughout Sage.  Getting this right was very hard work of Robert Bradshaw, David Roe, Craig Citro, etc.

{{{id=195| R. = ZZ[] R /// Univariate Polynomial Ring in x over Integer Ring }}} {{{id=314| 1/2 + (x+4) /// x + 9/2 }}} {{{id=398| parent(1/2), parent(x+4) /// (Rational Field, Univariate Polynomial Ring in x over Integer Ring) }}} {{{id=400| parent((1/2) + (x+4)) /// Univariate Polynomial Ring in x over Rational Field }}} {{{id=403| sage.structure.element.get_coercion_model().explain(1/2, x+4) /// Action discovered. Left scalar multiplication by Rational Field on Univariate Polynomial Ring in x over Integer Ring Result lives in Univariate Polynomial Ring in x over Rational Field Univariate Polynomial Ring in x over Rational Field }}} {{{id=313| /// }}}

Surprisingly, even Magma's coercion model is way behind Sage's:

{{{id=396| %magma R := PolynomialRing(IntegerRing()); 1/2 + (x+4) /// Traceback (most recent call last): File "", line 1, in File "/Users/wstein/.sage/sage_notebook/worksheets/admin/175/code/99.py", line 7, in 1/2 + (x+4)''', '/Users/wstein/.sage/sage_notebook/worksheets/admin/175/cells/396') File "/Users/wstein/s/local/lib/python2.5/site-packages/sage/server/support.py", line 353, in syseval return system.eval(cmd, sage_globals, locals = sage_globals) File "/Users/wstein/s/local/lib/python2.5/site-packages/sage/interfaces/magma.py", line 471, in eval raise RuntimeError, "Error evaluating Magma code.\nIN:%s\nOUT:%s"%(x, ans) RuntimeError: Error evaluating Magma code. IN:R := PolynomialRing(IntegerRing()); 1/2 + (x+4); OUT: >> 1/2 + (x+4); ^ Runtime error in '+': Bad argument types Argument types given: FldRatElt, RngUPolElt[RngInt] }}} {{{id=402| /// }}} {{{id=81| /// }}}

Sets

The sets module implements basic notions of sets of Python objects, and operations on them.  It's similar to what's in the standard Python library (the set class) but with more mathematical semantics, and support for infinite sets.

Exampleprimes.py defines the set of prime numbers, as a sort of example of how to define an infinite set.

PROJECT: Add more examples of interesting sets to this module.

{{{id=294| ls('sets') /// __init__.py all.py family.py primes.py set.py }}} {{{id=341| %hide def f(s, braces=True): t = ', '.join(sorted(list(s))) if braces: return '{' + t + '}' return t def g(s): return set(str(s).replace(',',' ').split()) @interact def _(X='1,2,3,a', Y='2,a,3,4,apple', Z='a,b,10,apple'): S = [g(X), g(Y), g(Z)] X,Y,Z = S XY = X.intersection(Y) XZ = X.intersection(Z) YZ = Y.intersection(Z) XYZ = XY.intersection(Z) html('
') html("$X \cap Y$ = %s"%f(XY)) html("$X \cap Z$ = %s"%f(XZ)) html("$Y \cap Z$ = %s"%f(YZ)) html("$X \cap Y \cap Z$ = %s"%f(XYZ)) html('
') centers = [(cos(n*2*pi/3), sin(n*2*pi/3)) for n in [0,1,2]] scale = 1.7 clr = ['yellow', 'blue', 'green'] G = Graphics() for i in range(len(S)): G += circle(centers[i], scale, rgbcolor=clr[i], fill=True, alpha=0.3) for i in range(len(S)): G += circle(centers[i], scale, rgbcolor='black') # Plot what is in one but neither other for i in range(len(S)): Z = set(S[i]) for j in range(1,len(S)): Z = Z.difference(S[(i+j)%3]) G += text(f(Z,braces=False), (1.5*centers[i][0],1.7*centers[i][1]), rgbcolor='black') # Plot pairs of intersections for i in range(len(S)): Z = set(S[i]).intersection(S[(i+1)%3]).difference(set(XYZ)) C = (1.3*cos(i*2*pi/3 + pi/3), 1.3*sin(i*2*pi/3 + pi/3)) G += text(f(Z,braces=False), C, rgbcolor='black') # Plot intersection of all three G += text(f(XYZ,braces=False), (0,0), rgbcolor='black') # Show it G.show(aspect_ratio=1, axes=False) ///
}}} {{{id=179| X = Set([1,2,5,'orange']); X /// {'orange', 1, 2, 5} }}} {{{id=178| Y = Set([2, 'apple']); Y /// {2, 'apple'} }}} {{{id=177| X.union(Y) /// {'orange', 1, 2, 5, 'apple'} }}} {{{id=181| X.intersection(Y) /// {2} }}} {{{id=182| set(X) /// set(['orange', 1, 2, 5]) }}} {{{id=180| Primes() /// Set of all prime numbers: 2, 3, 5, 7, ... }}}

This seems dumb, since clearly the result should just be a finite set with all elements enumerated.

{{{id=176| Z = X.intersection(Primes()); Z /// Set-theoretic intersection of {'orange', 1, 2, 5} and Set of all prime numbers: 2, 3, 5, 7, ... }}} {{{id=183| 2 in Z /// True }}} {{{id=184| 3 in Z /// False }}} {{{id=185| /// }}} {{{id=77| /// }}}

Combinat

The combinat directory is well over 50,000 lines of code that implements a wide range of algebraic combinatorics functionality in Sage.  It is under very active development.

  • Started in 2007, when Mike Hansen  (then an undergrad) decided to single-handedly port as much as possible of the MuPAD-combinat project (a major effort of nearly a dozen mathematicians) over to Sage.  He got about halfway through.
  • In 2008, the MuPAD combinat group decided to switch to Sage... just in time as it turns out, right before MuPAD was bought out by MATLAB.
  • They have been working on porting all of MuPAD-combinat to Sage during the last year, and greatly cleaning up and improved much of the design and code.   (Doing things right.)
  • Major new functionality: ode for combinatorics of words, representation theory of Lie groups, etc.

PROJECT: Completely finish the port of MuPAD-combinat.  

PROJECT: Dan Bump has been adding substantial new functionality for root systems.

{{{id=247| ls('combinat') /// __init__.py partition_algebra.py all.py partitions.cpp alternating_sign_matrix.py partitions.pyx backtrack.py partitions_c.cc cartesian_product.py partitions_c.h choose_nk.py permutation.py combinat.py permutation_nk.py combination.py posets combinatorial_algebra.py q_analogues.py composition.py ranker.py composition_signed.py restricted_growth.py crystals ribbon.py designs ribbon_tableau.py dlx.py root_system dyck_word.py schubert_polynomial.py expnums.c set_partition.py expnums.pyx set_partition_ordered.py family.py sf finite_class.py skew_partition.py free_module.py skew_tableau.py generator.py sloane_functions.py graph_path.py species integer_list.py split_nk.py integer_vector.py subset.py integer_vector_weighted.py subword.py lyndon_word.py symmetric_group_algebra.py matrices tableau.py misc.py tools.py multichoose_nk.py tuple.py necklace.py words output.py yamanouchi.py partition.py }}}

Cartesian Products

{{{id=133| S = CartesianProduct([1,2,3],['x','y']); S /// Cartesian product of [1, 2, 3], ['x', 'y'] }}} {{{id=134| S.list() /// [[1, 'x'], [1, 'y'], [2, 'x'], [2, 'y'], [3, 'x'], [3, 'y']] }}} {{{id=411| /// }}}

Root Systems

{{{id=130| S = RootSystem(['B',3]); S /// Root system of type ['B', 3] }}} {{{id=410| S.root_lattice() /// Root lattice of the Root system of type ['B', 3] }}} {{{id=131| /// }}}

Partitions of an integer:

{{{id=404| P = Partitions(5); P /// Partitions of the integer 5 }}} {{{id=405| P.cardinality() /// 7 }}} {{{id=132| P.list() /// [[5], [4, 1], [3, 2], [3, 1, 1], [2, 2, 1], [2, 1, 1, 1], [1, 1, 1, 1, 1]] }}} {{{id=406| time Partitions(10^6).cardinality() /// 1471684986358223398631004760609895943484030484439142125334612747351666117418918618276330148873983597555842015374130600288095929387347128232270327849578001932784396072064228659048713020170971840761025676479860846908142829356706929785991290519899445490672219997823452874982974022288229850136767566294781887494687879003824699988197729200632068668735996662273816798266213482417208446631027428001918132198177180646511234542595026728424452592296781193448139994664730105742564359154794989181485285351370551399476719981691459022015599101959601417474075715430750022184895815209339012481734469448319323280150665384042994054179587751761294916248142479998802936507195257074485047571662771763903391442495113823298195263008336489826045837712202455304996382144601028531832004519046591968302787537418118486000612016852593542741980215046267245473237321845833427512524227465399130174076941280847400831542217999286071108336303316298289102444649696805395416791875480010852636774022023128467646919775022348562520747741843343657801534130704761975530375169707999287040285677841619347472368171772154046664303121315630003467104673818 Time: CPU 0.04 s, Wall: 0.08 s }}}

Dyck words are the expressions containing $n$ pairs of correctly matched parentheses.

{{{id=407| @interact def _(n=(1..6)): for w in DyckWords(n): print w ///
}}} {{{id=17| /// }}}

Graphs

The Sage graphs module implements a huge amount of functionality for working with graphs (mostly by Robert Miller, Emily Kirkman, and Jason Grout, and built partly on NetworkX).  

  • Complete new implementation of computation of automorphism groups of graphs, determining isomorphism between graphs, and canonical labelings.
  • Extensive code for plotting graphs.
  • Queryable relational database of all graphs on at most 7 vertices. 
  • New highly optimized data structure for implementing algorithms that manipulate
  • Enumerating certain types of graphs efficiently (e.g., trees).

PROJECT: Robert Miller's vision for graphs is to have graphs/base completely production level (under active development now!), so that if someone wants to write some functions in Cython, then this is the clear graph theory library to use. We need a couple submodules:

  • sage/graphs/coloring/
  • sage/graphs/structured_graphs/ (or something similar, for bipartite graphs, bundles, etc.)
  • sage/graphs/generators/

graph.py needs to get split into several levels like the matrix code, and mostly Cythonized.

{{{id=256| ls('graphs') /// __init__.py graph_database.py linearextensions.py all.py graph_fast.c planarity base graph_fast.pyx planarity.c bipartite_graph.py graph_generators.py planarity.pyx chrompoly.c graph_isom.c print_graphs.py chrompoly.pyx graph_isom.pxd schnyder.py graph.py graph_isom.pyx trees.c graph_bundle.py graph_list.py trees.pxd graph_coloring.py graph_plot.py trees.pyx }}} {{{id=109| G = graphs.KrackhardtKiteGraph() H = G.coloring(hex_colors=True) G.plot(vertex_colors=H).show(figsize=3) /// }}} {{{id=110| G.automorphism_group() /// Permutation Group with generators [(1,10)(2,4)(5,6)] }}} {{{id=108| G.chromatic_polynomial() /// x^10 - 18*x^9 + 142*x^8 - 643*x^7 + 1837*x^6 - 3424*x^5 + 4152*x^4 - 3151*x^3 + 1356*x^2 - 252*x }}} {{{id=111| /// }}} {{{id=33| /// }}}

Crypto

 

The cryptography module is under current active developmen (mainly by Martin Albrecht and Minh Nguyen), with the goal of making Sage the standard tool of choice for analysing symmetric ciphers using algebraic and numerical methods.  The crypto module has two purposes:

  • Teaching of fundamental building blocks of cryptography (stream ciphers and e.g. LSFRs, block ciphers and their S-Boxes). 
  • Aids research in cryptography by providing common building blocks. 

The crypto module

  • provides elementary cryptographic primitives for the purposes of teaching and cryptanalysis,
  • includes scaled-down versions of standard cryptographic algorithms, and
  • provides interfaces to standard cryptographic algorithms, and
  • toolboxes for encryption, decryption, signatures, and hashing.

PROJECT: Minh Nguyen is working on expanding the teaching aspect right now by adding a MiniAES to sage.crypto and Martin Albrecht is expanding its usefulness for algebraic cryptanalysis by (a) adding more ciphers (e.g. DES and PRESENT) and (b) e.g. a SAT-Solver interface.

PROJECT:  Create a number of modules that wrap common number theoretic building blocks related to public-key cryptography, and package them up in a form useful for performing public-key cryptographic operations. All the building blocks are there (optimized arithmetic over the integers, support for basic and advanced number theory).

{{{id=249| ls('crypto') /// __init__.py classical_cipher.py stream.py all.py cryptosystem.py stream_cipher.py cipher.py lfsr.py classical.py mq }}}

Teaching crypto (there is a free undergrad cryptography book by David Kohel and Sage includes all the code he wrote for that book):

{{{id=137| M = AlphabeticStrings() E = SubstitutionCryptosystem(M); E /// Substitution cryptosystem on Free alphabetic string monoid on A-Z }}} {{{id=138| K = M([ 25-i for i in range(26) ]); K /// ZYXWVUTSRQPONMLKJIHGFEDCBA }}} {{{id=142| e = E(K) m = M("THECATINTHEHAT") secret = e(m); secret /// GSVXZGRMGSVSZG }}} {{{id=145| e.inverse()(secret) /// THECATINTHEHAT }}} {{{id=136| /// }}}

Small Scale Variants of the AES (SR) Polynomial System Generator.   Used to experiment with algebraic attacks on block ciphers.

{{{id=135| sr = mq.SR(1, 1, 1, 4) sr /// SR(1,1,1,4) }}} {{{id=141| print sr.R.repr_long() /// Polynomial Ring Base Ring : Finite Field in a of size 2^4 Size : 20 Variables Block 0 : Ordering : degrevlex Names : k100, k101, k102, k103, x100, x101, x102, x103, w100, w101, w102, w103, s000, s001, s002, s003, k000, k001, k002, k003 }}} {{{id=19| /// }}} {{{id=146| /// }}} {{{id=140| /// }}}