Blogue

Some small Sage tricks

14 décembre 2012 | Catégories: sage | View Comments

Below are some Sage tricks that I gathered from other users of Sage, from sage-devel and other places since one year.

Stop the focus in the Notebook

This Notebook hack of the day was published on sage-devel by William Stein during May 2012 to fix that focus movement in the Notebook:

html('<script>cell_focus=function(x,y){} </script>')

Consult the documentation of a function in the browser

Open the documentation of a particular function in a web browser, from either the command-line or the notebook:

sage: browse_sage_doc(factor)

It works also for methods of an object:

sage: m = matrix(2, range(4))
sage: browse_sage_doc(m.inverse)

I found this command when I consulted the help():

sage: help()

Implicit multiplication

Some behavior in Sage can be made implicit like multiplication and variable definition. This might be good for new users coming from Maple for instance.

Normally, this syntax raises an error:

sage: 34x
------------------------------------------------------------
   File "<ipython console>", line 1
     34x
       ^
SyntaxError: invalid syntax

It is possible to make it work:

sage: implicit_multiplication(True)
sage: 34x
34*x

Implicit variable definition

The following works only in the Sage Notebook. It allows to turn on automatic definition of variables:

sage: automatic_names(True)
sage: x + y + z
x + y + z

Turn out automatic show when using plot

Set the default to False for showing plots using any plot commands:

sage: show_default(False)

I prefer False but you may not.

Rerun the patchbot

One can re-run the tests of a particular ticket by adding ?kick to the url of the ticket on the patchbot Sage server. For example, to rerun the tests on the ticket #13461, one can load the following page:

http://patchbot.sagemath.org/ticket/13461/?kick

This trick was shared on sage-devel during August 2012.

Python debugger

The majority of the Best Practices for Scientific Computing are followed by the Sage Development model. But, there is one principle that at least I do not use enough : a debugger. However, a Python debugger exists and a tutorial for using the Python debugger is available on onlamp.com.

I remember that discussion on sage-devel Poll: which debugger do you use? where developers were sharing their debugger tricks. It seems that using print statements is unavoidable.

Computing basic statistics with R

I always knew R is in Sage but never used it even if sometimes I need to compute some statistics of list of numbers. In Sage, one can print statistics of a list of numbers using R:

sage: L = [randint(0,100) for _ in range(20)]
sage: r.summary(L)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
  14.00   27.75   57.50   53.45   69.00   98.00

Creation of the number field in \(\sqrt{5}\)

Before learning it from this video of William Stein, I did not know that the square brackets could be used to create such number field:

sage: A = ZZ[sqrt(5)]
sage: a,sqrt5 = A.gens()
sage: A
Order in Number Field in sqrt5 with defining polynomial x^2 - 5
sage: sqrt5
sqrt5

Using Sage locally in the notebook from a server

First, log into the server using the following port setup:

ssh -L 8389:localhoat:8389 [SERVER]

Start the notebook with the given port:

sage -notebook port=8389

This ask for a password, if you forget it, you may reset it by first opening Sage, and by starting the notebook with the option reset=True:

sage: notebook(port=8389, reset=True)

Then, by opening the browser at the following adress, I can log in to the notebook from the server:

http://localhost:8389/home/admin/

Going from Mercurial to Git

Sage will soon move from Mercurial to Git. In the past, I tried to understand the difference between Mercurial and Git. I was never able to find a simple text or blog post on the web explaining in a simple way the differences. One diffence would be about branching. But I was not using branches with Mercurial... As I see it, differences between Mercurial and Git are hard to explain or at least hard to understand.

Anyway, I once found this tutorial on the Git version control system: Understanding Git Conceptually where the approach is "conceptual" and maybe easier for the mathematician. For instance, in Section 1 it is written that repositories can be "visualized as a directed acyclic graph of commit objects". I still haven't go through this tutorial but I consider to start with this one.

Inheritance tree

One may draw the inheritance tree of a class with the following command:

sage: class_graph(Integer).plot()
/Files/2012/class_graph_integer.png
Read and Post Comments

Using Sage + graphviz + dot2tex + tikz + tikz2pdf to draw a graph

13 novembre 2012 | Mise à jour: 16 novembre 2012 | Catégories: latex, sage | View Comments

Let's first construct a graph that we will use in our examples below. We first construct a finite group generated by 2 by 2 matrices on the field \(GF(3)\). The group contains 24 elements. We then construct its Cayley graph:

sage: F = GF(3)
sage: gens = [matrix(F,2,[1,0, 1,1]), matrix(F,2, [1,1, 0,1])]
sage: group = MatrixGroup(gens); group
Matrix group over Finite Field of size 3 with 2 generators:
[[[1, 0], [1, 1]], [[1, 1], [0, 1]]]
sage: group.cardinality()
24
sage: G = group.cayley_graph()

Default graph plot

The default graph plot in Sage is:

sage: G.show(color_by_label=True)
/Files/2012/graph_show.png

Using view is actually broken when vertices are matrices because default format (format='tkz_graph') does not support it:

sage: view(G)
An error occurred.
...
LaTex error

Installing dot2tex + graphviz

One may get another kind of tikz output using the dot2tex.spkg together with graphviz. To know what is the latest available version of dot2tex use the command optional_packages():

sage: [x for x in flatten(optional_packages()) if 'dot2tex' in x]
['dot2tex-2.8.7-2']

The command to install the most recent version of dot2tex.spkg do from the command line (where you replace the version numbers by the above output):

sage -i dot2tex-2.8.7-2

As the documentation of G.layout_graphviz() says, install graphviz >= 2.14 so that the programs dot, neato, ... are in your path. The graphviz suite can be download from the graphviz website.

Basic Usage

This should allow the following to work:

sage: G.set_latex_options(format='dot2tex', prog='neato')
sage: G.set_latex_options(color_by_label=True)
sage: view(G)
/Files/2012/graph_neato.png

Limits of the basic usage

With the above usage, you will find that the command view(G) command is very slow and that sometimes it just doesn't work and gives a Latex error like this:

sage: G.set_latex_options(format='dot2tex', prog='dot')
sage: view(G)
An error occurred.
...
LaTex error

This is because the default compilation is just unappropriate for our usage (I still wonder for which usage it can be appropriate). In fact, the default compilation is first trying the conversion tex to dvi to png using latex and dvipng. If the dvipng part does not work for whatever reason (which is our case), it will then try the conversion dvi to ps to pdf using dvips and ps2pdf. This worked above for prog='neato' but not for prog='dot' because dvipng does not seem to like when latex produces Overfull \hbox and Overfull \vbox.

The Best Usage

The compilation strategy can be changed by using the engine option and by setting it to 'pdflatex'. Also the Overfull problem can be solved using the option tightpage=True:

sage: G.set_latex_options(format='dot2tex', prog='dot')
sage: G.set_latex_options(color_by_label=True)
sage: view(G, engine='pdflatex', tightpage=True)
/Files/2012/graph_dot.png

More options

The variable prog is for the program used for the layout. It must be a string corresponding to one of the software of the graphviz suite. Accepted values for prog are:

  • 'dot' (the default)
  • 'neato'
  • 'twopi'
  • 'circo'
  • 'fdp'

When using format='dot2tex', other available options are:

sage: G.set_latex_options(color_by_label=True)
sage: G.set_latex_options(edge_labels=True)
sage: G.set_latex_options(edge_colors=I_dont_know_what)

Consult the help for more details:

sage: opts = G.latex_options()
sage: opts.set_option?

However, these other options do not seem to work perfectly. I don't know what format to give to edges_colors and edge_labels=True seems broken. I posted a workaround on the sagetrac to fix it.

Using the tikz2pdf script instead of the command view

Alternatively, when I get problems with the view command, I use my script tikz2pdf instead:

sage: G.set_latex_options(format='dot2tex', prog='dot')
sage: G.set_latex_options(color_by_label=True)
sage: G.latex_options()
LaTeX options for Digraph on 24 vertices: {'prog': 'dot', 'color_by_label': True, 'format': 'dot2tex'}
sage: s = G.latex_options().dot2tex_picture()
sage: f = open('graph_dot.tikz', 'w')
sage: f.write(s)
sage: f.close()
sage: !tikz2pdf graph_dot.tikz
Using template ...
tikz2pdf: calling pdflatex...
tikz2pdf: Output written to 'graph_dot.pdf'.
Read and Post Comments

Draw a graph of matrices in LaTeX using Sage

18 octobre 2012 | Catégories: latex, sage | View Comments

In version 5.3 of Sage, if the vertices of a graph are matrices, then the default latex output does not compile. The default format is a tikzpicture and uses the tkz-berge library. One solution is to change the format to dot2tex. See below.

The default tikz output is:

sage: m = matrix(3, range(9))
sage: m.set_immutable()
sage: G = Graph()
sage: G.add_vertex(m)
sage: latex(G)
\begin{tikzpicture}
%
\useasboundingbox (0,0) rectangle (5.0cm,5.0cm);
%
\definecolor{cv0}{rgb}{0.0,0.0,0.0}
\definecolor{cfv0}{rgb}{1.0,1.0,1.0}
\definecolor{clv0}{rgb}{0.0,0.0,0.0}
%
\Vertex[style={minimum size=1.0cm,draw=cv0,fill=cfv0,text=clv0,shape=circle},
LabelOut=false,L=\hbox{$\left(\begin{array}{rrr}
0 & 1 & 2 \\
3 & 4 & 5 \\
6 & 7 & 8
\end{array}\right)$},x=2.5cm,y=2.5cm]{v0}
%
%
\end{tikzpicture}

This output does not compile. Here is the error I get:

sage: view(G)
An error occurred.
This is pdfTeX, Version 3.1415926-1.40.10 (TeX Live 2009) (format=pdflatex 2011.4.19)  18 OCT
2012 21:34
entering extended mode

[...]

! Use of \tikz@@scope@env doesn't match its definition.
\pgfutil@ifnextchar #1#2#3->\let \pgfutil@reserved@d =#1\def \pgfutil@reserved@a {
                                                                                  #2}\def \pgf
util@reserved@b {#3}\futurelet \pgfutil@let@token \pgfutil@ifnch
l.54 \end{array}\right)$},x=2.5cm,y=2.5cm]{v0}

If you say, e.g., `\def\a1{...}', then you must always
put `1' after `\a', since control sequence names are
made up of letters only. The macro here has not been
followed by the required stuff, so I'm ignoring it.

! Use of \tikz@@scope@env doesn't match its definition.

[...]

!  ==> Fatal error occurred, no output PDF file produced!

Latex error

The command to install dot2tex:

sage -i dot2tex-2.8.7-2

As the documentation of G.layout_graphviz() says, install graphviz >= 2.14 so that the programs dot, neato, ... are in your path. This allows the following to work:

sage: m = matrix(3, range(9))
sage: m.set_immutable()
sage: G = Graph()
sage: G.add_vertex(m)
sage: G.set_latex_options(format='dot2tex')
sage: view(G)

To obtain the tikz code:

sage: tikz_string = G.latex_options().dot2tex_picture()
sage: print tikz_string
\begin{tikzpicture}[>=latex,line join=bevel,]
%%
\node (012345678) at (34bp,22bp) [draw,draw=none]
{$\left(\begin{array}{rrr}0 & 1 & 2 \\3 & 4 & 5 \\6 & 7 &
8\end{array}\right)$};
%
\end{tikzpicture}
Read and Post Comments

Définition d'une série formelle en Sage

25 septembre 2012 | Catégories: sage | View Comments

Question :

Comment fait-on en sage pour avoir le terme général d'une serie formelle en \(x\) comme \(1/(1-q^2x)\) par exemple, où \(q\) est un paramètre (il faudrait obtenir \(q^{2k} x^k\) ) ?

Quelques exemples se trouvent dans la documentation sur les espèces en Sage, mais il faut faire quand même quelques essais et combiner quelques idées pour y parvenir. Une façon de procéder est définir une espèce récursive en assignant un poids pour le paramètre (voir Weighted Species).

Sous une forme récursive, la série s'écrit :

\[ L = 1 + q^2 \cdot x \cdot L \]

Alors, en sage, on écrira:

sage: q = QQ['q'].gen()
sage: E = species.EmptySetSpecies()
sage: X = species.SingletonSpecies(weight=q^2)
sage: L = CombinatorialSpecies()
sage: L.define(E+X*L)
sage: L.generating_series().coefficients(10)
[1, q^2, q^4, q^6, q^8, q^10, q^12, q^14, q^16, q^18]

Aussi:

sage: X.generating_series().coefficients(5)
[0, q^2, 0, 0, 0]
sage: E.generating_series().coefficients(5)
[1, 0, 0, 0, 0]

On peut faire le produit de deux espèces:

sage: A = X * X
sage: A.generating_series().coefficients(5)
[0, 0, q^4, 0, 0]

On peut faire la somme de deux espèces:

sage: B = X + X
sage: B.generating_series().coefficients(5)
[0, 2*q^2, 0, 0, 0]

mais pas la différence:

sage: E - X
Traceback (most recent call last) :
...
TypeError: unsupported operand type(s) for -: 'EmptySetSpecies_class'
and 'SingletonSpecies_class'

ni le quotient:

sage: E / X
Traceback (most recent call last):
...
TypeError: unsupported operand type(s) for /: 'EmptySetSpecies_class'
and 'SingletonSpecies_class'

Encore moins une combinaison des deux:

sage: E/(E-X)
Traceback (most recent call last) :
...
TypeError: unsupported operand type(s) for -: 'EmptySetSpecies_class'
and 'SingletonSpecies_class'

et je ne sais pas pourquoi...

Read and Post Comments

My implementation of André's Joyal Bijection using Sage

12 mai 2012 | Catégories: sage | View Comments

Doron Zeilbeger made a talk last Friday at CRM in Montreal during Sage Days 38 about \(n^{n-2}\). At the end of the talk, he propoed a contest to code Joyal's Bijection which relates double rooted trees on \(n\) vertices and endofunctions on \(n\) elements. I wrote an implementation in Sage. My code is available here : joyal_bijection.sage. It will certainly not win for the most brief code, but it is object oriented, documented, reusable, testable and allows introspection.

Example

First, we must load the file:

sage: load joyal_bijection.sage

Creation of an endofunction:

sage: L = [7, 0, 6, 1, 4, 7, 2, 1, 5]
sage: f = Endofunction(L)
sage: f
Endofunction:
[0..8] -> [7, 0, 6, 1, 4, 7, 2, 1, 5]

Creation of a double rooted tree:

sage: L = [(0,6),(2,1),(3,1),(4,2),(5,7),(6,4),(7,0),(8,5)]
sage: D = DoubleRootedTree(L, 1, 7)
sage: D
Double rooted tree:
Edges: [(0, 6), (2, 1), (3, 1), (4, 2), (5, 7), (6, 4), (7, 0), (8, 5)]
RootA: 1
RootB: 7

From the endofunction f, we get a double rooted tree:

sage: f.to_double_rooted_tree()
Double rooted tree:
Edges: [(0, 6), (2, 1), (3, 1), (4, 2), (5, 7), (6, 4), (7, 0), (8, 5)]
RootA: 1
RootB: 7

From the double rooted tree D, we get an endofunction:

sage: D.to_endofunction()
Endofunction:
[0..8] -> [7, 0, 6, 1, 4, 7, 2, 1, 5]

In fact, we get D from f and vice versa:

sage: D == f.to_double_rooted_tree()
True
sage: f == D.to_endofunction()
True

Timing

On my machine, it takes 2.23 seconds to transform a random endofunction on \(\{0, 1, \cdots, 9999\}\) to a double rooted tree and then back to the endofunction and make sure the result is OK:

sage: E = Endofunctions(10000)
sage: f = E.random_element()
sage: time f == f.to_double_rooted_tree().to_endofunction()
True
Time: CPU 2.23 s, Wall: 2.24 s

Comments

I am using the Sage graph library (Networkx) to find the cycles of a graph and to find the shortest path between two vertices. It would be interesting to compare the timing when using the zen library which is lot faster then networkx.

Read and Post Comments

« Previous Page -- Next Page »