2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 Быстрое преобразование фурье.
Сообщение09.03.2014, 19:58 
Здравствуйте, помогите пожалуйста разобраться. Я сделал быстрое преобразование фурье над массивом полученным из простейших тригонометрических функций или их произведения и сложения, получил массив по которому я могу построить спектр, но как мне теперь сделать так чтобы каждая точка полученного массива соответствовала частоте?
Вот код, может прояснить
https://dl.dropboxusercontent.com/u/714 ... Tforum.zip
код: [ скачать ] [ спрятать ]
Используется синтаксис Delphi
procedure TForm1.btn1Click(Sender: TObject);
var i:SmallInt;
begin
  for i:=0 to 128-1 do //генерация тестового сигнала
    begin
     fDataBuf[i] := F(i)*2*F(i*8);
    end;
  MakeFFT();
  DrawFFT();
  tmr1.Enabled:=True;
end;
 
procedure TForm1.MakeFFT;
var
 fftb: TFFTBase; //класс, который реализует БПФ
 fFFTComplBuf: ^TComplexArray;  //Буфер для хранения комплексных величин
 i: integer;
begin
 GetMem(fFFTComplBuf, 128*SizeOf(TComplex)); //Выделение памяти под массив
 for i:=0 to 128-1 do //Заполняем данными массив
  begin
   fFFTComplBuf[i].Re := fDataBuf[i];
   fFFTComplBuf[i].Im := 0;
  end;
 fftb:=TFFTBase.Create(nil);
 
 
fftb.FFT(Pointer(fFFTComplBuf), 128, 7, False, 0);
 for i:=0 to 128-1 do //Переносим результат БПФ в исходный массив
  begin
   fDataBuf[i] := Round(fFFTComplBuf[i].Re / 500);
  end;
 fftb.Free;
 FreeMem(fFFTComplBuf, 128*SizeOf(TComplex)); //Освобождение памяти выделенной под массив
end;
 
function TForm1.F(t: SmallInt): SmallInt;
begin
 F:=Round(10000*sin(2*Pi*2000*t/180));
end;
 

 
 
 
 Re: Быстрое преобразование фурье.
Сообщение09.03.2014, 20:52 
Аватара пользователя
Но она же и так соответствует.
$k$-й элемент массива соответствует $k$-й гармонике, частота которой в $k$ раз больше частоты первой гармоники.

 
 
 
 Re: Быстрое преобразование фурье.
Сообщение09.03.2014, 21:19 
А мне кажется, что $\operatorname{Re}\text{амплитуда}\ne|\text{амплитуда}|$

-- Пн мар 10, 2014 00:23:16 --

ishikawa, скажите, пожалуйста: вы писали код класса TFFTBase?

-- Пн мар 10, 2014 00:34:05 --

…и зачем вам дался бедный SmallInt — память экономить надо не в этом случае. А особенно если учесть, что его всё равно придётся конвертировать в TComplex, в котором координаты не целые. Конечно, массив маленький, конвертации туда-сюда время не сильно прибавляют, но мотивацию интересно было бы узнать.

 
 
 
 Re: Быстрое преобразование фурье.
Сообщение10.03.2014, 06:11 
arseniiv, нет, не я писал. Вообще даже приведенный код не я писал, нашел пример, я только офмормил графический интерфейс, я если честно вообще не понимаю как работает FTT и данная библиотека, мне просто нужно сделать "осцилоскоп", который показывает спектр как положено. Ну и конечно мотивации делать именно так никакой небыло, это большая удача что мне вообще попался такой пример. Если вы можете мне помочь как сделать лучшее и правильнее, я вас очень прошу.

svv, да но нужно чтобы просто значения на осях были правильные.

 
 
 
 Re: Быстрое преобразование фурье.
Сообщение10.03.2014, 14:46 
Аватара пользователя
А, Вы график строите.
Вы пишете в Delphi. Там есть компонент TChart. Прочитайте где-нибудь, как с ним работать. В Вашем случае (после добавления вручную новой TFastLineSeries, которая автоматически получит имя, например, Series1) код DrawFFT может быть примерно таким:

код: [ скачать ] [ спрятать ]
Используется синтаксис Delphi
const
  N=128;
  T=0.01; // период
  f1=1/T; // частота первой гармоники
var
  fDataBuf: array [0..N-1] of double;

procedure TForm1.DrawFFT();
var
  i: integer;
  f: double;
begin
  Series1.Clear;
  for i:=0 to N-1 do
  begin
    f:=f1*i;
    Series1.AddXY(f, fDataBuf[i]);
  end;
end;
 

Предполагается, что выше DrawFFT есть примерно такие объявления, как у меня. Значение константы T взято для примера.

 
 
 
 Re: Быстрое преобразование фурье.
Сообщение10.03.2014, 15:27 
ishikawa в сообщении #834828 писал(а):
arseniiv, нет, не я писал.
Спасибо! Если собираетесь дальше писать на Delphi или там FreePascal, не смотрите на использование и объявление массивов в этом коде — сейчас можно намного проще и красивее это сделать, используя динамические массивы, у которых на лету можно менять длину — все необходимые вещи компилятор напишет сам. А так, как написано в этом коде, приходилось писать раньше. Очень давно. Тогда паскали таких массивов не поддерживали.

 
 
 
 Re: Быстрое преобразование фурье.
Сообщение10.03.2014, 17:23 
svv, да дело в том, что я как раз уже все сделал с TChart, ссылка на архив с полным кодом и исполняемым файлом есть, и графики отлично строятся, весьма похоже, но как бы я не подгонял, всё не не совпадают частоты, я думал узнать может его еще нужно както преобразовать, мне про Гильберта говорили, но вроде правая часть должна уже совпадать.

 
 
 
 Re: Быстрое преобразование фурье.
Сообщение10.03.2014, 17:35 
Конечно, не совпадут:
arseniiv в сообщении #834723 писал(а):
А мне кажется, что $\operatorname{Re}\text{амплитуда}\ne|\text{амплитуда}|$

 
 
 
 Re: Быстрое преобразование фурье.
Сообщение11.03.2014, 08:48 
Аватара пользователя
0. Каждая точка соответствует частоте. Нулевая точка частоте 0, точка n/2 частоте Котельникова-Шеннона-Найквиста, далее обратно вниз по частоте. Разбивка равномерная, так что могут получаться "некрасивые" значения, дробные с большим числом знаков. Ну и что?
1. Амплитуда и действительная часть Фурье - не одно и то же. Сдвиг по времени переводит синусы в косинусы, а действительные компоненты в мнимые. Для вычисления амплитуды нужны и Re и Im. А ещё можно сказать, что нужно посчитать вместо "алгебраической формы комплексного числа" тригонометрическую или показательную. И модуль вдруг окажется амплитудой, а аргумент - фазой.
2. В первой процедуре там что - генерируется синусоида, модулированная синусоидой частоты в 8 раз ниже? В выходном спектре у Вас не будет пиков на частоте несущей и на частоте модуляции. Ищите пики неподалёку, но не точно на этих частотах.

 
 
 [ Сообщений: 9 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group