Діадичний перенос


9

Як і у більшості символів APL, він має різний зміст, коли викликається одним аргументом (транспоніровать) проти двох аргументів (діадичний розмір переміщення / зміни порядку). Ця проблема стосується останнього, який діє аналогічно numpy.moveaxisв Python або permuteMATLAB, але є більш потужним.

order ⍉ Aколи orderмає чіткі записи

Коли всі члени команди orderє різними, order ⍉ Aрівнозначно:

  • numpy.moveaxis(A, tuple(range(len(A.shape)), order) в Python, або
  • permute(A,order)в MATLAB. Цитуючи з документації останнього:

B = перестановка (A, порядок) переставляє розміри A так, щоб вони були в порядку, визначеному порядком вектора. В результаті масив B має ті самі значення, що і A, але порядок підписок, необхідний для доступу до будь-якого конкретного елемента, переставляється, як зазначено в порядку.

Наприклад, припустимо A, це 3D-масив, і нехай B ← (2 0 1)⍉A. Тоді Б такий, що B[x0,x1,x2] = A[x2,x0,x1]для всіхx2,x0,x1

order ⍉ Aколи orderє повторні записи

Після orderповторних записів ми беремо діагональний фрагмент масиву. Наприклад, нехай A - масив 2x3x4. B ← (0 0 1)⍉Aзаймає діагональний зріз уздовж, Aщоб створити Bтаке, що B[x0,x1] = A[x0,x0,x1]. Зауважте, що Bце масив 2x4: якби він був 3x4, нам потрібно було б встановити, B[2, x1] = A[2, 2, x1]який би не виходив за межі A. Загалом, цей kвимір Bбуде мінімальним для всіх A.shape[i]таких order[i] = k.

Приклад

Розглянемо діадичний транспозит, order⍉Aде order = [2, 1, 0]і 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]]]

Результат - масив 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]]]

Зауважимо, що коли, наприклад, (x0, x1, x2) = (4,1,2) у нас є B[x0,x1,x2] = A[x2, x1, x0] = A[2,1,4] = 49.

Якщо замість цього order = [0, 0, 0]і Aяк зазначено вище, тоді у нас виведенням Bбуде одновимірний масив розміру-3, B = [0, 26, 52]так щоB[1] = B[x0] = A[x0,x0,x0] = A[1,1,1] = 26

Вхідні дані

Тут ми використовуємо 0-індексацію, але ви також можете використовувати 1-індексацію, як це за замовчуванням APL.

  • Багатовимірний або вкладений масив Aрозмірності n ≥ 1.

  • Список orderз п позитивних цілих чисел , що складаються з цілих чисел {0,1, ..., K} (або {1, ..., K + 1} для 1-індексу) для деякого до < п , в будь-якому порядку, можливо , з повторами.

Вихідні дані

  • Багатовимірний або вкладений масив, що представляє результат застосування діадичного транспозиту з цими аргументами. (Вихід матиме розмірність k + 1. )

Ви можете написати повну програму, функцію тощо, як це дозволено чинним стандартом на мета.

Якщо у вашій мові є вбудований, рекомендується також написати рішення без вбудованого заради цікавої відповіді.

Тестові справи

Тестові приклади на TIO

Реалізація довідкового Python незабаром.

Примітка для читання тестових випадків: в APL передостання і кінцева осі масиву розташовані уздовж стовпців і рядків у такому порядку.


4
APL, 1 байт:: P
Квінтек

1
Насправді багато символів APL просто використовують другий аргумент за замовчуванням, коли викликається одним аргументом. Сюди входить те, що використовуються як за замовчуванням індекси оберненої осі, так ⍉Aсамо, як (2 1 0)⍉Aякщо б Aце тривимірний масив і взагалі ⍉Aє (⌽⍳≢⍴A)⍉A.
Adám

@lirtosiast питання щодо вводу-виводу: чи може багатовимірний масив представити у вигляді пари (перелік вимірів) та змісту (усі елементи у лексикографічному порядку їх індексів)?
ngn

@ngn я б зараз сказав "ні", але ви повинні запитати в мета, чи прийнятний цей формат за замовчуванням.
lirtosiast

@lirtosiast Анекдотично, Dyalog APL внутрішньо зберігає масиви як [number-of-dimensions,first-dimension-length,second-dimension-length,…,last-dimension-length,first-element,second-element,…,last-element].
Адам

Відповіді:


4

APL (Dyalog Unicode) , 34 байти SBCS

Це код мого колеги (трохи змінений з Роджера Хуя : Історія APL у 50 функціях , глава 30 ), розміщений з явним дозволом.

Анонімна мовчазна інфіксація лямбда (може використовуватися як спадний список ).

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

Спробуйте в Інтернеті!

{} Dfn; лівий аргумент (осі), правий аргумент (масив)
Напр. [2,2,1]та[[[1,2],[3,4]]]

⍵[] Індексувати масив за допомогою:

  (⍴⍵)[] Форма (довжини осей) масиву, індексована:
  [1,2,2]

   ⍋⍺ вектор градуювання (показники, які б їх сортували) осей
   [3,1,2]
  [2,1,2]

  ⍺[⍋⍺]{}⌸ Використовувати впорядковані осі як клавіші для групування цієї групи та для кожної групи:
  [1,2,2]{"1":[2],"2":[1,2]}

   {⌊/⍵} знайти найменшу довжину осі
   {"1":2,"2":1}[2,1]

   генерують показники в декартовій системі цих вимірів
  [[[1,1]],[[2,1]]]

   переконайтеся, що показники кожної координати є векторними (було б скалярним, якщо вектор)
  [[[1,1]],[[2,1]]]

  ()⌷¨ Індексувати кожного з них із наступним:

   ⊂⊂⍺ осі (подвійно укладені; один раз для вибору цих комірок по першій і єдиній осі, і один раз для того, ¨щоб з'єднати кожен вектор праворуч із усім набором осей зліва)
   2 1 2
  [[[1,1,1]],[[1,2,1]]]
[[1],[3]]

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.