Matrix 矩阵操作技巧?
我试图找到一种方法(惯用的或其他的)来转换一个矩阵Matrix 矩阵操作技巧?,matrix,apl,Matrix,Apl,我试图找到一种方法(惯用的或其他的)来转换一个矩阵 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 所以当我或所有人在一起时,我得到了原件。 每个“子矩阵”必须只有一个非零元素,并且必须具有与原始矩阵相同的形状。一个解决方案: 任意布尔矩阵: m←4 3⍴?12⍴2 m 0 0 1 0 0 0 1 1 0 0 1 0 注意它的形状: d←⍴m d 4 3 将矩阵展开为向量:
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
所以当我或所有人在一起时,我得到了原件。
每个“子矩阵”必须只有一个非零元素,并且必须具有与原始矩阵相同的形状。一个解决方案:
任意布尔矩阵:
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 ⍝ 1 0 1 0 1 0 0 0 0 1 0 1
验证结果:
↑∨/a
0 0 1
0 0 0
1 1 0
0 1 0
也许有一个很好的方法可以使用散点索引来实现这一点,首先生成一个三维矩阵,然后指定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
创建一个身份矩阵,如本文所述:
拉威尔原始矩阵:
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 ⍝ 1 0 1 0 1 0 0 0 0 1 0 1
使用展开矩阵展开单位矩阵。它创建一个矩阵,其中每一行都是组件矩阵的展开形式:
+(,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)∘⍴¨⊂[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
将该矩阵转换为行的向量:
+⊂[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)\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)∘⍴¨⊂[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
使用Dyalog APL 16.0版,您现在可以使用默认函数⍸{~@(⊂⍺)≠⍨⍵}⍤0 2⊢代码>。有关如何获取矩阵列表,请参见本文底部
它是如何工作的?
它是一个fork,其中,⍸代码>和的⊢
是{~@(⊂⍺)≠⍨⍵}⍤0 2
⍸代码> 给出参数中有1的索引列表
⊢代码> justyields未经修改的参数
{
..}⍤0 2
应用以下dfn,将左变元的每个秩-0子数组(即1的每个索引)作为左变元,将右变元的每个秩-2子数组(即整个矩阵)作为右变元
<代码>≠⍨⍵代码> 右参数的不等自拍;给出一个形状相同但充满零的矩阵
<代码>~@(⊂⍺)代码> 这将翻转(逻辑非)位于左参数所指示位置的位
因此,对于每个1,它创建一个全零层,在该层中,其位置的位被翻转
如何获取矩阵列表:
⍸{~@(⊂⍺)≠⍨⍵}¨⊂代码>提供所需矩阵的列表
其工作原理相同,但我们使用,而不是使用秩运算符对整个数组进行操作⊂
将1的每个索引与整个矩阵配对。非常好的解决方案!我喜欢这一个,因为它只是重塑1和0的形状,并且除了计算1的数量之外,不需要整数或索引。我曾认为一定有某种方法可以这样做,并玩弄了扩展,但生成标识矩阵却没有发生我。真的很好!@PaulMansour-谢谢你,Paul!我也喜欢你的解决方案,但我有点被它难住了,因为我在↓(五/一)∘.=我
。那左边不应该有一个参数吗?一元向下箭头被称为“拆分”,它的作用与⊂[2] ,将矩阵转换为向量向量。可能并非在所有APL实现中都可用。@PaulMansour-这可能是因为我使用的是NARS2000。我将尝试使用⊂[2]
。感谢您的回复。