FFT (고속 푸리에 변환) 는 DFT 의 특수한 경우로, 연산점의 수가 2 의 정수 제곱일 때 수행되는 연산입니다 (0 으로 보완하지 않음).
FFT 계산 원리 및 흐름도:
원칙: FFT 의 계산에서는 점 수가 0 으로 채워지지 않을 경우 점 수가 2 의 정수 제곱이어야 합니다. 예를 들어, {2,3,5,8,4} 를 계산하는 16 포인트 FFT 는 11 개의 0 을 채운 후 계산해야 합니다. FFT 계산은 나비 연산을 사용하며, 나비 연산에서 변화하는 법칙은 W(N, P) 에서 파생됩니다. 여기서 N 은 FFT 계산 포인트, J 는 아래쪽 각도의 값입니다.
L = 1 일 때 W(N, p) = W(N, j J) = W(2^L, j) 여기서 J = 0;;
L = 2 인 경우 W(N, p) = W(N, j J) = W(2^L, j) 여기서 j = 0,1;
L = 3 일 때 W(N, p) = W(N, j J) = W(2^L, j) 여기서 j = 0,1,2,3;
따라서 W(N, p p) = W(2^L, j) 여기서 J = 0, 1, ..., 2 (l-1)-1
또 2 l = 2 m * 2 (l-m) = n * 2 (l-m) 로 인해 n 은 2 의 정수 제곱인 n = 2 m,
입니다W(N, p p) = W(2^L, J) = W(N * 2 (l-m), j) = w (n, j * 2 (m-;
따라서 p = j * 2 (m-l), 여기서 J = 0, 1, ..., 2 (l-1)-1, j 통과가 끝났지만 계산점 수가 n 이 충분하지 않은 경우 j = j+
순서도:
구현 코드:/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = *? 방법 이름: FFT? *? 방법 기능: 배열의 FFT 를 계산하고 나비 연산을 사용합니까? *? *? 변수 이름:? *yVector? -응? 원시 데이터? * 길이-? 원시 데이터 길이? *N? -응? FFT 계산 포인트? *fftYreal-? FFT 이후 실제 부서? *fftYImg? -응? FFT 뒤의 허부? *? *? 반환 값: 성공 여부를 나타내는 플래그, 성공적으로 true 를 반환하면 false 를 반환합니다. * = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
+? (bool) FFT: (float float? *)yVector? Andoriginallength: (nsinteger) length? Andftcount: (nsinteger) n? Andfftreal: (float float? *)fftYReal? Andftyimg: (float float? *)fftYImg
{
//? 계산 시 2 의 정수 전력 점 계산 확인
NSInteger? N1? =? [셀프? Nextnumofpow2: n];
//? FFT 연산의 성공 여부를 정의하는 플래그
볼? IsFFTOK? =? False;;
//? 계산된 점 수가 2 의 정수 제곱인지 여부를 결정합니다
If? (n? ! =? N1)
{
//? 2 의 정수 제곱이 아니라 DFT
를 직접 계산합니다IsFFTOK? =? [셀프? Dft:yVector? AndOriginalLength:length? Andftcount: n? AndFFTReal:fftYReal? Andftyimg: fftyimg];
//? 성공 플래그 반환
리튼? IsFFTOK;;
}
//? 점 숫자 2 의 정수 제곱을 계산하는 경우 FFT 를 사용하여 다음과 같이 계산합니다
//? 변수 정의
플로트? Yvectorn [n1]; -응? //? N 점 연산의 원시 데이터
NSInteger? PowOfN? =? Log2 (n1); //? N? =? 최대 연산 시리즈 (공식에서 m 으로 표시)
를 표시하는 2^powOfNNSInteger? 레벨? =? 1; //? 연산 시리즈 (첫 번째 연산), 최대 powOfN, 초기 값은 첫 번째 단계 연산 (공식에서 l 로 표시됨)
NSInteger? LineNum;; //? 행 번호, 역순으로 정렬된 나비 연산 행 번호 (공식에서 k 로 표시됨)
플로트? Inverseordery [n1]; //? YVector 역방향 x
NSInteger? DistanceLine? =? 1; -응? //? 행 간격, 레벨 연산은 각 나비의 두 노드 거리를 dis 로 계산합니다
TanceLine? =? 2 (l-1) (공식에서 b 로 표시)
NSInteger? P; //? 회전 계수의 각도, 회전 계수는? W(N,? P), p? =? J * 2 (m-l)
NSInteger? J; //? 회전 계수의 각도, 회전 계수는? W (2 l,? J), j? =? 0,? 1,? 2, ...,? 2 (l-1)? -응? 1? =? DistanceLine? -응? 1
플로트? RealTemp,? ImgTemp,? TwiddleReal,? TwiddleImg,? 트위터,? TwiddleTemp? =? Pi _ x _ 2/n1;
NSInteger? N_4? =? N1/4;
//? 포인트 수가 FFT 연산 포인트 수에 충분한지 확인
If? -길이? Lt; =? N1)
{
//? N 이 길이 이상이면 먼저 yVector 를 모두 할당
For? (NSInteger? I? =? 0; -응? I? Lt; -응? 길이; -응? I++)
{
YVectorN[i]? =? Y vector [I];
}
If? -길이? Lt; -응? N1)
{
//? 만약? N? Gt; -응? 길이? 뒤에 0 채우기
For? (NSInteger? I? =? 길이; -응? I? Lt; -응? N1; -응? I++)
{
YVectorN[i]? =? 0.0;
}
}
}
Else
{
//? 만약? N? Lt; -응? 길이? 해당 길이의 데이터를 가로채서 연산
For? (NSInteger? I? =? 0; -응? I? Lt; -응? N1; -응? I++)
{
YVectorN[i]? =? Y vector [I];
}
}
//? 역순서 메서드 호출
[셀프? InverseOrder:yVectorN? Andn: n1? Andinverseordervector: inverseordery];
//? 초기값
For? (NSInteger? I? =? 0; -응? I? Lt; -응? N1; -응? I++)
{
FftYReal[i]? =? Inverseordery [I];
FftYImg[i]? =? 0.0;
}
//? 3 층 순환
//? 레이어 3 (가장 마일): 동일한 회전 계수의 나비 연산 완료
//? 레이어 2 (중간): 2 레벨
스텝핑으로 회전 계수 변경을 완료합니다//? 첫 번째 레이어 (가장 바깥쪽): m 회 반복 프로세스를 완료하여 x(k) 를 계산합니까? =? A0(k),? A1(k), ..., Am(k)? =
-응? X(k)
//? 1 층 루프
윌? (레벨? Lt; =? PowOfN)
{
DistanceLine? =? Powf(2,? 레벨? -응? 1); -응? //? 초기 조건? DistanceLine? =? 2 (레벨-1)
J? =? 0;
NSInteger? Pow2_Level? =? DistanceLine? *? 2; -응? //? 2 레벨
NSInteger? Pow2_NSubL? =? N1/pow2 _ level; //? 2 (m-l)
//? 레이어 2 루프
윌? (j? Lt; -응? DistanceLine)
{
P? =? J? *? Pow2_NSubL;;
리네넘? =? J;
NSInteger? StepCount? =? 0; -응? //? J 연산의 스텝 수
//? 회전 계수 찾기
If? (p==0)
{
TwiddleReal? =? 1.0;
TwiddleImg? =? 0.0;
}
엘시? If? (p? = =? N_4)
{
TwiddleReal? =? 0.0;
TwiddleImg? =? -1.0;
}
Else
{
//? 오일러 공식에서 θ 계산
TwiddleTheta? =? TwiddleTemp? *? P;
//? 복수형의 실부와 허부 계산
TwiddleReal? =? Cos (트위터);
TwiddleImg? =? -11 이요? *? 신 (twiddle theta);
}
//? 레이어 3 루프
윌? (리눅스? Lt; -응? N1)
{
//? 아래 첨자 계산
NSInteger? FootNum? =? 리네넘? +? DistanceLine;;
/*----------------? *? 복수연산으로 각 등급의 각 행에 대한 나비 연산 결과를 계산합니까? *? X(k)? =? X(k)? +? X(k+B)*W(N, p)? *? X(k+B)? =? X(k)? -응? X(k+B)*W(N, p)? *-----------------*/
RealTemp? =? FftYReal[footNum]? *? TwiddleReal? -응? FftYImg[footNum]? *? TwiddleImg;;
ImgTemp=? FftYReal[footNum]? *? Twi
DdleImg? +? FftYImg[footNum]? *? TwiddleReal;;
//? 계산된 실제 부분과 가상 부분을 반환 배열에 보관하십시오
FftYReal[footNum]? =? FftYReal[lineNum]? -응? RealTemp;;
FftYImg[footNum]=? FftYImg[lineNum]? -응? ImgTemp;;
FftYReal[lineNum]? =? FftYReal[lineNum]? +? RealTemp;;
FftYImg[lineNum]=? FftYImg[lineNum]? +? ImgTemp;;
StepCount? +=? Pow2_Level;;
//? 줄 번호 변경
리네넘? =? J? +? StepCount;;
}
//? 회전 계수의 각도 변환은 회전 계수 변경의 효과를 얻습니다
J++;+;
}
//? 연산 시리즈 더하기 1
레벨++;
}
IsFFTOK? =? 참;
리튼? IsFFTOK;;
}