В APL как превратить вектор (длиной n) в диагональную матрицу (nxn)?

У меня была программа J, которую я написал в 1985 году (на vax vms). Один раздел создавал диагональную матрицу из вектора.

a=(n,n)R1,nR0
b=In
a=bXa

Может быть, это не J, а APL в ascii, но эти строки работают в текущем J (с соответствующими изменениями в примитивных функциях). Но не в APL (GNU, NARS2000 или ELI). Я получаю ошибку домена в последней строке. Есть ли простой способ сделать это без зацикливания?

5 ответов

Ваш код является ASCII транслитерацией APL. Соответствующий J-код:

a=.(n,n)$1,n$0
b=.i.n
a=.b*a

Попробуйте онлайн! Однако ни один APL (на данный момент - он рассматривается для APL Dyalog) не имеет основного расширения ячейки, которое требуется в последней строке. Поэтому необходимо указать, что скаляры вектора b следует умножить на строки матрицы a используя обозначение оси скобок:

a←(n,n)⍴1,n⍴0
b←⍳n
a←b×[1]a

Попробуйте онлайн! В качестве альтернативы вы можете использовать оператор ранга (если есть):

a←(n,n)⍴1,n⍴0
b←⍳n
a←b(×⍤0 1)a

Попробуйте онлайн!

Более элегантный способ обращения к диагоналям - ⍉ с повторяющимися осями:

      n←5 ◊ z←(n,n)⍴0 ◊ (1 1⍉z)←⍳n ◊ z
1 0 0 0 0
0 2 0 0 0
0 0 3 0 0
0 0 0 4 0
0 0 0 0 5

Учитывая входной вектор Xво всех APL работает следующее (любезно предоставлено @Adám в чате):

(2⍴S)⍴((2×S)⍴1,-S←⍴X)\X

И вот место, где вы можете запустить его онлайн.

Вот мои старые, неэффективные версии, которые используют умножение и внешний продукт (последняя вызывает неэффективность):

((⍴Q)⍴X)×Q←P∘.=P←⍳⍴X
((⍴Q)⍴X)×Q←P Pρ1,(P←≢X)ρ0

Это решение работает в старом ISO Apl:

a←(n,n)⍴v,(n,n)⍴0

Или другим способом:

(n∘.=n)×(2ρρn)ρn←⍳5

должен дать вам следующее в большинстве APL

1 0 0 0 0
0 2 0 0 0
0 0 3 0 0
0 0 0 4 0
0 0 0 0 5
Другие вопросы по тегам