【发布时间】:2013-07-16 22:37:04
【问题描述】:
我正在尝试找到一种方法(惯用或其他方式)来转换看起来像的矩阵
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 个非零元素,并且必须具有与原始相同的形状。
【问题讨论】:
我正在尝试找到一种方法(惯用或其他方式)来转换看起来像的矩阵
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
创建一个如本文所述的单位矩阵: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
【讨论】:
↓(v/i)∘.=i 的价错误。左边不应该有一个论据吗?
⊂[2] 试试。感谢您的回复。
使用 Dyalog APL 版本 16.0,您现在可以使用默认函数 ⍸{~@(⊂⍺)≠⍨⍵}⍤0 2⊢ 非常简洁地编写此代码。 查看这篇文章的底部,了解如何获取矩阵列表。
它是如何工作的?
这是一个分叉,所以⍸ 和⊢ 的结果是{~@(⊂⍺)≠⍨⍵}⍤0 2 的左右参数。
⍸ 给出一个索引列表,参数中有 1
⊢ just yields 未修改的参数
{…}⍤0 2 应用以下dfn,左参数的每个rank-0子数组(即1的每个索引)作为左参数,每个rank-2 右参数的子数组(即整个矩阵)作为右参数
≠⍨⍵ 不等自拍的正确论据;给出一个形状相同但用零填充的矩阵
~@(⊂⍺) this 翻转(逻辑不)位在由左参数指示的位置
因此,对于每个 1,它都会创建一个全零层,在该层中其位置的位被翻转。
如何获取矩阵列表:
⍸{~@(⊂⍺)≠⍨⍵}¨⊂ 给出所需矩阵的列表。 Try it online!
这工作原理相同,但不是使用秩运算符对整个数组进行操作,而是使用¨⊂ 将 1 的每个索引与整个矩阵配对。
【讨论】: