Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Прочее / ZAPISKA2.DOC
Скачиваний:
30
Добавлен:
17.04.2013
Размер:
1.48 Mб
Скачать

Используя спектральную функцию s(yk) , кусочно-гладкую функциюf(X) периодаl можно представить в виде

f(x)= 1/l S(yk)e2ПiykX

Преобразования Фурье играют большую роль в распознавании образов , в моделировании фильтров , при корректировке изображений и в целом ряде других задач.

Известно , что аналитическое вычисление интегралов (*) и (**) вызывает , как правило , большие трудности , поэтому представляют большой интерес методы численной реализации этих интегралов.В связи с этим был разработан метод дискретного преобразования фурье (ДПФ) . интенсивное использование которого началось после введения в технику вычислений так называемого алгоритма «быстрого преобразования фурье» (БПФ).Этот алгоритм для вычисления БПФ был предложен Кули и Таки в 1965 г., хотя в других вычислениях он применялся значительно раньше.

Под дискретным преобразованием фурье понимается пара преобразований , устанавливающих взаимосвязь между конечным числом дискретных выборок как временной функции f(t), так и её частотного спектра S(y) .В случае 2N равноудалённых выборок в точках

tk= t0+k t , k=0,1,2,...,2N-1 ,и

yk= y0+n t , n=0,1,2,...,2N-1

Эти преобразования записываются обычно в виде

S^(yn) = t f(tk)e-2Пiyntk

f(tk) = y s^(yn)e2Пiyntk

Значения частотного спектраS^(yn) , вообще говоря , отличны от значений спектра S(yn) .По одному из свойств преобразований фурье :

S^(y) = S1(y)S2(y-т)dт , где S1 и S2 преобразования

фурье функций f1(t) и f2(t),т.е S^(y) является свёрткой.Это вызывает размыте по частоте спектральной функции, а также размытие по фазе.

Если спектр функции f(t) представляет непрерывную функцию S(y) , то её размывание происходит согласно формуле:

S^(y)= t S(т)e-Пi(y-т)(2N-1) t(sin2П(y-т)N t)/(sinП(y-т) t) dt

Это означает , что замена бесконечного интеграла конечной суммой с равномерными выборками приводит к спектральной функцииS^(y) , имеющей период 1/ t и осуществляющей размывание по частоте и изменение по фазе пиков исходной спектральной функцииS(y).

  1. Инструкция пользователя:

  • запустить компилятор CBuilder 4.0,

  • открыть файл проекта furie.bpr,

  • запустить программу на выполнение (F9)

  • нажать кнопку ЗНАЧЕНИЯ,

  • в появившемся диалоговом окне ввести коэффициенты полинома,

  • нажать кнопку ПЕРЕСЧИТАТЬ,

  • на экран будет выведен входной сигнал, амплитудный спектр и фазовый спектр,

  • для выхода из программы необходимо нажать кнопку ЗАКРЫТЬ.

Программа позволяет загружать результаты предыдущих вычи-слений без ввода значений коэффициентов полинома из файла

SPECTR.DAT (для этого нужно нажать кнопку ЗАГРУЗИТЬ)

этот файл автоматически записываются значения сигнала и

спектров при выходе из программы.

  1. Аппаратные и программные требования:

Для запуска программы необходимо:

  • компьютер с процессором INTEL Pentium 100 и выше,

  • монитор, поддерживающий разрешение 800х600 точек,

  • 1 Mb дискового пространства,

  • 16 Mb оперативной памяти,

  • наличие операционной системы MS Windows 95 и выше,

  • наличие пакета Borland CBuilder версии 4.0

Необходимые файлы:

  1. Текст программы: { Текст основной программы furie.Cpp}

#include <vcl.h>

#pragma hdrstop

USERES("furie.res");

USEFORM("mainunit.cpp", MainForm);

USEUNIT("data.cpp");

USEUNIT("_tdft.cpp");

USEFORM("Value.cpp", ValueForm);

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)

{

try

{

Application->Initialize();

Application->CreateForm(__classid(TMainForm), &MainForm);

Application->CreateForm(__classid(TValueForm), &ValueForm);

Application->Run();

}

catch (Exception &exception)

{

Application->ShowException(&exception);

}

return 0;

}

#include <vcl.h>

#pragma hdrstop

USERES("furie.res");

USEFORM("mainunit.cpp", MainForm);

USEUNIT("data.cpp");

USEUNIT("_tdft.cpp");

USEFORM("Value.cpp", ValueForm);

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)

{

try

{

Application->Initialize();

Application->CreateForm(__classid(TMainForm), &MainForm);

Application->CreateForm(__classid(TValueForm), &ValueForm);

Application->Run();

}

catch (Exception &exception)

{

Application->ShowException(&exception);

}

return 0;

}

{Текст модуля mainunit.cpp}

#include <vcl.h>

#pragma hdrstop

#include "mainunit.h"

#include "value.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma link "PERFGRAP"

#pragma link "CSPIN"

#pragma resource "*.dfm"

TMainForm *MainForm;

void __fastcall OutGraph()

{

// Отображение графиков

int pos = MainForm->ScrollBar->Position;

int div = MainForm->Spin->Value;

MainForm->Canvas->Brush->Color = clBtnFace;

MainForm->Canvas->Pen->Color = clBlack;

MainForm->Canvas->FillRect(NewRect);

Y[0]=90;Y[1]=230;Y[2]=300;

for (i=0;i<3;i++)

{

MainForm->Canvas->MoveTo(X0,Y[i]);

MainForm->Canvas->LineTo(X1,Y[i]);

MainForm->Canvas->LineTo(X1-10,Y[i]-2);

MainForm->Canvas->LineTo(X1-10,Y[i]+2);

MainForm->Canvas->LineTo(X1,Y[i]);

MainForm->Canvas->MoveTo(X0,Y[i]);

MainForm->Canvas->LineTo(X0,Y[i]-60);

MainForm->Canvas->LineTo(X0-2,Y[i]-50);

MainForm->Canvas->LineTo(X0+2,Y[i]-50);

MainForm->Canvas->LineTo(X0,Y[i]-60);

}

maximum = abs(x_R[0]);

for(n = 0 ;n < _N; n++)

{

if (maximum < abs(x_R[n])) {maximum = abs(x_R[n]);}

}

if (maximum != 0) {norm = 70/maximum;}

else {norm = 0;}

MainForm->Canvas->MoveTo(X0,-(int)(x_R[pos]*norm)+Y0);

for(n = pos ;n < (_N/div + pos); n++)

{

MainForm->Canvas->LineTo((n-pos)*(X1-X0)/(_N/div-1)+X0,-(int)(x_R[n]*norm)+Y0);

}

MainForm->Canvas->Pen->Color=clRed;

MainForm->Canvas->MoveTo(X0,Y1);

maximum = abs(m[0]);

for(n = 0 ;n < _N; n++)

{

if (maximum < abs(m[n])) {maximum = abs(m[n]);}

}

if (maximum != 0) {norm = 70/maximum;}

else {norm = 0;}

for(n = pos;n < _N/div + pos; n++)

{

MainForm->Canvas->MoveTo((n-pos)*(X1-X0)/(_N/div - 1)+X0,Y1);

MainForm->Canvas->LineTo((n-pos)*(X1-X0)/(_N/div - 1)+X0,-(int)(m[n]*norm)+Y1);

}

MainForm->Canvas->Pen->Color=clBlue;

MainForm->Canvas->MoveTo(X0,Y2);

for(n = pos;n < _N/div + pos; n++)

{

MainForm->Canvas->MoveTo((n-pos)*(X1-X0)/(_N/div - 1)+X0,Y2);

MainForm->Canvas->LineTo((n-pos)*(X1-X0)/(_N/div - 1)+X0,-(int)(f[n]*10)+Y2);

}

}

//---------------------------------------------------------------------------

__fastcall TMainForm::TMainForm(TComponent* Owner)

: TForm(Owner)

{

}

//---------------------------------------------------------------------------

void __fastcall TMainForm::CloseButtonClick(TObject *Sender)

{

Close();

}

//---------------------------------------------------------------------------

void __fastcall TMainForm::FormCreate(TObject *Sender)

{

// Установка начальных параметров компонентов

Panel1->Left = (ClientWidth - Panel1->Width) / 2;

Panel1->Top = (ClientHeight - Panel1->Height) / 2;;

ScrollBar->Min = 0;

ScrollBar->Max = _N;

ScrollBar->Width = X1 - X0;

ScrollBar->Top = Y2 + 50;

ScrollBar->Left = X0;

ScrollBar->Visible = False;

Canvas->Brush->Color = clWhite;

Canvas->FillRect(NewRect);

ButtonPanel->Show();

}

//---------------------------------------------------------------------------

void __fastcall TMainForm::CalcButtonClick(TObject *Sender)

{

// Задание входного сигнала и вычисление преобразрвания Фурье

Panel1->Show();

int tmp;

Application->ProcessMessages();

for (n=0;n<_N;n++)

{

tmp = n%T;

x_R[n] = ValueForm->Spin1->Value

+ ValueForm->Spin2->Value * tmp

+ ValueForm->Spin3->Value * tmp * tmp

+ ValueForm->Spin4->Value * tmp * tmp * tmp

+ ValueForm->Spin5->Value * tmp * tmp * tmp * tmp;

x_I[n] = 0;

}

// Открытие файла на запись

if ((out = fopen("SPECTR.dat", "w")) == NULL)

{

Panel1->Hide();

ShowMessage("Ошибка создания файла...");

}

else

{

MyDFT.Forward(x_R,x_I,X_R,X_I);

MyDFT.Magnitude(m,X_R,X_I);

MyDFT.Phase(f,X_R,X_I);

Panel1->Hide();

for (n=0;n<_N;n++) // Пишем данные в файл

{

fprintf(out,"%lf\n%lf\n%lf\n",x_R[n],m[n],f[n]); //Сигнал,амплитудный спектр

} //и фазовый спектр

fclose(out);

}

OutGraph();

}

//---------------------------------------------------------------------------

void __fastcall TMainForm::DrawButtonClick(TObject *Sender)

{

if ((out = fopen("SPECTR.dat", "r")) == NULL)

{

Panel1->Hide();

ShowMessage("Ошибка чтения файла...");

}

else

{

for (n=0;n<_N;n++) // Пишем данные в файл

{

fscanf(out,"%lf\n%lf\n%lf\n",&x_R[n],&m[n],&f[n]);//Сигнал,амплитудныйспектр

} //и фазовый спектр

fclose(out);

}

OutGraph();

}

//---------------------------------------------------------------------------

void __fastcall TMainForm::ScrollBarChange(TObject *Sender)

{

// Изменение значения ползунка

Label1->Caption = ScrollBar->Position; // Вывод значения ползунка

MainForm->Canvas->FillRect(NewRect); // Очистка формы

OutGraph(); // Вывод графиков

}

//---------------------------------------------------------------------------

void __fastcall TMainForm::SpinChange(TObject *Sender)

{

// Изменение коэффициента развёртки

if (Spin->Value > 1) {ScrollBar->Show();}

else {ScrollBar->Hide();}

ScrollBar->Max = _N - _N/Spin->Value;

OutGraph();

}

//---------------------------------------------------------------------------

void __fastcall TMainForm::ParamButtonClick(TObject *Sender)

{

// Вывод окошка для ввода параметров А1,А2...

ValueForm->ShowModal();

}

//---------------------------------------------------------------------------

void __fastcall TMainForm::FormPaint(TObject *Sender)

{

// Перерисока формы при её перекрытии

OutGraph();

}

//---------------------------------------------------------------------------

void __fastcall TMainForm::FormShow(TObject *Sender)

{

// При отображении формы читаем из INI файла значения параметров полинома

TIniFile *INI = new TIniFile("dat.ini");

ValueForm->Spin1->Value = INI->ReadInteger("Parametrs","A1",1);

ValueForm->Spin2->Value = INI->ReadInteger("Parametrs","A2",2);

ValueForm->Spin3->Value = INI->ReadInteger("Parametrs","A3",3);

ValueForm->Spin4->Value = INI->ReadInteger("Parametrs","A4",4);

ValueForm->Spin5->Value = INI->ReadInteger("Parametrs","A5",5);

INI->~TIniFile();

}

//---------------------------------------------------------------------------

void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action)

{

// При закрытии формы пишем в INI файл значения параметров полинома

TIniFile *INI = new TIniFile("dat.ini");

INI->WriteInteger("Parametrs","A1",ValueForm->Spin1->Value);

INI->WriteInteger("Parametrs","A2",ValueForm->Spin2->Value);

INI->WriteInteger("Parametrs","A3",ValueForm->Spin3->Value);

INI->WriteInteger("Parametrs","A4",ValueForm->Spin4->Value);

INI->WriteInteger("Parametrs","A5",ValueForm->Spin5->Value);

INI->~TIniFile();

}

{Текст модуля _tdft.cpp}

/*------------------------------------------------------------------------*/

/* */

/* TDFT.CPP - Complex Discrete Fourier Transform */

/* */

/* Copyright Eugene Emelin 2001 */

/* */

/* All Rights Reserved */

/* */

/*------------------------------------------------------------------------*/

#if !defined( __MATH_H )

#include <math.h>

#endif // __MATH_H

#if !defined( __STDIO_H )

#include <stdio.h>

#endif // __STDIO_H

#if !defined( _pi)

#define _pi 3.1415926535897932384626

#endif // _pi

#if !defined( _2pi)

#define _2pi 6.283185307179586476925

#endif // _2pi

#if !defined( __PRECISION)

#define __PRECISION double

#endif // __PRECISION

#if !defined( _THRESHOLD)

#define _THRESHOLD 0.000001

#endif // _THRESHOLD

class TDFT

{

int N; // Number of Samples

int k; // Harmonic index

int n; // Sample index

public:

double Threshold; // Magnitude Threshold for Phase calculation in the case of very small magnitude

TDFT(int Length)

{

N = Length; Threshold = _THRESHOLD;

};

~TDFT(){};

private:

void Trans (__PRECISION *RI, __PRECISION *II, __PRECISION *RO, __PRECISION *IO, unsigned int k);

public:

void Forward (__PRECISION *RTime, __PRECISION *ITime, __PRECISION *RFreq, __PRECISION *IFreq);

void Inverse (__PRECISION *RFreq, __PRECISION *IFreq, __PRECISION *RTime, __PRECISION *ITime);

inline void Forward (__PRECISION *RTime, __PRECISION *ITime, __PRECISION *RFreq, __PRECISION *IFreq, unsigned int k);

inline void Inverse (__PRECISION *RFreq, __PRECISION *IFreq, __PRECISION *RTime, __PRECISION *ITime, unsigned int k);

void Magnitude (__PRECISION *Magn, __PRECISION *RFreq, __PRECISION *IFreq);

void Phase (__PRECISION *Phase, __PRECISION *RFreq, __PRECISION *IFreq);

};

void TDFT::Forward (__PRECISION *RTime, __PRECISION *ITime , __PRECISION *RFreq, __PRECISION *IFreq)

{

// Прямое преобразование Фурье

for(k = 0; k < N; k++)

{

Trans (RTime, ITime, RFreq, IFreq, k);

RFreq[k] /= N;

IFreq[k] /= -N;

}

};

void TDFT::Inverse (__PRECISION *RFreq, __PRECISION *IFreq, __PRECISION *RTime, __PRECISION *ITime)

{

// Обратное преобразование Фурье

for(k = 0; k < N; k++)

Trans (RFreq, IFreq, RTime, ITime, k);

};

inline void TDFT::Forward (__PRECISION *RTime, __PRECISION *ITime , __PRECISION *RFreq, __PRECISION *IFreq, unsigned int k)

{

// Прямое преобразование Фурье

// (перегруженная функция)

Trans (RTime, ITime, RFreq, IFreq, k);

RFreq[k] /= N;

IFreq[k] /= -N;

};

inline void TDFT::Inverse (__PRECISION *RFreq, __PRECISION *IFreq, __PRECISION *RTime, __PRECISION *ITime, unsigned int k)

{

// Обратное преобразование Фурье

// (перегруженная функция)

Trans (RFreq, IFreq, RTime, ITime, k);

};

void TDFT::Trans (__PRECISION *RI, __PRECISION *II, __PRECISION *RO, __PRECISION *IO, unsigned int k)

{

// Одна итерация преобразования Фурье

__PRECISION w, cosw, sinw;

RO[k] = 0;

IO[k] = 0;

for(n = 0; n < N; n++)

{

w = (__PRECISION)(_2pi*n*k)/N;

sinw = sin(w);

cosw = cos(w);

RO[k] += (RI[n]*cosw) - (II[n]*sinw);

IO[k] += (II[n]*cosw) + (RI[n]*sinw);

}

};

void TDFT::Magnitude(__PRECISION *Magn, __PRECISION *RFreq, __PRECISION *IFreq)

{

// Вычисление магнитуды

__PRECISION tmp;

for(k = 0; k <= N/2; k++)

{

tmp = (__PRECISION)sqrt( (RFreq[k]*RFreq[k]) + (IFreq[k]*IFreq[k]) );

Magn[k] = tmp;

Magn[N-k] = tmp;

}

};

void TDFT::Phase(__PRECISION *Phase, __PRECISION *RFreq, __PRECISION *IFreq)

{

// Вычисление фазы

for(k = 0; k < N; k++)

if (( fabs(RFreq[k]) < Threshold ) && ( fabs(IFreq[k]) < Threshold )) Phase[k] = 0;

else

{

if (RFreq[k] == 0) RFreq[k] = 1e-38;

Phase[k] = (__PRECISION) atan2(IFreq[k], RFreq[k]);

if (Phase[k] == -_pi) Phase[k] = _pi;

};

};

{Текст модуля VALUE.CPP}

#include <vcl.h>

#pragma hdrstop

#include "Value.h"

#include "Data.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma link "CSPIN"

#pragma resource "*.dfm"

TValueForm *ValueForm;

//---------------------------------------------------------------------------

__fastcall TValueForm::TValueForm(TComponent* Owner)

: TForm(Owner)

{

}

//---------------------------------------------------------------------------

void __fastcall TValueForm::Button1Click(TObject *Sender)

{

Close();

}

//---------------------------------------------------------------------------

void __fastcall TValueForm::Button2Click(TObject *Sender)

{

Close();

}

Соседние файлы в папке Прочее