
応用数学において、ビット反転順列とは、 2のべき乗である の要素の列の順列である。これは、列の要素を からまでの数値でインデックス化し、これらの数値をそれぞれ2進表現(長さがちょうど になるようにパディング)で表し、各項目を、同じビットを逆順に表す項目にマッピングすることで定義される。
同じ順列を 2 回繰り返すと、項目の元の順序に戻るため、ビット反転順列は反転です。
この順列は、単純なインデックス計算のみを実行することで、任意のシーケンスに線形時間で適用できます。これは、低矛盾シーケンスの生成や高速フーリエ変換の評価に応用されています。
8つの文字からなるシーケンスabcdefgh を考えてみましょう。これらのインデックスは2進数で000、001、010、011、100、101、110、111です。これを反転すると、000、100、010、110、001、101、011、111となります。したがって、位置000の文字aは同じ位置(000)にマッピングされ、位置001の文字bは5番目の位置(100番目の文字)にマッピングされます。以下同様に、新しいシーケンスaecgbfdhが生成されます。この新しいシーケンスに対して同じ順列を繰り返すと、開始シーケンスに戻ります。
インデックス番号を10進数で書くと(ただし、順列の開始位置は1から始まるのが一般的だが、上述と同様に0から始まる)、 の項目のビット反転順列は次のようになる。[ 1 ]
| 順列 | ||
|---|---|---|
| 0 | 1 | 0 |
| 1 | 2 | 0 1 |
| 2 | 4 | 0 2 1 3 |
| 3 | 8 | 0 4 2 6 1 5 3 7 |
| 4 | 16 | 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15 |
この数列の各順列は、2つの数列を連結することによって生成できます。1つは前の順列の値を2倍にしたもの、もう1つは前の数列の各値を1ずつ増やしたものです。例えば、長さ4の順列0 2 1 3を2倍にすると0 4 2 6、1を加えると1 5 3 7になります。そして、これら2つの数列を連結すると、長さ8の順列0 4 2 6 1 5 3 7が得られます。[ 2 ]
基数 表現への一般化、すなわち、 、 への一般化は、各要素のインデックスの基数桁を反転させて、置換後のインデックスを得る桁反転順列である。同じ考え方は、混合基数数体系にも一般化できる。このような場合、桁反転順列は、各項目の桁と数体系の基数を同時に反転させ、反転後の各桁がその基数によって定義された範囲内に収まるようにする必要がある。[ 3 ]
ビット反転順列を一般化し、そのインデックスのバイナリ表現内で連続するビットブロックを反転する順列は、2つの等しい長さのデータシーケンスをその場でインターリーブするために使用できます。[ 4 ]
ビット反転順列には、任意長のシーケンスへの拡張が2つあります。これらの拡張は、長さが2のべき乗であるシーケンスのビット反転と一致し、シーケンス内の隣接する要素を分離してKaczmarzアルゴリズムを効率的に動作させることを目的とします。最初の拡張は効率的な順序付けと呼ばれ、[ 5 ]合成数に適用され、数を素数に分解することを基盤としています。
2つ目の拡張はEBR(拡張ビット反転)と呼ばれ、ビット反転と原理的には似ています。サイズ の配列が与えられると、EBRは範囲内の数値の順列を線形時間で配列に格納します。順列内の連続する数値は、少なくとも の位置で区切られます。[ 6 ]
ビット反転は基数2のCooley-Tukey FFTアルゴリズムにおいて最も重要であり、アルゴリズムの再帰段階はインプレースで動作し、入力または出力のビット反転を伴う。同様に、混合基数Cooley-Tukey FFTでは、混合基数桁反転が発生する。[ 7 ]
ビット反転順列は分散計算における下限値を考案するためにも使われてきた。 [ 8 ]
単位区間内の数値の低矛盾シーケンスである Van der Corput シーケンスは、ビット反転順列のインデックスを二項有理数の固定小数点 2 進表現として再解釈することによって形成されます。
ビット反転順列は、動的データ構造の下限値を求める際によく用いられる。例えば、特定の仮定のもと、これらの値を持つ任意の二分探索木において、とを含む整数を検索するコストは、これらの数値をビット反転順に検索した場合である。この上限は、アクセスごとにノードの順序を変更できるスプレー木のような木にも適用される。 [ 9 ]
高速フーリエ変換アルゴリズムの重要性から、ビット反転順列をシーケンスに適用するための効率的なアルゴリズムが数多く考案されてきた。[ 2 ]
ビット反転順列は反転であるため、要素のペアを交換するだけで(データを別の配列にコピーすることなく)、簡単にインプレースで実行できます。アルゴリズム解析で一般的に使用されるランダムアクセスマシンでは、入力順にインデックスをスキャンし、スキャン中に反転値がより大きな数値であるインデックスに遭遇するたびに交換する単純なアルゴリズムで、線形回数のデータ移動を実行できます。[ 10 ]しかし、各インデックスの反転を計算するには、一定ではないステップ数が必要になる場合があります。代替アルゴリズムでは、単純なインデックス計算のみを使用して、ビット反転順列を線形時間で実行できます。[ 11 ]ビット反転順列は計算の一部として複数回繰り返される可能性があるため、順列を表すために使用されるインデックスデータを計算するアルゴリズムのステップ(たとえば、倍加と連結法を使用する)と、この計算の結果を使用してデータを順列化するステップ(たとえば、データインデックスを順番にスキャンし、スワップされた位置が現在のインデックスよりも大きい場合はスワップを実行するか、より高度なベクトルスキャッターギャザー演算を使用する)を分離すると便利な場合があります。[ 2 ]
これらのアルゴリズムの性能にとってさらに重要なもう一つの考慮事項は、メモリ階層が実行時間に与える影響です。この影響により、メモリのブロック構造を考慮したより洗練されたアルゴリズムは、この単純なスキャンよりも高速になる可能性があります。 [ 2 ] [ 10 ]これらの手法の代替として、メモリに通常順序とビット反転順序の両方でアクセスできる特殊なコンピュータハードウェアがあります。[ 12 ]
高性能コンピューティングの分野では、ビット反転演算の性能向上に大きな注目が集まっています。アーキテクチャを考慮したアルゴリズムの開発は、キャッシュ、TLB、マルチコアプロセッサなどのハードウェアおよびシステムソフトウェアリソースを最適に活用するために不可欠です。[ 13 ]