Transposition dyadique

9

Comme avec la plupart des symboles APL, a des significations différentes lorsqu'il est appelé avec un argument (transposition) contre deux arguments (dimensions de transposition / réorganisation dyadique). Ce défi concerne ce dernier, qui agit de manière similaire à numpy.moveaxisPython ou permuteMATLAB, mais est plus puissant.

order ⍉ Aquand ordera des entrées distinctes

Lorsque tous les membres de ordersont distincts, order ⍉ Aéquivaut à:

  • numpy.moveaxis(A, tuple(range(len(A.shape)), order) en Python, ou
  • permute(A,order)dans MATLAB. Citant la documentation de ce dernier:

B = permute (A, ordre) réorganise les dimensions de A de sorte qu'elles soient dans l'ordre spécifié par l'ordre vectoriel. Le tableau B résultant a les mêmes valeurs que A mais l'ordre des indices nécessaires pour accéder à un élément particulier est réorganisé comme spécifié par la commande.

Par exemple, supposons qu'il As'agit d'un tableau 3D et laissez B ← (2 0 1)⍉A. Alors B est tel que B[x0,x1,x2] = A[x2,x0,x1]pour tousx2,x0,x1

order ⍉ Aquand ordera des entrées répétées

Quand ordera des entrées répétées, nous prenons une tranche diagonale du tableau. Par exemple, soit A un tableau 2x3x4. B ← (0 0 1)⍉Aprend une tranche diagonale Apour créer une Btelle chose B[x0,x1] = A[x0,x0,x1]. Notez qu'il Bs'agit d'un tableau 2x4: s'il était 3x4, nous aurions besoin de définir B[2, x1] = A[2, 2, x1]ce qui serait hors limites A. En général, la ke dimension de Bsera le minimum de tout A.shape[i]cela order[i] = k.

Exemple

Considérons la transposition dyadique order⍉Aorder = [2, 1, 0]et A est 3x4x5

    A =
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]
  [10 11 12 13 14]
  [15 16 17 18 19]]

 [[20 21 22 23 24]
  [25 26 27 28 29]
  [30 31 32 33 34]
  [35 36 37 38 39]]

 [[40 41 42 43 44]
  [45 46 47 48 49]
  [50 51 52 53 54]
  [55 56 57 58 59]]]

Le résultat est le tableau 5x4x3 B =

[[[ 0 20 40]
  [ 5 25 45]
  [10 30 50]
  [15 35 55]]

 [[ 1 21 41]
  [ 6 26 46]
  [11 31 51]
  [16 36 56]]

 [[ 2 22 42]
  [ 7 27 47]
  [12 32 52]
  [17 37 57]]

 [[ 3 23 43]
  [ 8 28 48]
  [13 33 53]
  [18 38 58]]

 [[ 4 24 44]
  [ 9 29 49]
  [14 34 54]
  [19 39 59]]]

Notez que lorsque, par exemple, (x0, x1, x2) = (4,1,2) nous avons B[x0,x1,x2] = A[x2, x1, x0] = A[2,1,4] = 49.

Si , au contraire order = [0, 0, 0]et Acomme ci - dessus, nous aurions la sortie Bsoit le tableau de taille 3 1 dimensions de B = [0, 26, 52]sorte queB[1] = B[x0] = A[x0,x0,x0] = A[1,1,1] = 26

Contribution

Ici, nous utilisons l'indexation 0, mais vous pouvez également utiliser l'indexation 1 comme c'est la valeur par défaut APL.

  • Un tableau multidimensionnel ou imbriqué A, de dimension n ≥ 1.

  • Une liste orderde n entiers positifs constitués des entiers {0,1, ..., k} (ou {1, ..., k + 1} pour 1-index) pour certains k < n , dans n'importe quel ordre, éventuellement avec répétitions.

Production

  • Un tableau multidimensionnel ou imbriqué représentant le résultat de l'application de la transposition dyadique avec ces arguments. (La sortie aura la dimension k + 1. )

Vous pouvez écrire un programme complet, une fonction, etc., comme le permet la norme actuelle sur la méta.

Si votre langue a une fonction intégrée, il est recommandé d'écrire également une solution sans la fonction intégrée pour une réponse intéressante.

Cas de test

Cas de test sur TIO

Référence de l'implémentation Python à venir.

Remarque pour la lecture des cas de test: dans APL, l'avant-dernier et l'axe ultime d'un tableau se trouvent le long des colonnes et des lignes dans cet ordre.

lirtosiast
la source
4
APL, 1 octet:: P
Quintec
1
En fait, de nombreux symboles APL utilisent simplement un deuxième argument par défaut lorsqu'ils sont appelés avec un seul argument. Cela inclut celui qui utilise les indices d'axe inversés par défaut, c'est donc ⍉Ala même chose que (2 1 0)⍉Asi Aest un tableau à 3 dimensions et en général l' ⍉Aest (⌽⍳≢⍴A)⍉A.
Adám
@lirtosiast question sur les E / S: un tableau multidimensionnel peut-il être représenté comme une paire de forme (liste de dimensions) et de contenu (tous les éléments dans l'ordre lexicographique de leurs indices)?
ngn
@ngn Je dirais non pour l'instant, mais vous devriez demander à meta si ce format est acceptable par défaut.
lirtosiast
@lirtosiast Anecdotally, Dyalog APL stocke en interne les tableaux sous [number-of-dimensions,first-dimension-length,second-dimension-length,…,last-dimension-length,first-element,second-element,…,last-element].
Adám

Réponses:

4

APL (Dyalog Unicode) , SBCS 34 octets

Il s'agit du code de mon collègue (légèrement modifié de Roger Hui : Une histoire d'APL en 50 fonctions , chapitre 30 ), publié avec une autorisation explicite.

Infixe tacite anonyme lambda (peut être utilisé comme drop-in pour ).

{⍵[(⊂⊂⍺)⌷¨,¨⍳⍺[⍋⍺]{⌊/⍵}⌸(⍴⍵)[⍋⍺]]}

Essayez-le en ligne!

{} Dfn; est l'argument gauche (axes), est l'argument droit (tableau)
Eg [2,2,1]et[[[1,2],[3,4]]]

⍵[] Indexez le tableau avec:

  (⍴⍵)[] La forme (longueurs des axes) du tableau, indexée par:
  [1,2,2]

   ⍋⍺ le vecteur de classement (les indices qui les trieraient) des axes
   [3,1,2]
  [2,1,2]

  ⍺[⍋⍺]{}⌸ Utiliser les axes triés comme clés pour regrouper cela, et pour chaque groupe:
  [1,2,2]{"1":[2],"2":[1,2]}

   {⌊/⍵} trouver la plus petite longueur d'axe
   {"1":2,"2":1}[2,1]

   générer les indices dans un système cartésien de ces dimensions
  [[[1,1]],[[2,1]]]

   s'assurer que les indices de chaque coordonnée est un vecteur (serait scalaire si c'est un vecteur)
  [[[1,1]],[[2,1]]]

  ()⌷¨ Indexez chacun de ceux-ci avec les éléments suivants:

   ⊂⊂⍺ les axes (doublement fermés; une fois pour sélectionner ces cellules le long du premier et du seul axe, et une fois pour ¨coupler chaque vecteur à droite avec l'ensemble des axes à gauche)
   2 1 2
  [[[1,1,1]],[[1,2,1]]]
[[1],[3]]

Adam
la source