Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bit-reversal algorithm by Rutkowska

I found a very interesting paper about bit-reversal algorithm suitable for in-place FFT: "A simple algorithm for the bit-reversal permutation" by Urszula Rutkowska from 1990 (doi.org/10.1016/0165-1684(91)90008-7).

However, her algorithm G1 does not appear to work as the very first iteration results in out-of-bounds error for that N1 = L << 1 and swap(a + 1, a + N1);. I assume L means the length of input vector.

Please, does anyone know if there was any errata for the paper or how to fix the algorithm?

The paper's pseudocode:

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);
}

Screenshot of the paper:

enter image description here

like image 435
minmax Avatar asked Sep 07 '18 16:09

minmax


1 Answers

It was pretty garbled, frankly. I had to read the paper for the idea (run Gold's algorithm (G) for L/4 and then derive the swaps for L) and then sort of massage the code into the right form. Here's my final result.

#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);
}
like image 103
David Eisenstat Avatar answered Sep 29 '22 06:09

David Eisenstat