Tính toán tự động hiệu quả bằng cách sử dụng FFT


12

Tôi đang cố gắng tính toán tự động tương quan trên một nền tảng nơi mà nguyên thủy tăng tốc duy nhất tôi có sẵn là (I) FFT. Tôi đang có một vấn đề mặc dù.

Tôi đã tạo mẫu cho nó trong MATLAB . Tôi, tuy nhiên, hơi bối rối. Tôi giả định rằng nó hoạt động đơn giản như sau (đây là từ bộ nhớ nên xin lỗi nếu tôi hiểu sai một chút).

 autocorr = ifft( complex( abs( fft( inputData ) ), 0 ) )

Tuy nhiên tôi nhận được một kết quả khác với việc tôi sử dụng xcorrhàm. Bây giờ tôi hoàn toàn mong đợi không có được phía bên trái của tương quan tự động (vì đó là sự phản ánh của phía bên tay phải và do đó dù sao cũng không cần thiết). Tuy nhiên, vấn đề là phía bên tay phải của tôi dường như là chính nó, được phản ánh xung quanh điểm giữa chừng. Điều đó có nghĩa là tôi nhận được khoảng một nửa lượng dữ liệu mà tôi mong đợi.

Vì vậy, tôi chắc chắn rằng tôi phải làm điều gì đó rất đơn giản sai, nhưng tôi không thể tìm ra điều gì.


1
Hãy cẩn thận. Trừ khi dữ liệu là xác định, chúng ta thường chỉ có thể ước tính trình tự tự tương quan. Có hai phiên bản phổ biến của ước tính tự tương quan: thiên vị và không thiên vị. Kết quả không thiên vị trong ước tính tự tương quan được thống kê không thiên vị. Tuy nhiên, phương sai có thể rất lớn đối với độ trễ bậc cao, dẫn đến các vấn đề nếu ước tính tự tương quan được sử dụng trong nghịch đảo ma trận chẳng hạn. Các mẫu thiên vị biểu hiện sai lệch thống kê nhưng với ít phương sai hơn (và sai số trung bình bình phương). Cả hai đều thống kê thống kê. Bạn có một ước tính sai lệch không chuẩn hóa ở trên.
Bryan

Câu trả lời:


16

pichenettes là đúng, tất nhiên. FFT thực hiện tích chập tuần hoàn trong khi xcorr () dựa trên tích chập tuyến tính. Ngoài ra, bạn cũng cần bình phương giá trị tuyệt đối trong miền tần số. Đây là một đoạn mã xử lý tất cả các phần đệm bằng 0, dịch chuyển và cắt bớt.

%% Cross correlation through a FFT
n = 1024;
x = randn(n,1);
% cross correlation reference
xref = xcorr(x,x);

%FFT method based on zero padding
fx = fft([x; zeros(n,1)]); % zero pad and FFT
x2 = ifft(fx.*conj(fx)); % abs()^2 and IFFT
% circulate to get the peak in the middle and drop one
% excess zero to get to 2*n-1 samples
x2 = [x2(n+2:end); x2(1:n)];
% calculate the error
d = x2-xref; % difference, this is actually zero
fprintf('Max error = %6.2f\n',max(abs(d)));

Wow mà làm việc một người đẹp. Phiên bản C thẳng (Luồng đơn, không SIMD) của trình theo dõi độ cao của tôi chạy trong 0,8 giây bằng phương pháp trên, trái ngược với phiên bản gốc dựa trên hiệu năng intel chạy trong 0,4 giây. Thật ngạc nhiên! Cảm ơn
Goz


3

N2N-1[-(N-1),N-1]0

2N-12N-12N-12N-1

N2N-1N

N-1N2N-102N-12N-1

Tóm lại: bạn nên làm điều này (để thích nghi với ngôn ngữ lập trình của bạn):

autocorr = ifft( complex( abs(fft(inputData, n=2*N-1))**2, 0 ) )

Hoặc trong MATLAB:

autocorr = ifft(abs(fft(inputData, 2*N-1)).^2)

0

Lý do chính khiến đầu ra của hàm xcorr mong muốn không giống với ứng dụng của hàm FFTIFFT là bởi vì trong khi áp dụng các hàm này để báo hiệu kết quả cuối cùng bị sai lệch theo vòng tròn .

Sự khác biệt chính giữa Convolution tuyến tính và Convolution tròn có thể được tìm thấy trong Convolution tuyến tính và tròn .

Vấn đề có thể được giải quyết bằng cách ban đầu không đệm tín hiệu và cắt đầu ra cuối cùng của IFFT .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.