Порт БПФ Matlab на нативную Java - PullRequest
       16

Порт БПФ Matlab на нативную Java

1 голос
/ 17 августа 2011

Я хочу перенести функцию быстрого преобразования Фурье в Matlab fft () на собственный код Java.

В качестве отправной точки я использую код JMathLib , где БПФ реализовано следующим образом:

    // given double[] x as the input signal

    n = x.length;  // assume n is a power of 2
    nu = (int)(Math.log(n)/Math.log(2));
    int n2 = n/2;
    int nu1 = nu - 1;
    double[] xre = new double[n];
    double[] xim = new double[n];
    double[] mag = new double[n2];
    double tr, ti, p, arg, c, s;
    for (int i = 0; i < n; i++) {
        xre[i] = x[i];
        xim[i] = 0.0;
    }
    int k = 0;

    for (int l = 1; l <= nu; l++) {
        while (k < n) {
            for (int i = 1; i <= n2; i++) {
                p = bitrev (k >> nu1);
                arg = 2 * (double) Math.PI * p / n;
                c = (double) Math.cos (arg);
                s = (double) Math.sin (arg);
                tr = xre[k+n2]*c + xim[k+n2]*s;
                ti = xim[k+n2]*c - xre[k+n2]*s;
                xre[k+n2] = xre[k] - tr;
                xim[k+n2] = xim[k] - ti;
                xre[k] += tr;
                xim[k] += ti;
                k++;
            }
            k += n2;
        }
        k = 0;
        nu1--;
        n2 = n2/2;
    }
    k = 0;
    int r;
    while (k < n) {
        r = bitrev (k);
        if (r > k) {
            tr = xre[k];
            ti = xim[k];
            xre[k] = xre[r];
            xim[k] = xim[r];
            xre[r] = tr;
            xim[r] = ti;
        }
        k++;
    }
    // The result 
    // -> real part stored in xre
    // -> imaginary part stored in xim

К сожалению, это не дает мне правильных результатов, когда я тестирую его, например, с массивом

double [] x = {1.0d, 5.0d, 9.0d, 13.0d};

результат в Matlab:

28,0
-8,0 - 8,0i
-8,0
-8,0 + 8,0i

результат в моей реализации:

28,0
-8,0 + 8,0i
-8,0
-8,0 - 8,0i

Обратите внимание, как знаки неправильны в сложной части.

Когда я использую более длинные, более сложные сигналы, различия между реализациями влияют также на числа. Таким образом, различия в реализации касаются не только некоторого знака «ошибка».

Мой вопрос: как я могу адаптировать мою реализацию, чтобы она была "равной" для Matlab? Или: уже есть библиотека, которая делает именно это?

1 Ответ

0 голосов
/ 11 августа 2012

Чтобы использовать Jtransforms для FFT на матрице, вам нужно выполнить fft col за col, а затем соединить их в матрицу.Вот мой код, который я сравнил с Matlab FFT

double [][] newRes = new double[samplesPerWindow*2][Matrixres.numberOfSegments];
double [] colForFFT = new double [samplesPerWindow*2];
DoubleFFT_1D fft = new DoubleFFT_1D(samplesPerWindow);

for(int y = 0; y < Matrixres.numberOfSegments; y++)
{
    //copy the original col into a col and and a col of zeros before FFT
    for(int x = 0; x < samplesPerWindow; x++)
    {
        colForFFT[x] = Matrixres.res[x][y];        
    }

    //fft on each col of the matrix
    fft.realForwardFull(colForFFT);                                                     //Y=fft(y,nfft);

    //copy the output of col*2 size into a new matrix 
    for(int x = 0; x < samplesPerWindow*2; x++)
    {
        newRes[x][y] = colForFFT[x];    
    }

}

Надеюсь, это то, что вы ищете.обратите внимание, что Jtransforms представляют комплексные числа как

array[2*k] = Re[k], array[2*k+1] = Im[k]
...