Cours Apl 08
La Réduction

Derrière ce nom mystérieux, se cache une fonctionnalité fort utile.

On l'appelle ainsi car son résultat comporte une dimension de moins que l'objet auquel elle s'applique.
Pas de panique, surtout ne zappez pas !!!
En effet ça semble impressionnant mais c'est juste une question de bon sens.
Illustration : Je veux la somme de ce vecteur : 10 20 30 40
- Première solution : 10 + 20 + 30 + 40
Bien sûr, ça marche, mais c'est un peu laborieux. Et puis il faut connaître tous les éléments du vecteur.

- Deuxième solution : Apl nous offre la réduction. Dans le cas qui nous intéresse, ça consiste à passer d'un vecteur numérique à un scalaire contenant la somme du vecteur.
La syntaxe est la suivante :

         +/10 20 30 40
100
L'immense avantage de ce procédé est qu'il fonctionne sans que nous ayons besoin de connaître la taille de l'objet à sommer, ni son contenu exact.

Par exemple pour connaître la somme de Vnum1 on écrit simplement : +/Vnum1

Nous venons de constater que nous réduisions effectivement les dimensions, passant d'un vecteur à un scalaire.
Cela fonctionne à l'identique avec une matrice, si ce n'est que nous avons le choix dans le sens de balayage.
Ainsi pour avoir la somme des lignes de Mnum1, nous devons faire une réduction sur la deuxième dimension (balayage horizontal) :

         +/[2]Mnum1
100 10 4
Apl travaillant implicitement sur la dernière dimension, on aurait simplement pu écrire :
         +/Mnum1
De plus en plus fort : Collons ce total à droite de Mnum1
     Mnum1,+/Mnum1
10 20 30 40 100
 1  2  3  4  10
 1  1  1  1   4
Que s'est-il passé ?
Comme nous l'avons vu précédemment, quand plusieurs fonctions figurent dans la même expression, Apl commence par exécuter le groupe le plus à droite et en passe le résultat à la fonction immédiatement à gauche.
Cette ligne a donc été effectuée en deux temps :
- d'abord +/Mnum1 qui a rendu le vecteur de totaux 100 10 4
- puis Mnum1,(100 10 4) qui a donné le résultat final.

Comment coller à une matrice les totaux dans les 2 sens ?
Dans un premier temps on affecte à Mtot Nnum1 avec ses totaux par lignes :

     Mtot„Mnum1,+/Mnum1
Ensuite on colle dessous les totaux par colonnes.
     Mtot,[1]+/[1]Mtot
10 20 30 40 100
 1  2  3  4  10
 1  1  1  1   4
12 23 34 45 114
Pour vérifier le total général, c'est simple, il suffit de calculer la somme de Mnum1 transformée en vecteur :
         +/,Mnum1
114
Ici encore, Apl a travaillé en 2 temps :
- Linéariser Mnum1 avec ,Mnum1
10 20 30 40 1 2 3 4 1 1 1 1
- Puis en faire la somme par réduction :
+/ 10 20 30 40 1 2 3 4 1 1 1 1
Autres exemples :
- connaître le plus grand nombre d'un vecteur :
⌈/3 6 2 12 8
- connaître le nombre de voyelles d'une chaîne de caractères :
+/'hello les amis' ∊ 'aeiouy'
- est-ce que Mnum1 comporte au moins un nombre supérieur à 5 ?
∨/,Mnum1 > 5
- etc ...


Travaux pratiques

0
Chargez votre Ws de travaux pratiques
)load c:\Mes documents\pratique-apl
1
Calculez la somme de Vnum1
2
Calculez le total de chaque ligne de Mnum1
- Total de chaque colonne
3
Affichez les lignes de Mnum1 sur lesquelles figure le nombre 1
4
Combien de 1 Mnum1 possède-t-elle ?
5
Quel est le total général de Mnum2 ?
6
Affichez les lignes de Mnum1 comportant au moins 1 nombre pair.
7
Affichez le plus grand nombre de chaque ligne de Mnum3.
Affichez le plus petit nombre de la dernière colonne de Mnum3.
8
Sans utiliser la fonction Moyenne, calculez la moyenne de Mnum2.
9
Sans utiliser la primitive apl ! calculez factorielle 5 (et bien sûr sans écrire 1x2x3x4x5).
10
Sachant qu'Apl commence toujours par exécuter le groupe d'instructions le plus à droite, quel est le résultat de : -/3 4 5 2 3
11
Sauvez votre travail
)save

Solutions

1
Calculez la somme de Vnum1
         +/Vnum1
2
Calculez le total de chaque ligne de Mnum1
         +/Mnum1 ou +/[2]Mnum1
- Total de chaque colonne
         +/[1]Mnum1
3
Affichez les lignes de Mnum1 sur lesquelles figure le nombre 1
         (∨/Mnum1=1)/[1]Mnum1
4
Combien de 1 Mnum1 possède-t-elle ?
         +/1=,Mnum1
5
Quel est le total général de Mnum2 ?
         +/+/Mnum2 ou +/,Mnum2
6
Affichez les lignes de Mnum1 comportant au moins 1 nombre pair.
         (∨/~2|Mnum1)/[1]Mnum1
7
Affichez le plus grand nombre de chaque ligne de Mnum3.
         ⌈/ Mnum3
Affichez le plus petit nombre de la dernière colonne de Mnum3.
         ⌊/,¯1↑[2] Mnum3
8
Sans utiliser la fonction Moyenne, calculez la moyenne de Mnum2.
         (+/,Mnum2)÷×/⍴Mnum2
On divise le total général de Mnum2 par son nombre d'éléments (nb lignes x nb colonnes)

9
Sans utiliser la primitive apl ! calculez factorielle 5 (et bien sûr sans écrire 1x2x3x4x5).
         ×/⍳5
10
Sachant qu'Apl commence toujours par exécuter le groupe d'instructions le plus à droite, quel est le résultat de : -/3 4 5 2 3
         5
Explication :
2-3=¯1
5-¯1=6
4-6=¯2
3-¯2=5