Отладка кода APL: как использовать `@` (index) и `⊢` (right tack) вместе? - PullRequest
1 голос
/ 06 марта 2020

Я пытаюсь прочитать тезис Аарона Хсу о Параллельном компиляторе данных, размещенном на графическом процессоре , где я обнаружил некоторый код APL, который не могу исправить. Я приложил оба скриншота страницы с нарушением (номер страницы 74 в соответствии с нумерацией тезисов внизу):

Переписанный код выглядит следующим образом:

d ← 0 1 2 3 1 2 3 3 4 1 2 3 4 5 6 5 5 6 3 4 5 6 5 5 6 3 4

Это имеет смысл: создать массив с именем d.

⍳≢d
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

Это тоже имеет смысл. Подсчитайте количество элементов в d и создайте последовательность этой длины.

⍉↑d,¨⍳≢d
0 1 2 3 1 2 3 3 4  1  2  3  4  5  6  5  5  6  3  4  5  6  5  5  6  3  4
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

Это немного сложно, но позвольте мне разбить это на части:

  • zip последовательность ⍳≢d = 1..27 с массивом d, используя идиому , которая сжимает два массива, используя сцепление.

  • Затем разделяется на две строки, используя и транспонировать, чтобы получить столбцы, используя

Теперь bigg ie:

(⍳≢d)@(d,¨⍳≢d)⊢7 27⍴' '
INDEX ERROR
      (⍳≢d)@(d,¨⍳≢d)⊢7 27⍴' '

Попытка разбить его:

  • ⍳≢d считает количество элементов в d
  • (d,¨⍳≢d) создает массив пар (d, index of d)
  • 7 27⍴' ' создает сетку 7 x 27: предположительно 7 потому что это максимальное значение d + 1, по причинам индексации.
  • Теперь я сбит с толку о том, как работает : насколько я знаю, он просто игнорирует все слева ! Поэтому я что-то упускаю из анализа этого выражения.

Я предполагаю, что оно анализируется как:

(⍳≢d)@((d,¨⍳≢d)⊢(7 27⍴' '))

, что, по моему мнению, должно оцениваться как:

(⍳≢d)@((d,¨⍳≢d)⊢(7 27⍴' '))
=  (⍳≢d)@((7 27⍴' ')) [using a⊢b = b]
=  not the right thing

Когда я записывал это, мне удалось исправить ошибку по счастливой случайности: если мы увеличим d до d + 1, чтобы мы были проиндексированы на 1, ошибка больше не проявляется:

d ← d + 1
d
1 2 3 4 2 3 4 4 5 2 3 4 5 6 7 6 6 7 4 5 6 7 6 6 7 4 5

затем:

(⍳≢d)@(d,¨⍳≢d)⊢7 27⍴' '
1                                                                      
  2     5         10                                                   
    3     6          11                                                
      4     7 8         12                   19                   26   
                9          13                   20                   27
                              14    16 17          21    23 24         
                                 15       18          22       25      

Однако я до сих пор не понимаю, как это работает! Я предполагаю, что контекст будет полезен для других, пытающихся оставить тезис, поэтому я собираюсь оставить остальную часть этого.

Пожалуйста, объясните, что делает (⍳≢d)@(d,¨⍳≢d)⊢7 27⍴' '

I ' Прикрепил необработанный скриншот, чтобы убедиться, что я что-то не пропустил: Hsu-dissertation-image

1 Ответ

1 голос
/ 06 марта 2020

Я рад видеть, что вы нашли ошибку "один за другим". Это происходит от Аарона Хсу, работающего с происхождением индекса 0. Если вы установите ⎕IO←0, то его код будет работать.


Некоторые операторы диади c могут принимать операнд массива давая последовательность OPERATOR operand argument, например, -@(1 2 3)(4 5 6 7). Это создает проблему, поскольку и операнд, и аргумент являются массивами, а сопоставление массивов образует новый массив с этими массивами в качестве элементов в процессе, известном как stranding . Сравните:

      (1 2 3)(4 5 6 7)
┌─────┬───┐
│1 2 3│4 5│
└─────┴───┘

Однако в случае оператора с его операндом массива мы хотим «разорвать» эту цепочку, чтобы левая часть могла выступать в качестве операнда, а правая часть - в качестве аргумента. Один из способов разорвать цепочку - применить функцию к аргументу, задав последовательность OPERATOR operand Function argument. Теперь нам на самом деле не нужно никакого преобразования аргумента, поэтому функция идентификации сделает: -@(1 2 3)⊢(4 5 6 7).


Что касается того, что (⍳≢d)@(d,¨⍳≢d)⊢7 27⍴' ' фактически:

7 27⍴' ' создает пустую матрицу.

(⍳≢d) - это индексы для вставки в указанные слоты в матрице.

@(d,¨⍳≢d) указывает в , какие места в матрице выше должны заменить существующие значения

служит исключительно для отделения (d,¨⍳≢d) от 7 27⍴' '. Код также мог быть записан как ((⍳≢d)@(d,¨⍳≢d))7 27⍴' ' с круглыми скобками, служащими для «привязки» операнда к оператору.

...