据罗塞塔代码 ,有创造APL身份矩阵的两个惯用方式:
1. ID←{∘.=/⍳¨ ⍵ ⍵}
2. ID←{⍵ ⍵ ρ 1, ⍵ρ0}
如何在(2)工作? 这是为什么优于(1),它使用被认为是惯用的做法,APL外的产品?
据罗塞塔代码 ,有创造APL身份矩阵的两个惯用方式:
1. ID←{∘.=/⍳¨ ⍵ ⍵}
2. ID←{⍵ ⍵ ρ 1, ⍵ρ0}
如何在(2)工作? 这是为什么优于(1),它使用被认为是惯用的做法,APL外的产品?
如果你比较两个表达式的性能,2明显胜出:
cmpx'{∘.=/⍳¨ ⍵ ⍵}1000' '{⍵ ⍵ ⍴ 1, ⍵⍴0}1000'
{∘.=/⍳¨ ⍵ ⍵}1000 → 2.4E¯3 | 0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
* {⍵ ⍵ ⍴ 1, ⍵⍴0}1000 → 5.7E¯5 | -98% ⎕
如果你考虑一下解释具有处理两个表达式时做的,(2)也远不如工作:链状一个标量A VEC和重塑的结果,而在(1)它必须建立两个向量,建立一个外产物与相等比较。 另外,它涉及到“每一个”,这是(一些)不被视为“纯APL” ......很显然,如果你想通过这两种算法实现的想法,(2)是更漂亮,更优雅。 但是,这只是我的意见;)
1,⍵⍴0
创建由一个的向量1
,接着⍵
零。 所以,这种载体的长度为⍵+1
。
⍵ ⍵ ⍴
占地面积⍵
-by- ⍵
矩阵。 矢量的副本将适合从左到右,从上到下。 第一拷贝将覆盖整个第一行和溢流到第二行,例如,用于⍵=5
:
1 0 0 0 0
0 . . . .
. . . . .
. . . . .
. . . . .
现在,第二个副本会在与第二排一点点缩进:
. . . . .
. 1 0 0 0
0 0 . . .
. . . . .
. . . . .
依此类推,直到我们覆盖所有的矩阵。 这不一定恰当覆盖,最后一个副本可能会被切掉。 如果你想象这个过程中进一步,你可以看到, 1
-s将降落在主对角线。
我不知道为什么这应该是比使用外积的一个更好的方法。 无论是似乎罚款。
{⍵⍵⍴(⍵+ 1)↑1} ...快
{∘=⍨⍳⍵} ...好
;)