APL:矩阵操作技巧?

时间:2013-07-16 22:37:04

标签: 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

所以,当我或他们所有人在一起时,我得到原件。 这些“子矩阵”中的每一个都必须只有1个非零元素,并且必须具有与原始元素相同的形状。

3 个答案:

答案 0 :(得分:3)

一个解决方案:

任何布尔矩阵:

      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

答案 1 :(得分:3)

给出一个向量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

创建一个标识矩阵,如本文所述:The most idiomatic way of creating identity matrix in 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

答案 2 :(得分:1)

使用 Dyalog APL 16.0版,您现在可以使用隐性函数⍸{~@(⊂⍺)≠⍨⍵}⍤0 2⊢非常简洁地编写。 请参阅本文的底部,了解如何获取矩阵列表。

Try it online!

它是如何运作的?

这是一个分支,因此的结果是{~@(⊂⍺)≠⍨⍵}⍤0 2的左右参数。

列出索引参数中有1个

yield 是未修改的参数

{ ... }⍤0 2将以下dfn应用于左参数的每个 rank-0 子数组(即1的每个索引)作为左参数,每个 rank-2 右参数的子数组(即整个矩阵)作为右参数

正确论据的

≠⍨⍵ 不平等自拍 ;给出一个形状相同但用零填充的矩阵

~@(⊂⍺)这会在左侧参数

指示的位置翻转(逻辑)位

因此,对于每个1,它会创建一个全零层,其中位置的位被翻转。

如何获取矩阵列表:

⍸{~@(⊂⍺)≠⍨⍵}¨⊂给出了所需矩阵的列表。 Try it online!

这同样有效,但我们不是使用秩运算符来操作整个数组,而是使用¨⊂将1的每个索引与整个矩阵配对。