Section : demarre_mupad
Précédent : Matrices
Suivant : Probabilités et Statistiques

Programmation

MuPAD propose toutes les commandes des langages de programmation classiques. La philosophie est celle d'un langage fonctionnel. Au lieu de créer un logiciel avec programme principal et procédures, on étend le langage par les fonctions dont on a besoin, éventuellement regroupées en ``modules''. Tous les modules, même ceux livrés avec le langage, se présentent sous forme de fichiers texte, et on peut donc les ouvrir pour avoir des modèles de programmation. Certaines erreurs difficiles à trouver proviennent de confusions entre noms de variables ou de fonctions. MuPAD garde en mémoire tous les noms introduits tant qu'ils n'ont pas été libérés par clear ou reset. Il est donc prudent de donner des noms assez explicites aux variables, et ce même si les variables déclarées à l'intérieur d'une procédure donnée resteront locales.

Il existe en général de nombreuses alternatives pour un même résultat. Il n'est pas évident de prédire celles qui seront les plus efficaces. Comparez les temps d'exécution de 7 manières de calculer 5000!.

time((5000!));
time(_mult($1..5000));
time((f:=1: for i from 2 to 5000 do f:=f*i end_for));
time((f:=1: i:=1: while i<5000 do i:=i+1; f:=f*i end_while));
time(product(i,i=1..5000));
time(fp::fold(_mult,1)($1..5000));
time(fp::fold((x,y)->(x*y),1)($1..5000));
L'ensemble de fonctions présenté ci-dessous peut servir de première boîte à outils pour la simulation de variables aléatoires. Elles illustrent différents aspects de la programmation en MuPAD.

/*-------------------------------------------------------------------*/
/*               GENERATION D'ECHANTILLONS ALEATOIRES                */
/*-------------------------------------------------------------------*/

/* Echantillon de taille n de la loi uniforme sur l'intervalle [0,1].*/ 

ech_uni:=proc(n)
local alea, i, resultat;
begin
     alea:=random/1e12;
     resultat:=[alea() $i=1..n];
     return(resultat)
end_proc:
/*-------------------------------------------------------------------*/

/* Echantillon de taille n de la loi de Bernoulli de parametre p.    */

ech_ber:=proc(n,p)
local alea, i, pp, resultat;
begin
     pp := p*1e12;
     alea:= proc() 
          begin 
               if random()<pp then return(1) else return(0) 
               end_if 
          end_proc;
     resultat:=[alea() $i=1..n];
     return(resultat)
end_proc:
/*-------------------------------------------------------------------*/

/* Echantillon de taille n de la loi normale N(0,1).                 */
         
ech_nor:=proc(n)
local alea, taille, i, resultat;
begin
     alea:=proc()
     local u, v, s;
     begin  
          u:=2*random()/1e12-1;
          v:=2*random()/1e12-1;
          s:=u*u+v*v;
          while s>1 do
               u:=2*random()/1e12-1;
               v:=2*random()/1e12-1;
               s:=u*u+v*v
          end_while;
          s:=sqrt(-2*ln(s)/s);
          u:=s*u;
          v:=s*v;
          return([u,v])
     end_proc;
     taille:=n div 2;
     resultat:=map([alea()$i=1..taille],op);
     return(resultat)
end_proc:

/*-------------------------------------------------------------------*/
/*                            FREQUENCES                             */ 
/*-------------------------------------------------------------------*/

/* "frequence_classe" retourne la frequence dans la liste "donnees"  */ 
/* de la classe [inf,sup[.                                           */

frequence_classe:=proc(donnees,inf,sup)
local resultat;
begin
     resultat:=float(nops(select(donnees,
                    func(bool(val>=inf and val<sup),val)))
                         /nops(donnees));
     return(resultat)
end_proc:
/*-------------------------------------------------------------------*/

/* "frequences" retourne une liste de couples, dont le premier terme */ 
/* est une des valeurs de la liste "donnees", le deuxieme terme est  */ 
/* sa frequence d'apparition.                                        */

frequences:=proc(donnees)
local valeurs, i , resultat;
begin
     valeurs:=[op({op(donnees)})];
     resultat:=[ [valeurs[i],
                    float(nops(select(donnees,has,valeurs[i]))
                         /nops(donnees))] $ i=1..nops(valeurs)];
     return(resultat)
end_proc:
/*-------------------------------------------------------------------*/
/*                           HISTOGRAMMES                            */
/*-------------------------------------------------------------------*/

/* Histogramme pour une liste de bornes quelconque.                  */

histogramme:=proc(donnees,bornes)
local nbrcla, bortri, donred, distrib, i, 
                    abscisses, ordonnees, nbrpoints;
begin
     nbrcla:=nops(bornes)-1;
     bortri:=sort(bornes);
     donred:=select(donnees,func(bool(val>=bortri[1] and 
                         val<bortri[nbrcla+1]),val));
     distrib:=[ frequence_classe(donred,bortri[i],bortri[i+1]) 
               $ i=1..nbrcla ];
     abscisses:=map([[bortri[i],bortri[i],bortri[i+1]] 
               $ i=1..nbrcla],op);
     abscisses:=append(abscisses,bortri[nbrcla+1]);
     ordonnees:=map([[0,distrib[i]/(bortri[i+1]-bortri[i]),
                         distrib[i]/(bortri[i+1]-bortri[i])] 
               $ i=1..nbrcla],op);
     ordonnees:=append(ordonnees,0);
     nbrepoints:=nops(ordonnees);
     plot2d([Mode=List,[polygon(point(abscisses[i],ordonnees[i]) 
               $ i=1..nbrepoints)]]);
end_proc:
/*-------------------------------------------------------------------*/

/* Histogramme regulier.                                             */

histo_reg:=proc(donnees,inf,sup,nbreclasses)
local pas, borreg, i;
begin
     pas:=float((sup-inf)/nbreclasses);
     borreg:=[inf+i*pas $ i=0..nbreclasses];
     histogramme(donnees,borreg);
end_proc:

/*-------------------------------------------------------------------*/
/*                       NUAGES DE POINTS                            */
/*-------------------------------------------------------------------*/

/* Representation d'un nuage de points dans le plan                  */

nuage:=proc(abscisses,ordonnees)
local g,i,taille;
begin
     taille:=min(nops(abscisses),nops(ordonnees));
     plot2d(Scaling=Constrained,
          [Mode=List,[point(abscisses[i],ordonnees[i])$i=1..taille]]);
end_proc:
/*-------------------------------------------------------------------*/