Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Desktop / KA Записка.docx
Скачиваний:
23
Добавлен:
16.03.2015
Размер:
301.8 Кб
Скачать

3 Описание разработанного алгоритма

3.1 Описание работы программы

Заданный алгоритм был реализован программно с помощью технологии Microsoft .NET Frameworkна языке программированияC++.

Написанное приложение состоит из двух сборок: библиотеки классов FFT, содержащей все необходимое для вычисления ДПФ по формуле и БПФ.

Также присутствует консольный модуль, реализующий пользовательский интерфейс:

Рисунок 1 Основное меню программы

После выбора алгоритма пользователь видит консоль с предложением ввести размер квадратного массива:

Рисунок 2 Консоль ввода массива

В результате генерируется файл с подаваемым на вход сигналом, на выходе получаем файл с исходным спектром в комплексном представлении. Далее представлены примеры выполненной работы алгоритмов БПФ и ДПФ для длины преобразования 64:

Рисунок 3 Пример работы алгоритма вычисления БПФ-64

Рисунок 4 Пример работы алгоритма вычисления ДПФ-64

4 Исследование алгоритма

Для наглядного представления приведем таблицу и график сравнения алгоритмов БПФ и ДПФ.

Проведем сравнение результатов непосредственного вычисления дискретного преобразования Фурье и результатов быстрых алгоритмов для длин преобразований 2, 4, 8, 16, 32, 64, 128, 256.

Таблица 2 Сравнение времени выполнения БПФ и ДПФ

N

Время вычисления БПФ, с

Время вычисления ДПФ, с

8

0,001322

0,001686

16

0,007954

0,018803

32

0,047996

0,455932

64

0,287401

8,510700

128

1,714250

160,6980

256

8,678940

3559,830

Рисунок 5 Зависимость времени выполнения алгоритма от длины преобразования

Из Рисунка 5 видно, что быстрый алгоритм Фурье имеет значительное преимущество в скорости перед непосредственным дискретным преобразованием, хотя для небольшого объёма данных различия несущественны. Так же присутствует погрешность, связанная с машинными характеристиками, которая напрямую влияет на скорость алгоритмов.

Приложение а. Текст программы

Class Hypercomplex

#include "StdAfx.h"

#include "Hypercomplex.h"

#include <iostream>

#include <math.h>

#include <float.h>

Hypercomplex::Hypercomplex()

{

W = 0.0;//1.0

X = 0.0;

Y = 0.0;

Z = 0.0;

}

Hypercomplex::Hypercomplex(const double w, const double x, const double y, const double z)

{

W = w;

X = x;

Y = y;

Z = z;

}

void Hypercomplex::PrintOn(ostream &strm) const

{

Hypercomplex q(W, X, Y, Z);

if(abs(q.getW()) < 0.000001)

{

q.setW(0.0);

}

if(abs(q.getX()) < 0.000001)

{

q.setX(0.0);

}

if(abs(q.getY()) < 0.000001)

{

q.setY(0.0);

}

if(abs(q.getZ()) < 0.000001)

{

q.setZ(0.0);

}

strm << "(" << q.W << "," << q.X << "," << q.Y << "," << q.Z << ")";

}

Hypercomplex operator * (const Hypercomplex &a, const Hypercomplex &b)

{

double w,x,y,z;

w = a.W*b.W - (a.X*b.X + a.Y*b.Y + a.Z*b.Z);

x = a.W*b.X + b.W*a.X + a.Y*b.Z + a.Z*b.Y;

y = a.W*b.Y + b.W*a.Y + a.Z*b.X + a.X*b.Z;

z = a.W*b.Z + b.W*a.Z + a.X*b.Y + a.Y*b.X;

return Hypercomplex(w,x,y,z);

}

const Hypercomplex& Hypercomplex::operator *= (const Hypercomplex &q)

{

double w = W, x = X, y = Y, z = Z;

double qW = q.W, qX = q.X, qY = q.Y, qZ = q.Z;

W = w*qW - (x*qX + y*qY + z*qZ);

X = w*qX + qW*x + y*qZ + z*qY;

Y = w*qY + qW*y + z*qX + x*qZ;

Z = w*qZ + qW*z + x*qY + y*qX;

return *this;

}

Hypercomplex operator + (const Hypercomplex &a, const Hypercomplex &b)

{

double w,x,y,z;

w = a.W+b.W;

x = a.X+b.X;

y = a.Y+b.Y;

z = a.Z+b.Z;

return Hypercomplex(w,x,y,z);

}

const Hypercomplex& Hypercomplex::operator += (const Hypercomplex &q)

{

W = W+q.W;

X = X+q.X;

Y = Y+q.Y;

Z = Z+q.Z;

return *this;

}

Hypercomplex operator - (const Hypercomplex &a, const Hypercomplex &b)

{

double w,x,y,z;

w = a.W-b.W;

x = a.X-b.X;

y = a.Y-b.Y;

z = a.Z-b.Z;

return Hypercomplex(w,x,y,z);

}

const Hypercomplex& Hypercomplex::operator -= (const Hypercomplex &q)

{

W = W-q.W;

X = X-q.X;

Y = Y-q.Y;

Z = Z-q.Z;

return *this;

}

Hypercomplex Hypercomplex::operator = (const Hypercomplex &q)

{

W = q.W;

X = q.X;

Y = q.Y;

Z = q.Z;

return *this;

}

const Hypercomplex& Hypercomplex::operator ~ ()

{

X = -X;

Y = -Y;

Z = -Z;

return *this;

}

const Hypercomplex& Hypercomplex::exp()

{

double Mul;

double Length = sqrt(X*X + Y*Y + Z*Z);

if (Length > 1.0e-4)

Mul = sin(Length)/Length;

else

Mul = 1.0;

W = cos(Length);

X *= Mul;

Y *= Mul;

Z *= Mul;

return *this;

}

const double& Hypercomplex::arg()

{

return acos(W/sqrt(W*W + X*X + Y*Y + Z*Z));

}

const Hypercomplex& Hypercomplex::sgn()

{

Hypercomplex q = *this;

return (1/sqrt(W*W + X*X + Y*Y + Z*Z))*q;

}

const Hypercomplex& Hypercomplex::log()

{

double Length;

Length = sqrt(X*X + Y*Y + Z*Z);

Length = atan(Length/W);

W = 0.0;

X *= Length;

Y *= Length;

Z *= Length;

return *this;

}

const Hypercomplex& Hypercomplex::u(Hypercomplex& q)

{

Hypercomplex u = q;

u.W = 0;

return u;

}

const Hypercomplex Hypercomplex::pow(int k)

{

Hypercomplex b(1,0,0,0);

Hypercomplex a = *this;

while (k)

{

if (k & 1)

{

b *= a;

}

a *= a;

k >>= 1;

}

return b;

}

const Hypercomplex Hypercomplex::toHypercomplex(const double &d)

{

double w, x, y, z;

w = d;

x = 0;

y = 0;

z = 0;

return Hypercomplex(w,x,y,z);

}

const Hypercomplex Hypercomplex::toHypercomplex(const std::complex<double> &c)

{

double w,x,y,z;

w = c.real();

x = c.imag();

y = 0;

z = 0;

return Hypercomplex(w,x,y,z);

}

const Hypercomplex& Hypercomplex::Initialize(const double& w, const double& x, const double& y, const double& z)

{

W = w;

X = x;

Y = y;

Z = z;

return *this;

}

void Hypercomplex::setW(const double &value)

{

W = value;

}

void Hypercomplex::setX(const double &value)

{

X = value;

}

void Hypercomplex::setY(const double &value)

{

Y = value;

}

void Hypercomplex::setZ(const double &value)

{

Z = value;

}

double Hypercomplex::getW()

{

return W;

}

double Hypercomplex::getX()

{

return X;

}

double Hypercomplex::getY()

{

return Y;

}

double Hypercomplex::getZ()

{

return Z;

}

Class DPF

#pragma once

#include <iostream>

#include <fstream>

#include <complex>

#include "Hypercomplex.h"

#include <conio.h>

#include <math.h>

using namespace std;

#ifndef PI

#define PI 3.14159265358979323846

#endif

class DPF

{

private:

int N1, N2;

Hypercomplex w1, w2;

Hypercomplex** mas_w;

public:

DPF();

~DPF(void);

double** loadMatrix(char name[]);

void writeComplexMatrix(char name[], complex<double>** complex_matrix, int&);

template<typename T>

T* binInverse(T* x, int& n)

{

int dl = n/2;

int st = n - 1;

int j = 0;

T s0 = 0;

int k = 0;

for(int i = 0; i < st; i++)

{

if(i < j)

{

s0 = x[i];

x[i] = x[j];

x[j] = s0;

}

k = dl;

while(k <= j)

{

j -= k;

k >>= 1;

}

j += k;

}

return x;

}

template<typename T>

T** binMtrInverse(T** matr, int& N)

{

int size = 0;

size = N;

for(int i = 0; i < size; i++)

{

binInverse(matr[i], size);

}

T* v = new T[size];

for(int i=0; i<size; i++)

{

for(int j=0; j<size; j++)

{

v[j] = matr[j][i];

}

binInverse(v, size);

for(int j=0; j<size; j++)

{

matr[j][i] = v[j];

}

}

delete v;

return matr;

}

Hypercomplex** matrInv(Hypercomplex** q, int& N);

void genMatr(int N, char name[]);

Hypercomplex** _dpf(Hypercomplex** matrix);

Hypercomplex** Q44(Hypercomplex&, Hypercomplex&, Hypercomplex&, Hypercomplex&, Hypercomplex&, Hypercomplex&,

Hypercomplex&, Hypercomplex&, Hypercomplex&, Hypercomplex&, Hypercomplex&, Hypercomplex&, Hypercomplex&, Hypercomplex&, Hypercomplex&, Hypercomplex&);

Hypercomplex butterfly2(Hypercomplex&, Hypercomplex&, Hypercomplex&, Hypercomplex&, int&, int&, int&);

Hypercomplex Q_dft_basis4(Hypercomplex**, int&, const int&, const int&);

int pos(int a);

Hypercomplex** HyperMatrix(const int&);

Hypercomplex** toHyperMatrix(double**, int&);

Hypercomplex** Q_ftfbs(Hypercomplex**, int &size);

Hypercomplex Q00(Hypercomplex**, int&, int&, int&);

Hypercomplex Qab(Hypercomplex**, int&, int&, int&, const int&, const int&);

void shift(Hypercomplex**, int, int);

void clcCoordinates(int&, int&, int, int);

void clcMasW(int&);

void clearMasW();

Hypercomplex** Q_algftf(Hypercomplex** , int&);

void fft2(Hypercomplex**,int&);

void fft4(Hypercomplex**,int&);

complex<double> toComplex(Hypercomplex&);

const Hypercomplex automorphism(Hypercomplex&, const int&);

complex<double>** allocPartSpectr(Hypercomplex**, int&);

complex<double>** getComplexSpectr(Hypercomplex**, int&);

void set(int& N);

int get_N1();

int get_N2();

void setW1(int);

void setW2(int);

};

Соседние файлы в папке Desktop