vendredi 2 octobre 2009

Loi de Zipf sous Linux

Vers 1935, George Kingsley Zipf entreprit d'analyser la fréquence des mots dans Ulysses de James Joyce...

Après avoir classé les mots par leur fréquence d'apparition, il se serait aperçu que si le mot le plus fréquent apparaissait N fois, le dixième mot le plus fréquent apparaissait N/λ, le centième mot, N/λ², etc...

Il est aujourd'hui facile de vérifier ses travaux.

D'abord, il faut aller chercher Ulysses sur le Projet Gutenberg et en traitant le texte avec des outils standards Unix/Linux, on obtient assez facilement le résultat attendu.

Il suffit, en effet, d'envoyer le texte dans une série de filtres :

cat 4300-8.txt |

La première chose à faire est de transformer toutes les majuscules en minuscules pour que 'The' soit équivalent à 'the' :

|tr [A-Z] [a-z]

Ensuite, on sépare tous les mots pour en mettre un sur chaque ligne. Le plus simple est de substituer tous les caractères non alphabétiques par un retour à la ligne :

|sed 's/[^a-z]/\n/g'

Tant qu'à faire, supprimons toutes les lignes vides créées :

|awk '/[a-z]/{print $1;}'

Nous avons maintenant une liste de mots qu'il convient de trier :

|sort

Et compter chaque mot :

|uniq -c

Nous ne nous intéressons pas aux mots en eux-mêmes, mais au nombre de fois qu'ils apparaissent :

|awk '{print $1;}'

On va trier cette liste de fréquences par ordre descendant pour avoir la plus haute fréquence au premier rang (première ligne) :

|sort -rn

Et numéroter les lignes pour obtenir deux colonnes : le rang et la fréquence :

|pr -n -t

En résumé :

time cat 4300-8.txt|tr [A-Z] [a-z]|sed 's/[^a-z]/\n/g'|awk '/[a-z]/{print $1;}'|sort|uniq -c|awk '{print $1;}'|sort -rn|pr -n -t > zipf.data

Cela a pris, en gros, 9 secondes, bien moins que ce que le pauvre monsieur Zipf a dû y consacrer.

Si on trace le graphe log/log résultant avec Gnuplot

set logscale
set xlabel 'rang'
set ylabel 'frequence'
set title 'Loi de Zipf (Ulysses)'
set term png
set output 'UlyssesZipf.png'
plot 'zipf.data'

On obtient :




Un autre truc amusant (qui n'a probablement rien à voir avec Zipf) est la génération d'un graphique log/log qui montre 'le nombre 'y' de mots présents 'x' fois'.

À partir de la liste des fréquences, je compte combien de mots apparaissent un fois, deux fois,...

|sort -n|uniq -c

Et, comme on veut obtenir un graphique : nombre 'y de fois' qu'un mot apparaît 'x fois', il faut inverser les colonnes avant de l'injecter dans Gnuplot :

|awk '{print $2" "$1}'

En résumé :

time cat 4300-8.txt|tr [A-Z] [a-z]|sed 's/[^a-z]/\n/g'|awk '/[a-z]/{print $1;}'|sort|uniq -c|awk '{print $1;}'|sort -n|uniq -c|awk '{print $2" "$1;}' > data

Il ne reste plus qu'à 'gnuploter' tout ça :

set logscale
set term png
set output 'UlyssesZipf.png'
plot 'data'

Et voilà!

On 'voit bien' que sur un graphique log/log,
le nombre 'y' de fois qu'un mot apparaît 'x' fois
suit une loi de puissance.

mardi 9 juin 2009

Boule


Pour faire une boule, il suffit de frotter deux corps en rotation. (?)

Catadioptre


Une pile de cubes chromés formant un 'catadioptre'...

dimanche 7 juin 2009

Coin de cube avec POV-Ray


La boule rouge est placée derrière la caméra, le ciel est bleu, le sol est sable; on tourne autour d'un cube chromé dont on a retiré un 'coin de cube'... On remarquera que la boule (caméra) restent bien au centre quand elle se trouve dans le coin de cube.

#include "textures.inc"
#include "colors.inc"

global_settings {
assumed_gamma 1.5
noise_generator 2
}

light_source {
<-10, 100, -10>, rgb <1, 1, 1>
}
light_source {
<30, 20, -80>, rgb <1, 1, 1>
}
background { color rgb <0.4, 0.4, 0.6> }

camera {
location <8, 4, -4>
look_at <0, 0, 0>
rotate <0, 0, 15>
rotate <0, -15+clock*90, 0>
}
sphere {
<32, 16, -16>, 1
pigment { color Red}
rotate <0, 0, 15>
rotate <0, -15+clock*90, 0>
}
#declare D = 0.00001; // just a little bit !
difference {
box {
// big cube
<0, 0, 0>, <3, 3, -3>
texture{Polished_Chrome
finish {reflection 0.9}}
}
box {
// creux
<2, 2, -2>, <3+D, 3+D, -3-D>
texture{Polished_Chrome
finish {reflection 0.9}}
}
}
plane{ <0,1,0>, 0
texture{
pigment {color rgb <0.85,0.6,0.4>}
} // end of texture
translate <0, -2, 0>
} // end of plane


----

; Persistence Of Vision raytracer version 3.5 CubeCorner.ini file.

Antialias=On
Antialias_Threshold=0.3
Antialias_Depth=3

Input_File_Name=CubeCorner.pov

Initial_Frame=1
Final_Frame=30
Initial_Clock=0
Final_Clock=1

Cyclic_Animation=on
Pause_when_Done=off

----

povray -H200 -W200 CubeCorner.ini
convert -delay 50 -loop 0 -dispose Previous CubeCorner*.png CubeCornerMirror.gif

lundi 4 mai 2009

Faire un baudrier avec une sangle (et un peu de ferraille)



Il faut environ 2.50 mètres de sangle plate de 45 mm (noire sur le dessin), deux 'boucles' triangulaires (rouge) et deux 'boucles' carrées avec deux trous (bleu). Il est/était connu, à Bruxelles, sous le nom 'baudrier Lecomte' (du nom d'une famille de vendeurs de matériel d'escalade/spéléo/...). Lorsque la sangle est usée, il est facile et économique de la remplacer. Le confort n'est pas exceptionnel, mais il est simple, solide et efficace. Le schéma ci-dessus donne le parcours de la sangle dans les boucles. Le bas de la sangle passe derrière le dos; on passe les jambes dans les deux grandes boucles (reliée par une ficelle (verte)). Les 'triangles rouges' sont maintenus contre les plaquettes bleue par la sangle (la boucle est la plus courte possible); les 'jambières' passent en dessous. Le 'delta' (mousqueton en acier, triangulaire, à vis (non représenté)) ferme les deux 'triangles rouges'.