Rutkowska的位反转算法

时间:2018-09-07 16:30:44

标签: algorithm bit-manipulation fft permutation

我发现了一篇有关位反转算法的非常有趣的论文,该论文适用于就地FFT:“一种简单的位反转排列算法”,作者: 1990年的Urszula Rutkowska(doi.org/10.1016/0165-1684(91)90008-7)。

但是,她的算法G1似乎不起作用,因为第一次迭代导致该N1 = L << 1swap(a + 1, a + N1);的越界错误。我假设L表示输入向量的长度。

请,有人知道论文是否有勘误表或如何修正算法?

论文的伪代码:

G1(L)
{int     i,j,L1
         N1,N2,a,b;
unsigned k;
j=0;    L1=L-1;
N1=L<<1;N2=N1+1;
for(i=0;i<L1;i++)
{if(i<j)
    { a=i<<1;
      b=j<<1;
      swap(a,b);
      swap(a+N2,b+N2);
      swap(a+1,b+N1);
      swap(b+1,a+N1);
    }
 else
    if(i==j)
    { a=i<<1;
      swap(a+1,a+N1);
    }
 k=L>>1;
 while(k<=j){ j=j-k;
              k=k>>1;
            }
 j+=k;
 }
 i<<=1;
 swap(i+1,i+N1);
}

论文的屏幕截图:

enter image description here

1 个答案:

答案 0 :(得分:1)

坦白说,那真是乱七八糟。我必须阅读该想法的论文(针对L / 4运行Gold的算法(G),然后得出L的交换),然后将代码整理成正确的形式。这是我的最终结果。

#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

static bool is_power_of_two(int L) { return L > 0 && (L & (L - 1)) == 0; }

static void swap(int i, int j) { printf("swap %d,%d\n", i, j); }

static void G(int L) {
  assert(is_power_of_two(L));
  int j = 0;
  for (int i = 0; i < L - 1; i++) {
    if (i < j) {
      swap(i, j);
    }
    int k = L >> 1;
    while (j >= k) {
      j -= k;
      k >>= 1;
    }
    j += k;
  }
}

static void G1(int L) {
  assert(is_power_of_two(L));
  if (L < 4) {
    return;
  }
  int j = 0;
  int N1 = L >> 1;
  int N2 = N1 + 1;
  int L2 = L >> 2;
  for (int i = 0; i < L2 - 1; i++) {
    if (i < j) {
      int a = i << 1;
      int b = j << 1;
      swap(a, b);
      swap(a + N2, b + N2);
      swap(a + 1, b + N1);
      swap(b + 1, a + N1);
    } else if (i == j) {
      int a = i << 1;
      swap(a + 1, a + N1);
    }
    int k = L2 >> 1;
    while (j >= k) {
      j -= k;
      k >>= 1;
    }
    j += k;
  }
  int a = (L2 - 1) << 1;
  swap(a + 1, a + N1);
}

int main(int argc, char *argv[]) {
  assert(1 < argc);
  int L = atoi(argv[1]);
  G(L);
  putchar('\n');
  G1(L);
}