
2026/04/05 15:25
「⍋⍋ は一体何を表しているのでしょうか?(2023)」
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
要約
この記事では、APL の順位演算子 ⍋(昇順グレード)と ⍒(降順グレード)が、配列の要素をソートするためのインデックスの並べ替えとしてどのように機能するかを説明しています。
任意の配列 Y に対し、⍋ Y の i 番目の要素は昇順 TAO 順序で順位 i を持つ項目のインデックスです。 ペア表記 ⟨i, j⟩ は「項目 i が順位 j を持つ」ことを示すために使われ、⍋ Y に対しては ⟨j, i⟩、さらに ⍒ = ⌽⍋ であるため ⟨−j, i⟩(逆順位)として成り立ちます。
グレードを二度適用すると、⍋⍋ は順列ベクトルに対して恒等演算子となりますが、一般には「Rank」ベクトルを生成します。同様に ⍒⍒ は「ReverseRank」ベクトルを生成します。 4 通りの組み合わせは次のようにマッピングされます:
- ⍋⍋ – 昇順順位
- ⍋⍒ – 昇順逆順位
- ⍒⍋ – 降順順位
- ⍒⍒ – 降順逆順位
配列 Y =
l n p w b k m c x t を例に取ると、これらの結果が示されます。 すべての項目が異なる場合、Rank と ReverseRank の和は一定(総項目数 – 1)となりますが、重複があるとこの恒等性が崩れます。そのため ⍋ と ⍒ が両方必要になる理由を説明し、そうでなければ ⍋ ≡ ⌽∘⍒ という関係は常に成り立ってしまうことを示しています。
記事ではまた、これらの順位特性が Paul Mansour の AverageRank 関数などの高水準関数でどのように活用できるかも指摘し、APL における効率的なソートとランキング処理の実践的応用例を示しています。
本文
2023年8月4日投稿
数か月前、私は Jót Dọt Ti̽mes の記事をざっくりと眺めていたところで、Paul Mansour が書き上げるほぼすべての内容に恋をしました。彼の「Grade Down of Grade Up」では、挑戦的な一文が引用されています。
したがって結論としては、私たちが順列(Permutation)だけで扱う場合 ⍒⍋ は価値がなく、単なる遅い ⌽ にすぎません。順列を扱わない場合でも Adám が ⍒⍋ の意味を知らないので、やはり同様に無駄だと考えられます。
Mansour の回答は非常に興味深い特殊な応用ですが、実際には満足のいく一般的な答えがあります。ここでは一般的な配列を扱いますが、念頭に具体例を置きましょう:
⊢Y←⎕UCS 97+?10⍴26 lnpwbkmcxt ↑Y (⍋Y) l n p w b k m c x t 4 7 5 0 6 1 2 9 3 8
定義
- アイテム – 最初の軸に沿った配列要素。
ベクターの場合は要素、行列の場合は行がそれです。 - アイテム y ∈ Y のランク – Y を昇順(TAO順)で並べたときの y のインデックス。
ランクが i の場合、y は Y の中で i 番目に小さい要素です。
この定義により Grade Up 演算子は次のように機能します:⍋Y の i 番目の要素は、ランク i を持つ Y のアイテムを指し示すインデックスです。別の言い方をすると:
R は整数ベクトルで、
を並べ替えて、最初の軸に沿った部分配列(サブアレイ)を昇順に配置します。⍳1↑⍴Y
< i, j > という表記は、Y の i 番目のアイテムがランク j を持つことを意味します。
⍋Y に対しては < j, i > が得られます。すなわち ⍋ は i と j を入れ替えるだけで、⍋⍋Y は < i, j > を変えません。Y が順列ベクトルの場合、⍋⍋ は恒等演算子になりますが、一般には Rank 関数のように振る舞います。
⍒ が ⌽⍋ と等しいことから < N‑j, i >(N = ¯1+≢Y、⎕IO←0 を仮定)と書くことができます。i, j を ℤₙ 上に置くと < -j, i > となります。
↑Y (⍋⍋Y) l n p w b k m c x t 3 5 6 8 0 2 4 1 9 7
<·,·> のマイナス符号は、対応するフィールドが配列の末尾から数えていることを示すだけです。これを ReverseRank 関数と呼ぶこともできます。
四つ組み合わせ
| 演算子 | 結果ペア | 解釈 |
|---|---|---|
| ⍋⍋ | < i, j > | 昇順ランク |
| ⍋⍒ | < i, -j > | 昇順 ReverseRank |
| ⍒⍋ | <-i, j > | 降順ランク |
| ⍒⍒ | <-i, -j> | 降順 ReverseRank |
したがって、先頭の Grade は昇順か降順を選び、末尾の Grade が Rank か ReverseRank を選択します。
これを例に適用すると:
↑Y (⍋⍋Y) (⍋⍒Y) (⍒⍋Y) (⍒⍒Y) l n p w b k m c x t 3 5 6 8 0 2 4 1 9 7 6 4 3 1 9 7 5 8 0 2 7 9 1 4 2 0 8 6 5 3 2 0 8 5 7 9 1 3 4 6
整合性チェック
Rank + ReverseRank は一定であるべきです。各アイテム y ∈ Y に対して、y より小さいアイテムの数と大きいアイテムの数を足すと
≢Y - 1 になります。
(⍋∘⍋ + ⍋∘⍒) Y → 9 9 9 9 9 9 9 9 9 9 (⍒∘⍋ + ⍒∘⍒) Y → 9 9 9 9 9 9 9 9 9 9
Y のアイテムが等しい場合、Rank + ReverseRank は一定ではありません。これは両方の ⍋ と ⍒ が同じ方法で等値をランク付けするためです(方向性は関係しません)。この細かな違いが両者を有用にしています。さもなければ
(⍋≡⌽∘⍒) Y は常に真になってしまいます。この性質こそ、Paul Mansour が記事で使う AverageRank 関数の鍵となります。