FFT를 사용하여 자기 상관을 효율적으로 계산


12

내가 사용할 수있는 유일한 가속 프리미티브가 (I) FFT 인 플랫폼에서 자기 상관을 계산하려고합니다. 그래도 문제가 있습니다.

MATLAB 에서 프로토 타입을 만들었습니다 . 그러나 나는 약간 혼란스러워한다. 나는 그것이 다음과 같이 간단하게 작동한다고 가정했다 (이것은 메모리에서 왔기 때문에 약간 잘못하면 사과한다).

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

그러나 xcorr함수 를 사용할 때와 다른 결과가 나타납니다 . 이제 자동 상관 관계의 왼쪽을 얻지 않을 것으로 기대합니다 (오른쪽을 반영하므로 어쨌든 필요하지 않음). 그러나 문제는 내 오른쪽 자체가 중간 지점 주위에 반영 된 것처럼 보입니다. 이는 내가 기대하는 데이터의 약 절반을 얻는다는 것을 의미합니다.

그래서 나는 매우 간단한 일을해야한다고 확신하지만, 나는 단지 무엇을 알아낼 수 없습니다.


1
조심해. 데이터가 결정적이지 않으면 일반적으로 자기 상관 시퀀스 만 추정 할 수 있습니다 . 자기 상관 추정의 두 가지 일반적인 버전이 있습니다 : 바이어스 및 바이어스 없음. 편향되지 않은 결과는 통계적으로 편향되지 않은 자기 상관 추정치가됩니다. 그러나 고차 지연의 경우 분산이 매우 클 수 있으며, 예를 들어 자기 상관 추정치가 행렬 반전에 사용되는 경우 문제가 발생할 수 있습니다. 치우친 샘플은 통계적 치우침을 나타내지 만 분산이 적습니다 (평균 제곱 오차). 둘 다 통계적으로 일관성이 있습니다. 위의 정규화되지 않은 바이어스 추정값이 있습니다.
Bryan

답변:


16

물론 피케 네트가 맞습니다. 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.4 초 동안 실행 된 인텔 성능 기본 기반 버전과 달리 위의 방법을 사용하여 0.8 초 동안 실행되었습니다. 그 놀라운! 감사합니다
Goz

7

Matlab의 xcorr은 FFT를 계산합니다 . 여기서 은 입력 데이터의 길이입니다 (즉, 입력은 0으로 채워짐). 이것은 원형도 문제를 피합니다.N N - 12N1NN1


3

이전 답변에 대해 좀 더 자세히 설명하기 위해 길이가 신호의 자동 상관을 계산하면 크기가 (샘플링 된) 자동 상관이 발생합니다 . 사실, 그것은 무한대 여야하지만 외부의 자동 상관 은 어쨌든 같습니다 .2 N - 1 [ - ( N - 1 ) , N - 1 ] 0N2N1[(N1),N1]0

이제, 이산 푸리에 변환 (DFT)을 사용하여이를 계산하려고하고, 공식은 실제로 신호 DFT의 제곱 크기의 역 DFT입니다. 그러나 생각해보십시오. 우리가 다른 방법으로 가져 와서 자기 상관의 DFT를 계산하면 방해가되는 샘플을 잃고 싶지 않으면 크기의 스펙트럼으로 끝납니다 ! 따라서이 스펙트럼의 크기는 이어야하며, 따라서 시간 영역 신호를 최대 까지 0으로 DFT ( 포인트)를 계산 한 후 계속 진행 해야하는 이유 입니다.2 N 1 2 N 1 2 N 12N12N12N12N1

이것을 보는 또 다른 방법은 포인트 에서 DFT를 계산할 때 발생하는 상황을 분석하는 것입니다 . 이는 (연속 주파수) 이산 시간 푸리에 변환 (DTFT)을 다운 샘플링하는 것과 같습니다. 샘플링되지 않은 크기 스펙트럼 으로 크기가 이어야하는 자동 상관 관계를 검색하면 시간 앨리어싱 (원형 피케 네트에 대해 이야기하고 있음)이 발생합니다. 출력면 "2 N - 1 NN2N1N

실제로 Hilmar가 제공 한 코드도 작동합니다. 보다 큰 크기 (0의 경우 FT는 의 크기를 계산 함) 까지 패드 를 채우면 FT 를 "과도하게 샘플링"하기 때문입니다. , 여전히 "유용한"샘플을 얻습니다 (다른 샘플은 초 여야 함 ). 따라서 효율성을 높이기 위해 제로 패드에서 이면 충분합니다 ( FFT를 사용하는 경우 의 다음 제곱까지 제로 패드 를 사용하는 것이 좋습니다).N 2 N - 1 0 2 N - 1 2 N - 1N1N2N102N12N1

간단히 말해서 : 프로그래밍 언어에 맞게이 작업을 수행해야합니다.

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

또는 MATLAB에서 :

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

0

xcorr 함수 의 원하는 출력이 FFTIFFT 함수 의 적용과 유사하지 않은 주된 이유는 이러한 함수를 신호에 적용하는 동안 최종 결과가 순환 적으로 복잡하기 때문 입니다.

선형 회선 및 원형 회선의 주요 차이에서 찾을 수 있습니다 선형 및 원형 컨볼 루션 .

신호 를 초기에 제로 패딩 하고 IFFT의 최종 출력을 자르면 문제를 해결할 수 있습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.