Transposição Diádica

9

Como na maioria dos símbolos de APL, tem significados diferentes quando chamados com um argumento (transposição) versus dois argumentos (dimensões diádicas de transposição / reordenação). Esse desafio diz respeito ao último, que age de maneira semelhante ao numpy.moveaxisPython ou permuteno MATLAB, mas é mais poderoso.

order ⍉ Aquando ordertem entradas distintas

Quando todos os membros de ordersão distintos, order ⍉ Aé equivalente a:

  • numpy.moveaxis(A, tuple(range(len(A.shape)), order) em Python ou
  • permute(A,order)em MATLAB. Citando a documentação deste último:

B = permuto (A, ordem) reorganiza as dimensões de A para que elas estejam na ordem especificada pela ordem do vetor. A matriz resultante B tem os mesmos valores que A, mas a ordem dos subscritos necessários para acessar qualquer elemento específico é reorganizada conforme especificado por ordem.

Por exemplo, suponha que Aseja uma matriz 3D e deixe B ← (2 0 1)⍉A. Então B é tal que B[x0,x1,x2] = A[x2,x0,x1]para todosx2,x0,x1

order ⍉ Aquando orderrepetiu entradas

Quando ordertem entradas repetidas, pegamos uma fatia diagonal da matriz. Por exemplo, seja A uma matriz 2x3x4. B ← (0 0 1)⍉Aleva uma fatia diagonal Apara criar Btal que B[x0,x1] = A[x0,x0,x1]. Observe que Bé uma matriz 2x4: se fosse 3x4, precisaríamos definir B[2, x1] = A[2, 2, x1]qual estaria fora dos limites de A. Em geral, a kth dimensão Bserá o mínimo de tudo A.shape[i]isso order[i] = k.

Exemplo

Considere a transposição diádica order⍉Aonde order = [2, 1, 0]e A é 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]]]

O resultado é a 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]]]

Note que quando, por exemplo, (x0, x1, x2) = (4,1,2) temos B[x0,x1,x2] = A[x2, x1, x0] = A[2,1,4] = 49.

Se, em vez disso, order = [0, 0, 0]e Aacima, teríamos a saída Bcomo uma matriz tamanho-3 unidimensional, B = [0, 26, 52]para queB[1] = B[x0] = A[x0,x0,x0] = A[1,1,1] = 26

Entrada

Aqui usamos a indexação 0, mas você também pode usar a indexação 1 como é o padrão da APL.

  • Uma matriz multidimensional ou aninhada A, de dimensão n ≥ 1.

  • Uma lista orderde n números inteiros positivos consistindo nos números inteiros {0,1, ..., k} (ou {1, ..., k + 1} para 1 índice) para alguns k < n , em qualquer ordem, possivelmente com repetições.

Resultado

  • Uma matriz multidimensional ou aninhada que representa o resultado da aplicação da transposição diádica com esses argumentos. (A saída terá a dimensão k + 1. )

Você pode escrever um programa completo, função etc., conforme permitido pelo padrão atual no meta.

Se o seu idioma tiver um builtin, é recomendável também escrever uma solução sem o builtin para obter uma resposta interessante.

Casos de teste

Casos de teste no TIO

Implementação do Python de referência em breve.

Nota para a leitura de casos de teste: no APL, os penúltimos e últimos eixos de uma matriz estão ao longo de colunas e linhas nessa ordem.

lirtosiast
fonte
4
APL, 1 byte:: P
Quintec 17/11/2018
11
Na verdade, muitos símbolos da APL usam apenas um segundo argumento padrão quando chamados com um argumento. Isso inclui o uso dos índices de eixo reverso como padrão, ⍉Ao mesmo que (2 1 0)⍉Ase Afor uma matriz tridimensional e, em geral, ⍉Aé (⌽⍳≢⍴A)⍉A.
Adám 18/11/19
@lirtosiast pergunta sobre E / S: uma matriz multidimensional pode ser representada como um par de forma (lista de dimensões) e conteúdo (todos os elementos em ordem lexicográfica de seus índices)?
NGN
@ngn Eu diria que não por enquanto, mas você deve perguntar na meta se esse formato é aceitável por padrão.
lirtosiast
@lirtosiast Curiosamente, o Dyalog APL armazena internamente matrizes como [number-of-dimensions,first-dimension-length,second-dimension-length,…,last-dimension-length,first-element,second-element,…,last-element].
Adám 19/11/19

Respostas:

4

APL (Dyalog Unicode) , 34 bytes SBCS

Este é o código do meu colega (ligeiramente modificado de Roger Hui : A History of APL in 50 Functions , capítulo 30 ), publicado com permissão explícita.

Infix tácito anônimo lambda (pode ser usado como entrada para ).

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

Experimente online!

{... } dfn; é deixado argumento (eixos), é o argumento direita (array)
Por exemplo, [2,2,1]e[[[1,2],[3,4]]]

⍵[] Indexe a matriz com:

  (⍴⍵)[… A ] forma (comprimentos dos eixos) da matriz, indexada por:
  [1,2,2]

   ⍋⍺ o vetor de classificação (os índices que os classificariam) dos eixos
   [3,1,2]
  [2,1,2]

  ⍺[⍋⍺]{}⌸ Use os eixos classificados como chaves para agrupar isso e para cada grupo:
  [1,2,2]{"1":[2],"2":[1,2]}

   {⌊/⍵} encontre o menor comprimento do eixo
   {"1":2,"2":1}[2,1]

   gerar os índices em um sistema cartesiano dessas dimensões
  [[[1,1]],[[2,1]]]

   garantir que os índices de cada coordenada sejam um vetor (seria escalar se for um vetor)
  [[[1,1]],[[2,1]]]

  ()⌷¨ Indexe em cada um dos seguintes itens:

   ⊂⊂⍺ os eixos (duplamente fechados; uma vez para selecionar as células ao longo do primeiro e único eixo e uma vez para ¨emparelhar cada vetor à direita com todo o conjunto de eixos à esquerda)
   2 1 2
  [[[1,1,1]],[[1,2,1]]]
[[1],[3]]

Adão
fonte