我正在尝试找到一种方法(惯用或其他方式)来转换看起来像的矩阵
0 1
0 1
0 1
分成 3 个单独的矩阵
0 1
0 0
0 0
0 0
0 1
0 0
0 0
0 0
0 1
因此,当我将它们全部放在一起时,我会得到原件。这些“子矩阵”中的每一个都必须仅具有 1 个非零元素,并且必须具有与原始元素相同的形状。
一种解决方案:
任何布尔矩阵:
m←4 3⍴?12⍴2
m
0 0 1
0 0 0
1 1 0
0 1 0
注意它的形状:
d←⍴m
d
4 3
将矩阵分解成一个向量:
v←,m
v
0 0 1 0 0 0 1 1 0 0 1 0
生成索引:
i ←⍳⍴v
i
0 1 2 3 4 5 6 7 8 9 10 11
为原始矩阵中的每个 1 构造一个矩阵:
a←d∘⍴¨↓(v/i)∘.=i
a
0 0 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0
验证结果:
↑∨/a
0 0 1
0 0 0
1 1 0
0 1 0
使用散点索引也可能有一个很好的方法,首先生成一个 3 维矩阵,然后指定 1 的位置。
是的,如上使用 v 和 d :
n←+/v
b←(n,d)⍴0
b[↓⍉(⍳n)⍪d⊤v/⍳⍴v]←1
b
0 0 1
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
1 0 0
0 0 0
0 0 0
0 0 0
0 1 0
0 0 0
0 0 0
0 0 0
0 0 0
0 1 0
∨⌿b
0 0 1
0 0 0
1 1 0
0 1 0
给定一个向量 A:
+A←3 4⍴1 0 1 0 1 0 0 0 0 1 0 1
1 0 1 0
1 0 0 0
0 1 0 1
将其分解为组件矩阵,如下所示:
+(⍴A)∘⍴¨⊂[2](,A)\B B⍴1,(B←+/,A)⍴0
1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1
这个怎么运作
首先将 1 的个数赋给 B:
B←+/,A ⍝ 5
创建一个单位矩阵,如本文所述:在 APL 中创建单位矩阵的最惯用方式:
B B⍴1,(B←+/,A)⍴0
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
解开原始矩阵:
,A ⍝ 1 0 1 0 1 0 0 0 0 1 0 1
使用 raveled 矩阵扩展单位矩阵。这将创建一个矩阵,其中每一行都是组件矩阵的分解形式:
+(,A)\B B⍴1,(B←+/,A)⍴0
1 0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 1
将该矩阵转换为行向量:
+⊂[2](,A)\B B⍴1,(B←+/,A)⍴0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1
使用 A 的原始形状(⍴A)
,创建最终矩阵:
(⍴A)∘⍴¨⊂[2](,A)\B B⍴1,(B←+/,A)⍴0
1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1