Transposición diádica

9

Como con la mayoría de los símbolos APL, tiene diferentes significados cuando se llama con un argumento (transposición) versus dos argumentos (dimensiones de transposición / reordenación diádica). Este desafío se refiere a este último, que actúa de manera similar a numpy.moveaxisPython o permuteMATLAB, pero es más poderoso.

order ⍉ Acuando ordertiene entradas distintas

Cuando todos los miembros de orderson distintos, order ⍉ Aes equivalente a:

  • numpy.moveaxis(A, tuple(range(len(A.shape)), order) en Python, o
  • permute(A,order)en MATLAB Citando de la documentación de este último:

B = permutar (A, orden) reorganiza las dimensiones de A para que estén en el orden especificado por el orden vectorial. La matriz B resultante tiene los mismos valores que A pero el orden de los subíndices necesarios para acceder a cualquier elemento en particular se reorganiza según lo especificado por orden.

Por ejemplo, supongamos que Aes una matriz 3D, y deja B ← (2 0 1)⍉A. Entonces B es tal que B[x0,x1,x2] = A[x2,x0,x1]para todosx2,x0,x1

order ⍉ Acuando orderha repetido entradas

Cuando orderha repetido entradas, tomamos un corte diagonal de la matriz. Por ejemplo, deje que A sea una matriz de 2x3x4. B ← (0 0 1)⍉Atoma un corte diagonal Apara crear Btal que B[x0,x1] = A[x0,x0,x1]. Tenga en cuenta que Bes una matriz de 2x4: si fuera 3x4, tendríamos que establecer B[2, x1] = A[2, 2, x1]cuál estaría fuera de los límites de A. En general, la kdimensión de Bserá el mínimo de todo A.shape[i]eso order[i] = k.

Ejemplo

Considere la transposición diádica order⍉Adonde order = [2, 1, 0]y A es 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]]]

El resultado es la matriz 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]]]

Tenga en cuenta que cuando, por ejemplo, (x0, x1, x2) = (4,1,2) tenemos B[x0,x1,x2] = A[x2, x1, x0] = A[2,1,4] = 49.

Si, en cambio, order = [0, 0, 0]y Acomo se indica arriba, la salida Bsería la matriz 1-dimensional size-3 B = [0, 26, 52]para queB[1] = B[x0] = A[x0,x0,x0] = A[1,1,1] = 26

Entrada

Aquí usamos la indexación 0, pero también puede usar la indexación 1 como es el valor predeterminado de APL.

  • Una matriz multidimensional o anidada A, de dimensión n ≥ 1.

  • Una lista orderde n enteros positivos que consiste en los enteros {0,1, ..., k} (o {1, ..., k + 1} para 1-index) para algunos k < n , en cualquier orden, posiblemente con repeticiones

Salida

  • Una matriz multidimensional o anidada que representa el resultado de aplicar la transposición diádica con esos argumentos. (La salida tendrá dimensión k + 1. )

Puede escribir un programa completo, función, etc. según lo permitido por el estándar actual en meta.

Si su idioma tiene una función incorporada, se recomienda escribir también una solución sin la función incorporada en aras de una respuesta interesante.

Casos de prueba

Casos de prueba en TIO

La implementación de Python de referencia estará disponible próximamente.

Nota para leer casos de prueba: en APL, los ejes penúltimo y último de una matriz están a lo largo de columnas y filas en ese orden.

lirtosiast
fuente
44
APL, 1 byte:: P
Quintec
1
En realidad, muchos símbolos APL solo usan un segundo argumento predeterminado cuando se los llama con un argumento. Esto incluye qué usa los índices de eje invertidos como predeterminados, por lo que ⍉Aes lo mismo que (2 1 0)⍉Asi se Atrata de una matriz tridimensional y, en general, ⍉Aes (⌽⍳≢⍴A)⍉A.
Adám
@lirtosiast pregunta sobre E / S: ¿se puede representar una matriz multidimensional como un par de formas (lista de dimensiones) y contenido (todos los elementos en orden lexicográfico de sus índices)?
ngn
@ngn Yo diría que no por ahora, pero debes preguntar en meta si ese formato es aceptable por defecto.
lirtosiast el
@lirtosiast De manera anecdótica, Dyalog APL almacena internamente las matrices como [number-of-dimensions,first-dimension-length,second-dimension-length,…,last-dimension-length,first-element,second-element,…,last-element].
Adám

Respuestas:

4

APL (Dyalog Unicode) , SBCS de 34 bytes

Este es el código de mi colega (ligeramente modificado de Roger Hui : Una historia de APL en 50 funciones , capítulo 30 ), publicado con permiso explícito.

Anónimo tácito infijo lambda (se puede utilizar como complemento para ).

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

Pruébalo en línea!

{... } dfn; es argumento izquierdo (ejes), es argumento derecho (matriz)
Por ejemplo [2,2,1]y[[[1,2],[3,4]]]

⍵[... ] indexar la matriz con:

  (⍴⍵)[... ] la forma (longitudes de los ejes) de la matriz, indexada por:
  [1,2,2]

   ⍋⍺ el vector de clasificación (los índices que los ordenarían) de los ejes
   [3,1,2]
  [2,1,2]

  ⍺[⍋⍺]{}⌸ Use los ejes ordenados como claves para agrupar eso, y para cada grupo:
  [1,2,2]{"1":[2],"2":[1,2]}

   {⌊/⍵} encontrar la longitud del eje más baja
   {"1":2,"2":1}[2,1]

   generar los índices en un sistema cartesiano de esas dimensiones
  [[[1,1]],[[2,1]]]

   asegúrese de que los índices de cada coordenada sean un vector (sería escalar si es un vector)
  [[[1,1]],[[2,1]]]

  (... )⌷¨ indice en cada uno de los siguientes:

   ⊂⊂⍺ los ejes (doblemente encerrados; una vez para seleccionar esas celdas a lo largo del primer y único eje, y una vez para ¨emparejar cada vector a la derecha con todo el conjunto de ejes a la izquierda)
   2 1 2
  [[[1,1,1]],[[1,2,1]]]
[[1],[3]]

Adán
fuente