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] 
。感谢您的回复。