Produit interne
L’exemple classique de produit interne est la fonction SOMMEPROD d’Excel permettant de faire une somme de produits. Ceci se traduit en APL par :
1 2 3 +.× 4 5 6 Output: 32 ⍝ (1×4) + (2×5) + (3×6)
Ce cas particulier s’obtient facilement en RPL :
2: {1 2 3}
1: {4 5 6}
× # Produit terme à terme des 2 listes
∑LIST # Somme des éléments
1: 32
D’autres cas utiles en version APL :
∧.< ⍝ Tous plus petits que... ∨.< ⍝ Au moins un plus petit que... 4 6 8 ∧.< 10 1 ⍝ Tous plus petits que 10 14 16 8 ∨.< 10 1 ⍝ Au moins un plus petit que 10
Et en version RPL :
2: {4 6 8}
1: 10
< ΠLIST # Produit de booléens = ET
1: 1 # Tous plus petits que 10
2: {4 6 8}
1: 10
< ∑LIST SIGN # Signe somme booléens = OU
1: 1 # Au moins un plus petit que 10
Remarquez que l’on aurait pu utiliser une écriture plus proche de l’APL :
2: {4 6 8}
1: « 10 < « AND » STREAM »
EVAL
1: 1 # Tous plus petits que 10
2: {4 6 8}
1: « 10 < « OR » STREAM »
EVAL
1: 1 # Au moins un plus petit que 10
On en déduit une généralisation du produit interne « x f.g y », Norman Brenner propose la fonction IN. (notée IOPROD dans le document original)
« → f « EVAL f STREAM » » 'IN. STO
Exemple :
4: {1 2 3}
3: {4 5 6}
2: « × »
1: « + »
VAR IN.
1: 32
Le principe est assez simple, l’opérateur + est mis dans la variable f (et disparait de la pile), EVAL fait alors le produit entre les 2 listes puis on réduit (application de manière récursive avec STREAM) en utilisant f, ce qui signifie ici faire la somme des termes.
Exercice révision
Plus grande valeur commune entre 2 listes
Il s’agit de trouver quelle est la plus grande valeur commune entre 2 listes (ces listes pouvant comporter des nombres négatifs ou nuls). Voici le résultat à traduire en RPL :
MAXI ← {⌈/ (⍺ ∊ ⍵) / ⍺}
2 3 8 1 MAXI 3 5 7 8 9
Output: 8
Solution : Le symbole ⍺ désigne l’opérande à gauche et ⍵ l’opérande à droite. On crée le vecteur logique ⍺ ∊ ⍵ qui permettra de ne garder que les éléments de ⍺ qui appartiennent à ⍵. On réduit « / » ensuite ce vecteur par la fonction max ⌈. En utilisant la fonction CL. que l’on a construite dans la première partie et qui permet de faire une compression logique :
« 2 « IF NOT THEN DROP END » DOLIST » 'CL. STO
Ou notre version simplifiée :
« SWAP IFT » 'CL. STO
On peut définir MAXI par :
« → v « DUP 1 « v SWAP POS SIGN » DOLIST » # ⍺ ∊ ⍵ ? CL. # (⍺ ∊ ⍵) / ⍺ « MAX » STREAM # ⌈/ » 'MAXI STO
Testons :
2: {2 3 8 1}
1: {3 5 7 8 9}
VAR MAXI
1: 8
Ou, si l’on ne veut pas utiliser CL. et n’avoir qu’une seule boucle:
« → v
« DUP
2 « IF v SWAP POS NOT # Boucle (⍺ ∊ ⍵) / ⍺
THEN DROP END
» DOLIST
»
« MAX » STREAM # ⌈/
»
'MAXI STO
Signalons que « MAX » STREAM ne fonctionne pas lorsqu’une liste est vide.
2: {2 3 8 1}
1: {4 4 4 4}
VAR MAXI
STREAM Error # Car aucun élément en commun