2013-07-03 18 views
1

FinnAPL Library中的第三項稱爲「由X表示的Y的子矢量的累積極大值(⌈)」,其中X是二進制向量,而Y os是數字向量。下面是它的用法的例子:APL中由X表示的累積最大值

X←1 0 0 0 1 0 0 0 
Y←9 78 3 2 50 7 69 22 
Y[A⍳⌈\A←⍋A[⍋(+\X)[A←⍋Y]]]  ⍝ output 9 78 78 78 50 50 69 69 

你可以看到從起點或從X陣列中的任何1個值開始,cumulave最大的發現Y中所有相應的數字,直到另一個1中找到X.在給出的例子中,X將數組分成兩個相等的4個數字。在第一部分中,9是最大值,直到遇到78,第二部分是最大值,直到遇到69。

這很容易理解,我可以盲目地使用它,但我想了解它是如何工作的,因爲APL習慣用法基本上是由運算符和函數組成的算法。爲了更好地理解APL,理解主人們如何將它們一起編織成如此緊湊和優雅的代碼行非常重要。

我覺得這個特殊的習語特別難理解,因爲索引嵌套了兩層深。所以我的問題是,是什麼讓這個成語打勾?

+1

我很享受你對各種APL習語的理解。這些成語非常整齊,通過它們的工作可以更深入地瞭解基礎知識,比如升級。並向下。這就是說,應該指出的是,嵌套陣列的現代APL允許直接和清晰地解決許多這些古老的習語。例如,可以簡單地完成每個分區矢量的最大掃描:ε⌈\¨X⊂Y 請注意,分區原語和enlist原語因您的APL實現而異,因此此表達式可能需要調整。 –

+0

@PaulMansour - 很高興聽到它!我發現它非常具有挑戰性,但它也是一種愉快的學習體驗。 –

+1

還需要注意的是,Dyalog的下一個版本有一個名爲「key」的新操作符,靈感來自Roger Hui和J語言,我認爲這將解決這個特殊問題,而不需要使用每個操作符,也不必將結果合併成一個簡單的向量。 –

回答

1

這個成語可以分解成更小的成語,最重要的是,它包含了從FinnAPL圖書館成語#11名爲:

級了(⍋)排序的Y子向量由X表示

使用在給定的問題的X和Y相同的值,這裏是它的使用的一個示例:

X←1 0 0 0 1 0 0 0 
Y←9 78 3 2 50 7 69 22 
A[⍋(+\X)[A←⍋Y]]    ⍝ output 4 3 1 2 6 8 5 7 

如前,X爲將所述矢量分成兩個半部,及輸出指示,對於每個位置,需要Y的哪個數字來對每個半部進行排序。因此,輸出中的4表示在第一個位置需要Y(2)的第四個數字; 3表示第2位的第3位(3); 1表示第三位的第一位數字(9);等等。因此,如果我們將此索引爲Y,我們得到:

Y[A[⍋(+\X)[A←⍋Y]]]   ⍝ output 2 3 9 78 7 22 50 69 

爲了理解這個檔次式成語中的索引,考慮的是與以下情況發生:

(+\X)[A←⍋Y]     ⍝ Sorted Cumulative Addition 

X 1 1 2 1 2 2 2 1

A←⍋Y      ⍝ 4 3 6 1 8 5 7 2 
+\X       ⍝ 1 1 1 1 2 2 2 2 
(+\X)[A←⍋Y]     ⍝ 1 1 2 1 2 2 2 1 SCA 
A[⍋(+\X)[A←⍋Y]]    ⍝ 4 3 1 2 6 8 5 7 

可以看到分類累加(SCA)應用到一個行爲:一步將它分解步作爲向左壓縮和向右壓縮的組合。與1對齊的A的所有值都移動到左側,而與2對齊的那些值向右移動。當然,如果X有更多的1,它將按照SCA結果的值所指示的順序來壓縮和定位壓縮包。例如,如果X的SCA3 3 2 1 2 2 1 1 1一樣,則最終會得到與1相對應的4位數字,隨後是對應於2的3位數字,最後是對應於3的2位數字。

您可能已經注意到,我跳過了一步,將顯示品位的效果了

(+\X)[A←⍋Y]     ⍝ 1 1 2 1 2 2 2 1 SCA 
⍋(+\X)[A←⍋Y]    ⍝ 1 2 4 8 3 5 6 7 Grade up 
A[⍋(+\X)[A←⍋Y]]    ⍝ 4 3 1 2 6 8 5 7 

壓縮和重排的效果不被SCA單獨全美基礎。它的行爲有效,如我在另一個post中所討論的。同樣在那篇文章中,我談到了排名和指數基本上是同一枚硬幣的兩面,你可以使用等級來切換兩者。因此,這就是發生在這裏:SCA被轉換爲指數適用於A,而且效果等級式排序子向量由十

指示從排序子向量累積千里馬

如前所述,對子向量進行排序的結果是一個索引,它在應用於Y時將數據壓縮爲數據包,並根據X排列這些數據包。重點在於它是一個索引,它將索引轉換成等級:

⍋A[⍋(+\X)[A←⍋Y]]   ⍝ 3 4 2 1 7 5 8 6 

這裏的問題是,爲什麼?那麼,下一步就是應用一個累積最大值,並且如果它應用於表示每個數據包內相對幅度的秩的值,那麼它纔有意義。查看這些值,可以看到4是第一組4的最大值,8是第二組的最大值。這些值對應於78和69的輸入值,這是我們想要的。這是沒有意義的(至少在這種情況下)將最大值應用於指示值的位置,所以轉換爲等級是必要的。應用累積最大值給出:

⌈\A←⍋A[⍋(+\X)[A←⍋Y]]  ⍝ 3 4 4 4 7 7 8 8 

剩下最後一步完成索引。在進行累積極大值運算後,向量值仍然表示等級,所以需要將它們轉換回索引值。爲此,使用index-of運算符。這需要在正確的參數值,並在左邊參數發現返回自己的立場:

A⍳⌈\A←⍋A[⍋(+\X)[A←⍋Y]]  ⍝ 1 2 2 2 5 5 7 7 

爲了更容易地看到:

四是在左邊第二個位置參數,所以結果在正確的參數中每4顯示一個2。該指數是完整的,所以把它應用到Y,我們得到了預期的結果:

Y[A⍳⌈\A←⍋A[⍋(+\X)[A←⍋Y]]] ⍝ 9 78 78 78 50 50 69 69 
0

我的實現:

 X←1 0 0 0 1 0 0 0 
     Y←9 78 3 2 50 7 69 22 

     ¯1+X/⍳⍴X ⍝ position 
0 4 
     (,¨¯1+X/⍳⍴X)↓¨⊂Y 
9 78 3 2 50 7 69 22 50 7 69 22 

     (1↓(X,1)/⍳⍴X,1)-X/⍳⍴X ⍝ length 
4 4 
     (,¨(1↓(X,1)/⍳⍴X,1)-X/⍳⍴X)↑¨(,¨¯1+X/⍳⍴X)↓¨⊂Y 
9 78 3 2 50 7 69 22 

     ⌈\¨(,¨(1↓(X,1)/⍳⍴X,1)-X/⍳⍴X)↑¨(,¨¯1+X/⍳⍴X)↓¨⊂Y 
9 78 78 78 50 50 69 69 
     ∊⌈\¨(,¨(1↓(X,1)/⍳⍴X,1)-X/⍳⍴X)↑¨(,¨¯1+X/⍳⍴X)↓¨⊂Y 
9 78 78 78 50 50 69 69 

有一個愉快的一天。