Blogue

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

Sur le nombre de passes sans perdre le disque à l'ultimate

08 novembre 2012 | Mise à jour: 11 novembre 2012 | Catégories: ultimate | View Comments

Les équipes d'ultimate ne sont pas parfaites et ne réussissent pas toutes leurs passes. Certaines équipes les réussissent plus que d'autres et on peut comparer deux équipes par exemple en calculant le pourcentage de passes réussies. Si une équipe réussit 4 passes sur 5, elle a un taux d'efficacité de 80%. Sur 100 passes, elle en réussira 80. Dans ce texte, on écrira qu'une équipe est E80 si elle réussit 80% de ses passes, E90 si elle réussit 90% de ces passes, etc.

Probabilité de réussir trois passes consécutives

Quelle est la probabilité qu'une équipe E80 réussisse trois passes consécutives? En supposant que chaque passe constitue un événement indépendant, on peut calculer cette probabilité de la même façon qu'on la calcule pour les dés, c'est-à-dire en faisant le produit des probabilités de chaque événement. La probabilité d'obtenir deux 6 en lançant deux dés est : \[ \frac{1}{6} \times \frac{1}{6} = \frac{1}{36}. \] De la même façon, la probabilité qu'une équipe E80 réussisse trois passes consécutives est \[ 0.80 \times 0.80 \times 0.80 = 0.512. \]

Ainsi, une équipe E80 a seulement une chance sur deux (51.2%) de réussir trois passes consécutives. On peut penser qu'une équipe E80 est une équipe faible, mais pas forcément car cela peut aussi dépendre des conditions météorologiques. Dans un match récent entre Goat et Doublewide ayant eu lieu aux championnats américains de USA Ultimate où le vent dépassaient les 30 km/h, l'équipe Goat de Toronto a réussi 105 de ses 133 passes tentées (selon ce texte sur ultiworld.com) pour un taux de réussite de 78.9%.

Et pour une équipe E90 maintenant? Si le taux de réussite d'une passe augmente à 90%, alors la probabilité de réussir trois passes consécutives devient 70% environ : \[ 0.90 \times 0.90 \times 0.90 = 0.729. \]

Calculer le nombre de passes q'une équipe peut se permettre grâce au logarithme

Combien de passes est-ce qu'une équipe E90 peut faire avant de perdre le disque une fois sur deux? Calculons. \[ 0.90 \times 0.90 \times 0.90 \times 0.90 = 0.656, \] \[ (0.90)^5 = 0.590, \] \[ (0.90)^6 = 0.531, \] \[ (0.90)^7 = 0.478. \] Donc, entre la 6ème et la 7ème passe, ou du moins à partir de la 7ème, la probabilité qu'une équipe E90 soit encore en possession du disque est moins d'une chance sur deux. Cet exposant peut être calculé plus efficacement grâce aux logarithmes. En effet l'exposant que l'on doit mettre à la base 0.90 pour que la puissance égale 0.5 est donné par le logarithme de 0.50 en base 0.90: \[ (0.90)^x = 0.50 \quad\iff\quad x = \log_{0.90} 0.50 = 6.579, \] donc la puissance vaut bel et bien 0.5 entre la 6ème et la 7ème puissance entière comme on avait évalué. Si votre calculatrice ne permet pas de calculer le logarithme dans la base de votre choix, vous pouvez utiliser la formule de changement de base: \[ x = \log_{0.90} 0.50 = \frac{\log_b 0.50}{\log_b 0.90} = 6.579, \] où \(b\) est une base quelconque.

Demie-vie de possession

Ainsi, au delà de 6 passes, il y a plus d'une chance sur deux qu'une équipe E90 ait perdu la possession du disque. Inspiré par la chimie et la physique qui définit la demi-vie d'un élément radioactif comme étant la durée nécessaire pour que la moitié des noyaux radioactifs se soient désintégrés, nous définissons la demi-vie de possession d'une équipe d'ultimate comme étant le nombre de passes avant que la probabilité d'être encore en possession du disque soit inférieure à une chance sur deux. En général, la demie-vie de possession peut être exprimée sous la forme: \[ \text{demie-vie de possession } = \frac{-\log 2}{\log q} \] où \(q\) est la probabilité de réussir une passe. On remarque que la demi-vie de possession correspond en fait à la médiane d'une loi géométrique.

On a déjà calculé que la demi-vie de possession d'une équipe E80 est 3 passes et que la demi-vie de possession d'une équipe E90 est 6 passes. Calculons maintenant la demi-vie de possession d'une équipe E95: \[ \frac{-\log 2}{\log 0.95} = 13.51, \] que l'on arrondit à l'entier inférieur, donc 13 passes. La demi-vie de possession augmente à 22 passes pour une équipe E97 et à 68 passes pour une équipe E99. Les valeurs de demi-vie de possession sont indiquées dans la première colonne du Tableau ci-bas, chaque ligne correspondant à une équipe dont l'efficacité par 100 passes est fixé.

Tableau : la demi-vie de possession est dans la colonne 0.50

  0.50 0.60 0.70 0.80 0.90 0.95 0.97
Équipe E80 3 2 1 1 0 0 0
Équipe E90 6 4 3 2 1 0 0
Équipe E95 13 9 6 4 2 1 0
Équipe E97 22 16 11 7 3 1 1
Équipe E99 68 50 35 22 10 5 3

Les autres colonnes indiquent des durées de possessions plus courtes. En effet, une équipe élite E99 réussissant 99% de ses passes sera plus exigeante et voudra marquer plus d'une fois sur deux. Ainsi, elle tentera de marquer en moins de passes que sa demi-vie de possession. Par exemple, une équipe E99 se limitera à 10 passes si elle veut marquer le point avec une probabilité de 90% et à 22 passes si elle veut marquer à 80%.

Conséquences sur les stratégies

Cela indique qu'une équipe doit posséder des stratégies indiquant comment marquer en une dizaine de passes tout au plus. Si la montée de terrain demande de faire 2, 3 ou 4 passes latérales, il en reste juste 6 pour avancer. D'où l'importance d'avoir des stratégies simples qui permettent de sortir de la ligne en pas plus que 2 ou 3 passes suivies d'au moins deux ou trois passes de continuité. Une équipe qui nécessite plus de 4 passes pour sortir des situations difficiles est vouée à l'échec.

Approfondir le raisonnement pour mieux connaître votre équipe

Pour mettre à l'épreuve les théories présentées dans ce texte et aussi afin de mieux connaître votre équipe, il faut d'abord évaluer le taux de passes réussies par votre ou par une équipe si possible dans un match représentatif joué contre une équipe de son niveau. Quel pourcentage de passes obtenez-vous? Une équipe E85, E94 ou E97 ? À partir du pourcentage obtenu et des formules ci-haut, calculez votre demi-vie de possession. Ensuite, il serait intéressant de considérer la statistique de match suivante, i.e. pour chaque possession du disque, calculer le nombre de passes effectuées. Enuite, vous pouvez tenter de répondre aux questions suivantes sur cette statistique:

  • Quelle est la distribution?
  • Quelle est la moyenne?
  • Quelle est la valeur maximale? minimale? l'écart type? etc.
  • Et surtout, où se situe la demi-vie de possession parmi la distribution?
  • Est-ce que la moyenne du nombre de passes est plus grande, égale ou plus petite que la demi-vie de possession?
  • Séparer la distribution en deux groupes (deux couleurs) selon que la possession s'est terminée par un point marqué et par un revirement. Comment se comparent les deux distributions?
  • Est-ce que cela donne une indication sur les stratégies à utiliser? à ne pas utiliser?

Si vous faites l'exercice sur votre équipe ou encore sur un match d'ultimate diffusé sur internet, n'hésitez pas à rendre compte de vos conclusions dans la section commentaires, car plusieurs questions restent sans réponses dont les suivantes :

  • Quel type d'équipe est Odyssée de Montréal?
  • Quel type d'équipe est Boston Ironside?
  • Atteignent-t-ils plus ou moins que E99?
  • Existe-il en pratique une équipe réussissant 999 passes sur 1000?
  • Dans quel intervalle se situent les équipes élites?

Exemple sur la finale des CUC 2012 opposant Odyssée et Union

La finale de la division mixte des Championnats canadiens 2012 opposant Odyssée de Montréal et Union de Toronto est sur internet:

CUC 2012 - Mixed Final - Odyssee vs Union

Dans ce match, on obtient les statistiques suivantes (tableau ci-bas).

Statistiques

On remarque que la durée des possessions d'Odyssée durait en moyenne 7.33 passes et que celles d'Union étaient de 6.00 passes. Or la demi-vie de possession d'Odyssée était de 11.09 passes de sorte que 88.9% de leurs possessions étaient plus courtes que leur demi-vie. Tandis que pour Union, la demi-vie de possession était seulement de 6.41 passes de sorte que seulement 57.% de leurs possessions étaient plus courtes que leur demi-vie.

  Odyssée Union
Passes tentées 198 156
Passes réussies 186 140
Taux de réussite 93.9 % 89.7 %
Demi-vie de possession 11.09 6.41
Minimum 1 1
Maximum 18 17
Moyenne 7.33 6.00
Médiane 6 4.5
Taux de possesions plus courtes que la demi-vie 88.9 % 57.7 %

Données brutes

Voici les données brutes dont je me suis servi, c'est-à-dire la durée de chaque possession en nombre de passes consécutives. Je les ai séparées en deux selon que l'équipe marquait le point ou perdait le disque. Dans le cas d'une possession qui se termine par un revirement, la dernière passe manquée est comptée.

  Durée des possessions (en nombre de passes)
Union marque le point 11, 8, 4, 7, 12, 7, 17, 1, 1, 6
Union perd le disque 11, 5, 2, 13, 2, 12, 2, 9, 7, 3, 3, 3, 3, 3, 3, 1
Odyssée marque le point 6, 4, 8, 5, 15, 4, 16, 10, 7, 4, 5, 4, 6, 8, 18
Odyssée perd le disque 3, 5, 7, 5, 3, 11, 11, 6, 1, 9, 7, 10
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

Le printemps québécois

08 octobre 2012 | Catégories: politique | View Comments

Pendant le printemps 2012, au Québec, le mouvement étudiant contre la hausse des frais de scolarité a été sans précédent. Une multitude de textes, vidéos, images se sont retrouvées sur le web. Dans ce message, je rassemble un certain nombre de liens que j'ai conservés dans mes signets.

Créations artistiques

Le printemps québécois a engendré une quantité phénoménale de créations artistiques dont voici quelques-unes:

"Nous, étudiants, ne sommes pas des casseurs violents comme Jean Charest et son équipe s'efforcent de nous représenter. Nous sommes une génération remplie d'espoir envers un futur meilleur, en quête d'une société plus juste. Nous marchons depuis février presque quotidiennement pour faire entendre notre indignation face à un gouvernement sourd, entêté à nous discréditer pour séduire son électorat de droite. Cette fois-ci, nous avons rassemblé des groupes d'étudiants faisant briller notre grand mouvement par leur originalité d'expression. Des artistes engagés dans la réussite de notre soulèvement depuis ses débuts. Sur des airs à saveur révolutionnaire, nous maintenons la pression et nous déclarons haut et fort et en musique, une fois de plus...", Libdub Rouge, 29 avril 2012.

Nous point d'interrogation

  • NOUS?, un événement unique de prise de parole, de réflexion sur l'état du Québec, sa démocratie, samedi 7 avril 2012, de midi à minuit. Les vidéos sur youtube.

Les meilleurs textes

Médias alternatifs

Plus que jamais, il faut s'informer et pas seulement dans les médias traditionnels. Voici des médias alternatifs que j'ai consultés ce printemps:

Des blogues

Des blogues qui ont traité du mouvement étudiant:

Autres sites sur le Mouvement étudiant

D'autres sites sur le mouvement étudiant:

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

« Previous Page -- Next Page »