В 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
Или другим способом:
(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