Thứ tự tần số MATLAB FFT


9

Wikibook này nói rằng đầu ra của MATLAB FFTtương ứng với các wavenumbers được đặt hàng là:

k={0,1,...,n2,n2+1,n2+2,...,1}

Tuy nhiên, trong các mã ví dụ trên cùng một trang, các wavenumbers được mã hóa là

k = [0:n/2-1 0 -n/2+1:-1];

tương tự như đầu tiên, nhưng với -wavenumber ("wavemnumber tối đa") được thay thế bằng 0 . Có vẻ lạ khi họ sẽ bao gồm 0 lần.n/200

Có vẻ như thứ tự đúng là cần thiết để lấy đạo hàm thông qua các biến đổi Fourier, như được mô tả trong wikibook. Điều nào trong số này là đúng và MATLAB có tài liệu này ở bất cứ đâu không?


3
nhìn vào chức năng frafthift. Nó sẽ lấy đầu ra của fft và sắp xếp lại nó từ [-n / 2 + 1: n / 2-1], điều này sẽ giúp ích cho sự nhầm lẫn của bạn.
Godric Seer

Đây không phải là thứ mà bạn có thể nhanh chóng tự kiểm tra sao? Việc tìm ra thứ tự đầu ra của FFT có vẻ dễ xác định với một vài thử nghiệm.
Federico Poloni

Câu trả lời:


4

Tôi muốn mở rộng nhận xét của mình và làm lại ví dụ mà bạn tham chiếu theo cách dễ hiểu hơn bản gốc và để giải thích tại sao ffttrả về các hệ số theo cách nó làm.

Để tham khảo, phần fft của ví dụ là:

Nx = size(x,2);
k = 2*pi/(b-a)*[0:Nx/2-1 0 -Nx/2+1:-1];
dFdx = ifft(1i*k.*fft(f));
d2Fdx2 = ifft(-k.^2.*fft(f));

Tôi đã thêm một phần khác của mã ngay bên dưới nó:

Nx = size(x,2);
k = 2*pi/(b-a)*(-Nx/2:Nx/2-1);
dFdxp = ifft(ifftshift(1i*k.*fftshift(fft(f))));
d2Fdx2p = ifft(ifftshift(-k.^2.*fftshift(fft(f))));

và bọc cả hai đoạn mã trong một tic; tocthời gian suy nghĩ. Trong định dạng dễ đọc hơn, phương thức thứ hai sử dụng:

ckf = fftshift(fft(f));
ckdf = 1i*k.*ckf;
df = ifft(ifftshift(ckdf));

Sự khác biệt đầu tiên là ví dụ thứ hai có trực quan hơn nhiều k. Đây là ưu điểm chính của ví dụ thứ hai, vì k bây giờ ở dạng mà chúng ta nghĩ về chúng. Trong dòng thứ hai và thứ ba tôi phải thêm fftshiftxung quanh cuộc gọi đến fft, sau đó một cuộc gọi đến ifftshifttrực tiếp bên trong cuộc gọi đến ifft. Các hàm bổ sung này gọi sắp xếp lại các hệ số từ những gì cần thiết cho máy tính để làm việc với chúng theo cách con người thường nghĩ về chúng.

Vấn đề với ví dụ thứ hai, là trong khi kchúng ta trực quan hơn, điều này để lại các ma trận nội bộ để giải quyết và đảo ngược ffttrong các hình thức không thuận lợi. Vì vậy, hoặc chúng ta phải chuyển thứ tự với các cuộc gọi đến fftswitchifftswitchhoặc nó phải được mã hóa cứng vào các fftchức năng. Điều này ít bị lỗi từ người dùng (giả sử họ không quen với các hoạt động của fft, như nhiều người), nhưng bạn phải trả giá trong thời gian chạy.

Như tôi đã nói trước đây, tôi đã thêm các cuộc gọi thời gian xung quanh hai khối để so sánh và chạy cho nhiều N. Kết quả thời gian là:

N =     1000,  Ex1 = 0.000222 s,   Ex2 = 0.007072 s
N =    10000,  Ex1 = 0.001576 s,   Ex2 = 0.003506 s
N =   100000,  Ex1 = 0.023857 s,   Ex2 = 0.034051 s
N =  1000000,  Ex1 = 0.213816 s,   Ex2 = 0.406250 s
N = 10000000,  Ex1 = 4.555143 s,   Ex2 = 7.102348 s

Như bạn có thể thấy, hành động chuyển đổi các giá trị qua lại làm chậm quá trình một cách đáng kể, đặc biệt là ở mức N thấp (nơi nó chậm hơn 30 lần). Đây chỉ là một ví dụ và máy tính của bạn có thể hiển thị các xu hướng hơi khác nhau tùy thuộc vào những thứ như tốc độ bộ nhớ, lõi / tốc độ xử lý, v.v. nhưng nó mang tính minh họa cho điểm. Lý do fftcó đầu ra khó hiểu là bởi vì nó đang tiết kiệm cho bạn một phần không cần thiết trong thời gian tính toán của bạn.


3
Điều này vẫn không trả lời câu hỏi ban đầu - tại sao nó hoàn toàn hoạt động để bao gồm số không hai lần? Và tại sao tài liệu cho thấy số 0 chỉ nên được đưa vào một lần?
David Ketcheson

2

Câu hỏi của bạn liên quan đến wavenumber 'thay thế' là khá khó khăn. Nói chung, sửa đổi wavenumber của loại này không nhằm mục đích lưu flops, như một số người đã đề xuất ở đây, mà thay vào đó được thiết kế để tôn trọng các đặc thù phân tích của, nói, các toán tử vi phân nhất định. Tôi rất ngạc nhiên khi tôi không thể tìm thấy một cuộc thảo luận liên quan trong Phương pháp quang phổ của Trefethen. Để tiếp tục, tôi sẽ giả định rằng bạn lo ngại về sự khác biệt phổ dựa trên FFT và rằng bạn đang thực hiện các phép biến đổi trên một miền có tính đồng đều.

Quy tắc của ngón tay cái, đối với các dẫn xuất lẻ, là đặt

k = [0:n/2-1 0 -n/2+1:-1];

và cho các dẫn xuất chẵn, để thiết lập

k = [0:n/2 -n/2+1:-1];

Nếu bạn đang đối phó với bất kỳ phần đệm nào, việc điều trị tần số Nyquist cũng tương tự tẻ nhạt. Có một bài viết xuất sắc chứng minh và nhận xét về các chủ đề này ở đây !



0

NN/2xRN/2N/2N/2

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.