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