การคำนวณค่าสัมพันธ์อัตโนมัติอย่างมีประสิทธิภาพโดยใช้ FFT


12

ฉันกำลังพยายามคำนวณความสัมพันธ์อัตโนมัติบนแพลตฟอร์มที่มีการเร่งความเร็วแบบดั้งเดิมที่ฉันมีอยู่คือ (I) FFT ฉันมีปัญหาว่า

ฉันเป็นต้นแบบในMATLAB อย่างไรก็ตามฉันสับสนเล็กน้อย ฉันคิดว่ามันใช้งานได้ง่ายดังต่อไปนี้ (มาจากความทรงจำดังนั้นขอโทษถ้าฉันทำผิดเล็กน้อย)

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

อย่างไรก็ตามฉันได้รับผลลัพธ์ที่แตกต่างจากการใช้xcorrฟังก์ชั่น ตอนนี้ฉันคาดหวังอย่างเต็มที่ว่าจะไม่ได้รับทางด้านซ้ายของความสัมพันธ์แบบอัตโนมัติ (เนื่องจากเป็นภาพสะท้อนของทางด้านขวามือและไม่จำเป็นต้องมีอยู่แล้ว) อย่างไรก็ตามปัญหาคือด้านขวามือของฉันดูเหมือนจะสะท้อนตัวเองรอบจุดกึ่งกลาง ซึ่งหมายความว่าฉันได้รับข้อมูลประมาณครึ่งหนึ่งอย่างที่ฉันคาดไว้

ดังนั้นฉันแน่ใจว่าฉันจะต้องทำสิ่งที่ผิดง่าย ๆ แต่ฉันก็ไม่สามารถหาอะไรได้


1
ระวัง. ยกเว้นว่าข้อมูลนั้นถูกกำหนดค่าไว้โดยทั่วไปเราสามารถประมาณค่าลำดับความสัมพันธ์อัตโนมัติเท่านั้น มีการประมาณค่าแบบอัตโนมัติสองเวอร์ชันทั่วไป: เอนเอียงและไม่เอนเอียง ผลลัพธ์ที่ไม่เอนเอียงในการประมาณค่าอัตโนมัติที่ไม่มีอคติทางสถิติ อย่างไรก็ตามความแปรปรวนอาจมีขนาดใหญ่มากสำหรับคำสั่งซื้อที่ล่าช้าซึ่งนำไปสู่ปัญหาหากมีการใช้การประมาณค่าความสัมพันธ์แบบอัตโนมัติในเมทริกซ์ผกผัน ตัวอย่างลำเอียงมีอคติเชิงสถิติ แต่มีความแปรปรวนน้อยกว่า (และค่าคลาดเคลื่อนกำลังสองเฉลี่ย) ทั้งสองมีความสอดคล้องทางสถิติ คุณมีค่าประมาณเอนเอียงผิดปกติด้านบน
ไบรอัน

คำตอบ:


16

pichenettes ถูกต้องแน่นอน FFT ใช้การบิดแบบวนวนในขณะที่ xcorr () ขึ้นอยู่กับการบิดเชิงเส้น นอกจากนี้คุณต้องกำหนดค่าสัมบูรณ์ในโดเมนความถี่ด้วย นี่คือข้อมูลโค้ดที่จัดการการเติมเต็มศูนย์เลื่อนและตัดทอน

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

ว้าวที่ทำงานงาม เวอร์ชั่น C แบบตรง (เธรดเดี่ยวไม่มี SIMD) ของตัวติดตามพิชช์ของฉันวิ่งใน 0.8 วินาทีโดยใช้วิธีการด้านบนซึ่งต่างจากรุ่นดั้งเดิมที่อิงกับประสิทธิภาพของ Intel ซึ่งวิ่งใน 0.4 วินาที ที่น่าตื่นตาตื่นใจ! ขอบคุณ
Goz

7

xcorr ของ Matlab คำนวณ FFT โดยที่คือความยาวของข้อมูลอินพุต (เช่นอินพุตถูกเติมด้วยศูนย์ ) นี่เป็นการหลีกเลี่ยงปัญหาเวียนN N - 12N1NN1


3

N2N1[(N1),N1]0

2N12N12N12N1

N2N1N

N1N2N102N12N1

กล่าวโดยย่อ: คุณควรทำสิ่งนี้ (เพื่อปรับให้เข้ากับภาษาการเขียนโปรแกรมของคุณ):

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

หรือใน MATLAB:

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

0

เหตุผลหลักสำหรับการส่งออกที่ต้องการของxcorrฟังก์ชั่นที่จะไม่คล้ายกับที่ของการประยุกต์ใช้FFTและIFFTฟังก์ชั่นเป็นเพราะในขณะที่ใช้ฟังก์ชั่นเหล่านี้เป็นสัญญาณผลสุดท้ายจะซับซ้อน circularly

ความแตกต่างที่สำคัญระหว่างการเชิงเส้นบิดและ Circular บิดสามารถพบได้ในเชิงเส้นและ Circular บิด

ปัญหาที่เกิดขึ้นสามารถแก้ไขได้โดยในขั้นต้นเป็นศูนย์ paddingสัญญาณและตัดทอนผลลัพธ์สุดท้ายของIFFT

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.