Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
  #11  
Старый 06.03.2012, 02:13
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Возиожно этот вариант проще:
Код:
unit cplxfft2;

interface

type
  PScalar = ^TScalar;
  TScalar = Extended;

  PScalars = ^TScalars;
  TScalars = array[0..High(Integer) div SizeOf(TScalar) - 1] of TScalar;

const
  TrigTableDepth : word = 0;
  CosTable : PScalars = NIL;
  SinTable : PScalars = NIL;

procedure InitTrigTables(Depth : Word);

procedure FFT(Depth : Word; SrcR, SrcI : PScalars; DestR, DestI : PScalars);

{Перед вызовом Src и Dest ТРЕБУЕТСЯ распределение (integer(1) shl Depth) * SizeOf(TScalar) байт памяти!}

implementation

procedure DoFFT(Depth : Word; SrcR, SrcI : PScalars; SrcSpacing : Word;
 DestR, DestI : PScalars);
{рекурсивная часть, вызываемая при готовности FFT}
var
  J, N : Integer;
  TempR, TempI : TScalar;
  Sh : Word;
  c, s : Extended;
begin
  if Depth = 0 then
  begin
    DestR^[0] := SrcR^[0];
    DestI^[0] := SrcI^[0];
    Exit;
  end;

  N := Integer(1) shl (Depth - 1);

  DoFFT(Depth - 1, SrcR, SrcI, SrcSpacing * 2, DestR, DestI);
  DoFFT(Depth - 1, @SrcR^[srcSpacing], @SrcI^[SrcSpacing], SrcSpacing * 2, @DestR^[N], @DestI^[N]);

  Sh := TrigTableDepth - Depth;

  for J := 0 to N - 1 do
  begin
    c := CosTable^[J shl Sh];
    s := SinTable^[J shl Sh];

    TempR := c * DestR^[J + N] - s * DestI^[J + N];
    TempI := c * DestI^[J + N] + s * DestR^[J + N];

    DestR^[J + N] := DestR^[J] - TempR;
    DestI^[J + N] := DestI^[J] - TempI;

    DestR^[J] := DestR^[J] + TempR;
    DestI^[J] := DestI^[J] + TempI;
  end;
end;

procedure FFT(Depth : Word; SrcR, SrcI : PScalars; DestR, DestI : PScalars);
var
  J, N : Integer;
  Normalizer : Extended;
begin
  N := Integer(1) shl Depth;

  if Depth TrigTableDepth then
    InitTrigTables(Depth);

  DoFFT(Depth, SrcR, SrcI, 1, DestR, DestI);

  Normalizer := 1 / sqrt(N);

  for J := 0 to N - 1 do
  begin
    DestR^[J] := DestR^[J] * Normalizer;
    DestI^[J] := DestI^[J] * Normalizer;
  end;
end;

procedure InitTrigTables(Depth : Word);
var
  J, N : Integer;
begin
  N := Integer(1) shl Depth;
  ReAllocMem(CosTable, N * SizeOf(TScalar));
  ReAllocMem(SinTable, N * SizeOf(TScalar));

  for J := 0 to N - 1 do
  begin
    CosTable^[J] := cos(-(2 * Pi) * J / N);
    SinTable^[J] := sin(-(2 * Pi) * J / N);
  end;
  TrigTableDepth := Depth;
end;

finalization
  ReAllocMem(CosTable, 0);
  ReAllocMem(SinTable, 0);

end.

unit demofrm;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, cplxfft2, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Edit1: TEdit;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

uses
  MMSystem;

procedure TForm1.Button1Click(Sender: TObject);
var
  SR, SI, DR, DI : PScalars;
  J, D, N : Integer;
  st, et : Longint;
  norm : Extended;
begin
  D := StrToIntDef(edit1.text, -1);
  if d < 1 then
    raise
      exception.Create('глубина рекурсии должны быть положительным целым числом');

  N := Integer(1) shl D;

  GetMem(SR, N * SizeOf(TScalar));
  GetMem(SI, N * SizeOf(TScalar));
  GetMem(DR, N * SizeOf(TScalar));
  GetMem(DI, N * SizeOf(TScalar));

  for J := 0 to N - 1 do
  begin
    SR^[J] := Random;
    SI^[J] := Random;
  end;

  st := TimeGetTime;
  FFT(D, SR, SI, DR, DI);

  et := TimeGetTime;

  memo1.Lines.Add('N = ' + inttostr(N));
  memo1.Lines.Add('норма ожидания: ' + #9 + FloatToStr(N * 2 / 3));

  norm := 0;
  for J := 0 to N - 1 do
    norm := norm + SR^[J] * SR^[J] + SI^[J] * SI^[J];
  memo1.Lines.Add('норма данных: ' + #9 + FloatToStr(norm));

  norm := 0;
  for J := 0 to N - 1 do
    norm := norm + DR^[J] * DR^[J] + DI^[J] * DI^[J];
  memo1.Lines.Add('норма FT: ' + #9#9 + FloatToStr(norm));

  memo1.Lines.Add('Время расчета FFT: ' + #9 + inttostr(et - st));
  memo1.Lines.add('');

  FreeMem(SR, N * SizeOf(TScalar));
  FreeMem(SI, N * SizeOf(TScalar));
  FreeMem(DR, N * SizeOf(TScalar));
  FreeMem(DI, N * SizeOf(TScalar));
end;

end.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
 


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 14:31.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025