((⍴X)⍴⍋⍋X⍳X,Y)⍳(⍴Y)⍴⍋⍋X⍳Y,X ⍝ idiom #1
((⍋X⍳X,Y)⍳⍳⍴X)⍳(⍋X⍳Y,X)⍳⍳⍴Y ⍝ idiom #5
这种双重性背后是否有任何重要的印记?
旁注:
APL中对身份的强调一直是APL从一开始就具有特色的特征之一。 APL的创始人Kenneth Iverson说:
“身份是两个不同表达之间的等价物。虽然身份通常只被认为是数学分析的工具,但它们可以成为一种重要的实用工具,用于简化和修改用于定义函数的表达式。“
答案 0 :(得分:4)
这些习语有一些共同之处。两者的最后一步是操作索引,它们都使用一种镜像串联策略,也许最重要的是,左右参数的输出对于两者都是相同的。这简化了对身份的搜索,因为我们可以将#1的正确参数与#5的正确参数进行比较:
(⍴Y)⍴⍋⍋X⍳Y,X ⍝ right arg #1
(⍋X⍳Y,X)⍳⍳⍴Y ⍝ right arg #5
可以简化搜索的另一件事是删除或修改截断输出的任何内容,因为两个参数的输出相同而不截断。习语#1使用(⍴Y)⍴
将其截断为Y
的长度,而习语#5中右参数的长度取决于Y
中⍳⍴Y
的长度。在第一种情况下,可以删除截断,在第二种情况下,可以将其修改为Y,X
的全长:
⍋⍋X⍳Y,X ⍝ #1
(⍋X⍳Y,X)⍳⍳⍴Y,X ⍝ #5
鉴于两个表达式都包含⍋X⍳Y,X
,我们将其分配给变量A ← ⍋X⍳Y,X
并简化。但是,重要的是要指出我们现在只有在A是置换向量的情况下才能应用这个身份,我稍后会详细讨论。与此同时,我们有这样的身份:
⍋A ←→ A⍳⍳⍴Y,X
由于'Y,X'在该表达式中没有任何作用,除了提供向量长度,并且因为该长度等于'A',所以可以将身份简化为其最终形式:
⍋A ←→ A⍳⍳⍴A, where A is a permutation vector
这很有道理。标识左侧的升级运算符返回索引值,如果按升序排序,则A
的每个值都将具有该值。右侧的index-of运算符返回A中的索引,其中⍳⍴A
的升序值位于此处。例如:
5 2 1 4 3 ⍝ A←5 2 1 4 3
3 2 5 4 1 ⍝ ⍋A
5 2 1 4 3 ⍝ A←5 2 1 4 3
1 2 3 4 5 ⍝ ⍳⍴A
3 2 5 4 1 ⍝ A⍳⍳⍴A
查看最后两行,1在A中有3的索引,2有2,3有5,4有4,而最后的5有1的索引。这是有道理的,因为这几乎是由定义等级运算符的作用。
置换向量
如前所述,只有当A是置换向量时,此身份才有效。在他的论文作为思想工具的符号中,Kenneth Iverson定义了一个置换向量:“一个向量P,其元素是其索引的一些排列(即,^ / 1 = + /P∘。= ⍳⍴P)将被称为置换向量。“看一些成语本身,你可以看到这个想法以各种方式表示:
Y[⍋Y]^.=X[⍋X] #6 permutations of each other
X^.=⍋⍋X #7 test if permutation vector
X[⍋X]^.=⍳⍴X #29 test if permutation vector
⍋X #48 Inverting a permutation
X⍳⍳⍴X #212 Inverting a permutation
^/1=+⌿X∘.=⍳⍴X #281 test if permutation vector
^/(⍳⍴X)∊X #454 test if permutation vector
A←⍳⍴X ⋄ A[X]←A ⋄ A #654 Inverting a permutation
在成语#7中,表达式的右侧是升序的基数数字成语,我在另一个post中讨论过,在那篇文章中,我谈到了升级算子来回切换的事实在两个州之间,排名和指数,以便我们有以下两个身份:
⍋X ←→ ⍋⍋⍋X ←→ ⍋⍋⍋⍋⍋X ...
⍋⍋X ←→ ⍋⍋⍋⍋X ←→ ⍋⍋⍋⍋⍋⍋X ...
第二个身份可以扩展如下,如果X是一个排列向量,因为成语#7建立:
X ←→ ⍋⍋X ←→ ⍋⍋⍋⍋X ←→ ⍋⍋⍋⍋⍋⍋X …
我们知道,升级运算符会将所有数字从1返回到参数中的值数。再次应用等级向上运算符,您将以相同的顺序获得完全相同的向量。因此,成语#7只是说排列向量是包含从1到某个其他值的所有数字的一次且仅一次。 (这假设1被设置为第一个索引值。)
上面成语列表中另一个有趣的事情是成语#48和#212是答案中讨论的身份的左右两边:
⍋A ←→ A⍳⍳⍴Y,X