Introduction à Pari/GP

Utilisation

Survie

  • Si bien installé, le logiciel se lance par la commande gp dans un terminal.

  • pour avoir de l’aide, taper ? (et entrée)

  • pour quitter, taper \q (et entrée)

Ergonomie

  • on peut utiliser Pari/GP directement pour les choses simples, en entrant les commandes les unes après les autres.

  • dès que ça devient plus compliqué, le mieux est d’éditer un fichier prog.gp (avec gEdit, Nano, vim…) dans lequel on rentre les commandes, les fonctions.

    En parallèle, lancer Pari/GP via un terminal dans le même répertoire. Chaque fois qu’on tape \r prog.gp on exécute le contenu du fichier.

Installation

  • Aller sur https://pari.math.u-bordeaux.fr/download.html.

    Si l’on compile le logiciel, penser à installer auparavant readline (par exemple via apt-get install libreadline-dev)

  • ou bien lancer via docker:

    docker run -it pascalmolin/parigp-small gp
    

    pour accéder à un répertoire local il faut le monter:

    docker run -it -w /tmp -v `pwd`:/tmp pascalmolin/parigp-small gp
    

Langage de base

Types de base

  • entiers, flottants

    a = 7
    b = 3.141592
  • Rationnels, entiers modulaires

    3/4
    Mod(7,26)
  • Polynômes

    x^7+x^2+1
  • Chaînes de caractères

    str = "salut"

Structures et manipulation

vecteur

  • c’est un tableau d’éléments quelconques

    l = [ 1, "coucou", 0.2 ]
  • attention les éléments sont indicés à partir de 1

    l[1]
  • longueur

    #l
  • affectation

    l[2] = 2/3
  • création

    vector(10)
    vector(10,k,k^2)
    
    [1..5]
  • concaténation

    l = concat(l, [2,3,4])
  • opérations par compréhension

    l = [1..9]
    l = [ k^2 | k <- l ]

    on peut rajouter des conditions pour ne garder que certains éléments

    l = [ k | k <- l, k % 2 == 1 ]

Opérations

Les opérateurs usuels :

  • arithmétiques : +, -, *, /, ^, % pour le reste et \ pour la division entière

    Les i++ et i--, i+=2, etc. du langage C sont valides.

  • comparaisons : ==, <=, >=, !=, <, >

  • opérateurs logiques : &&, ||

Toutes les opérations ont en général le sens le plus large possible. On peut écrire:

[1, 3, 7, 9] + [3, 1, 4, 3]

Mod([5, 8], 15)

11/17 % 5

Programmation

Note

La syntaxe est un peu surprenante : toutes les structures de contrôle sont des fonctions, dont les différents arguments contiennent les blocs à tester ou exécuter.

boucles

  • boucle tant que

    n = 7; while(n>0, print(n); n--)
  • itération simple

    for(n=2,9, print(n^2) )
  • d’autres itérateurs existent, par exemple

    forstep(k=1,30,5,print1(k));print()
    
    forprime(p=8,40,print1(p));print()
    
    forvec(v=[[1,2],[5,7]],print1(v));print()

tests

if(n==3, n++)
n = if(n % 2, 3*n+1, n/2 )

fonctions

f(x) = x^2+1;

Les fonctions peuvent être récursives. Pour faire une définition sur plusieurs lignes, il est nécessaire de mettre des accolades

g(a,b) = {
  if ( b == 0,
    a,
    g( b, a % b )
    );
}

Exercices (à chaque fois en une ligne)

  1. Calculer la proportion de premiers \(\leq 5000\) qui sont congrus à 3 mod 4.

    
            
            
    solution ⇲ ⇱ solution

    v=primes([1,5000]);#select(k->k%4==3,v)/#v

Spécificités à retenir

  • les tableaux sont indicés à partir de 1

  • une fin de ligne exécute la commande, sauf à l’intérieur d’un bloc délimité par des accolades. Les espaces sont ignorés.

  • les structures de contrôle sont des fonctions à plusieurs paramètres

Autres structures

Matrices

On peut rentrer une matrice à la main en terminant les lignes par un ;

m = [1, 2, 3 ; 4, 5, 6]

Les lignes et colonnes sont aussi indicés à partir de 1:

m[2,1]

Comme vector`, le constructeur générique est matrix

m = matrix(2,3,i,j,i+j);

et on peut omettre les arguments de remplissage pour créer une matrice remplie de zéros:

matrix(2,3)

Vecteurs lignes, colonne, matrices

Par défaut, un vecteur est un vecteur ligne. On peut le transformer en vecteur colonne en le transposant avec ~:

v = [1,2,3]
type(v)

c = v~
type(c)

C’est indispensable pour l’algèbre linéaire

M = [1,2,3;1,3,2;1,1,3];
M * c
v * M

Tables de hachage

On peut associer n’importe quoi à une clef:

g = Map()
mapput(g, "toto", 1273);
mapput(g, 1928, [3,2,1]);

Si une clef existe, on récupère la valeur avec mapget:

mapget(g, "toto")

et pour vérifier que la clef existe:

mapisdefined(g, "loulou")

Conversions

Pol([1,2,3])== x^2+2*x+3

Vec(x^5-3)== [1, 0, 0, 0, 0, -3]

Polrev([2,1,0,7,1])
Mat([ [1,2]~ , [3,5]~ ])== [1, 3; 2, 5]
Vec(Vecsmall("abc z"))== [97, 98, 99, 32, 122]

Strchr([65, 115, 99, 105, 105])== "Ascii"
digits(123)== [1, 2, 3]
digits(123, 2)== [1, 1, 1, 1, 0, 1, 1]

fromdigits([7,3,4,1])== 7341
fromdigits([7,3,4,1], 127)== 14387577

Sélection de fonctions utiles

Taper ?foo pour avoir de l’aide sur l’utilisation de la fonction foo.

Taper ? pour avoir un sommaire des commandes disponibles.

  • vecteurs : concat, vecsort, v[3..k-2], Vecrev

  • matrices: matsize, matdet, matker, matsolve

  • polynômes : poldegree, polcoeff, polroots, factor

  • primalité : isprime, ispseudoprime, primes, nextprime

  • arithmétique : factor, gcd, gcdext, chinese

  • anneaux quotients : Mod(2,17), Mod(x, x^13-1)

  • corps finis : ffgen, ffprimroot, fforder, fflog

  • courbes elliptiques : ellinit, elladd, ellmul, ellcard, ellorder

Exercices (oneliners)

  1. Construire la séquence [0,-1,1,-2,2,-3,3,-4,4...10]

    
            
            
    solution ⇲ ⇱ solution
    vector(21,k,(-1)^(k-1)*(k\2))
    
  2. Construire la liste du nombre de facteurs premiers distincts des 100 premiers entiers (utiliser factor qui renvoie une matrice des premiers et exposants).

    
            
            
    solution ⇲ ⇱ solution
    [ matsize(factor(n))[1] | n <- [1..100] ]
    

    Pari-GP contient aussi la fonction sigma qui simplifie les choses

    [ sigma(n,0) | n <- [1..100] ]
    
  3. Déterminer les nombres premiers inférieurs à 1000 qui sont palindromes en base 7.

    \\ utiliser isprime, digits, Vecrev
    solution ⇲ ⇱ solution
    [ n | n <- [1..1000], isprime(n) && fromdigits(Vecrev(digits(n,7)),7)==n ]
    
  4. Déterminer toutes les manières de placer les opérations +,-,* entre les entiers 1,2,3...9 (dans cet ordre) de sorte que l’on obtienne 120.

    \\ utiliser forvec, concat, eval
    solution ⇲ ⇱ solution

    forvec(p=vector(8,k,[1,3]),s = concat(concat(concat(vector(8,k,[k,op[p[k]]])),9));if(eval(s)==120,print(s)))

  5. Faire afficher les développements binaires suivants

    [0, 0, 0, 0, 1]
    [0, 0, 0, 1, 0]
    [0, 0, 0, 1, 1]
    [0, 0, 1, 0, 0]
    [0, 0, 1, 0, 1]
    [0, 0, 1, 1, 0]
    [0, 0, 1, 1, 1]
    [0, 1, 0, 0, 0]
    [0, 1, 0, 0, 1]
    [0, 1, 0, 1, 0]
    [0, 1, 0, 1, 1]
    [0, 1, 1, 0, 0]
    [0, 1, 1, 0, 1]
    
    solution ⇲ ⇱ solution
    for(n=1,13,print(Vecrev(Vecrev(digits(n,2),5))))