Проектирование
Модульная структура
Программа является головным модулем.
Используемые библиотеки:
Модуль cmath – предоставляет функции для работы с комплексными числами. В программе были использованы следующие функции:
cmath.exp() – экспонента
cmath.pi() – число Пи.
Tkinter - это графическая библиотека, позволяющая создавать программы с оконным интерфейсом. Эта библиотека является интерфейсом к популярному языку программирования и инструменту создания графических приложений tcl/tk. Tkinter, как и tcl/tk, является кроссплатформенной библиотекой и может быть использована в большинстве распространённых операционных систем (Windows, Linux, Mac OS X и др.)[2].
В программе были использованы следующие виджеты:
Button – кнопка, Entry – однострочное поле ввода, Label – текстовое поле, Text – многострочное поле ввода, Frame – виджет, который используется, главным образом, в качестве мастера геометрии для других виджетов.
В программе был задействован подмодуль tkinter.messagebox. Он предназначен для вывода на экран сообщений. В программе была использована функция tkinter.showmessage.showerror(‘Название окна’,’Выводимое сообщение’).
Модуль math предоставляет обширный функционал для работы с числами. В программе была использована логарифимическая функция math.log(‘аргумент’,’основание’)
Кодирование
Структура текста программы
В программе используются следующие глобальные переменные:
fourier – список комплексных чисел, используется для хранения входных данных
fourierback – список комплексных чисел, используется для хранения преобразованных чисел
fouriertwo – список комплексных чисел, используется для хранения чисел, полученных обратным преобразованием
countline – бинарная переменная, используется для отслеживания последнего ввода исходных данных.
Функция 1. Заголовок «recurs». В функции 1 происходит рекурсивный расчёт БПФ.
Функция recurs имеет следующие локальные параметры:
n – целого типа, используется для хранения длины списка вводных данных
y – список комплексных чисел, используется для хранения результата быстрого преобразования
E – переменная – экспонента, применяется для реализации БПФ в поле комплексных чисел
w – переменная, используется для сокращения времени расчёта экспоненциальной функции
a0, a1, y0, y1 – списки комплексных чисел, используются для реализации рекурсии в процедуре
x, k – переменные-счетчики
c – переменная-флаг, используется для реализации алгоритма БПФ.
Функция 2. Заголовок: «fft». Функция 2 — функция, вызываемая с помощью кнопки, начинающая процесс быстрого преобразования.
Функция fft имеет те же параметры, что и функция 1.
Функция 3. Заголовок: «count». Функция 3 — это подпрограмма, которая реализует ввод числа и добавляет его в список fourier.
Функция count имеет следующие параметры:
Mistake – переменная – флаг, для предотвращения повторного появления окон, с сообщением об ошибке ввода
a – переменная, отвечающая за действительную часть комплексного числа
b – переменная, отвечающая за мнимую часть комплексного числа
c – переменная, в которой действительная и мнимая части преобразуются в комплексное число.
Функция 4. Заголовок «dpf». Функция 4 – это подпрограмма, которая реализует дискретное преобразование Фурье.
Функция dpf имеет следующие локальные параметры:
n – переменная, которая хранит длину списка входных данных
i, k – переменные – счётчики.
Функция 5. Заголовок «opf». Функция 5 – это подпрограмма, которая реализует обратное преобразование Фурье.
Функция opf имеет идентичные локальные параметры с функцией dpf.
Функция 6. Заголовок «clrf». Функция 6 – подпрограмма, которая очищает списки БПФ, ДПФ и ОПФ.
Функция 7. Заголовок «save». Функция 7 реализует сохранение проведенных расчётов в текстовый файл.
Алгоритмы реализации
Дискретное преобразование Фурье
Получение исходных данных в виде списка комплексных чисел
Вычисление ДПФ по формуле
Быстрое преобразование Фурье
Псевдокод
[3],
при
Получение исходных данных
Проверка на соответствие количества элементов списка степени двойки и в случае несоответствия, выводится сообщение о невозможности проведения БПФ
Разбиение исходного списка на два списка, в один из которых попадают чётные элементы исходного списка, а в другой не чётные
К каждому из этих списков применяется рекурсивная функция БПФ
Получение выходного списка комплексных чисел, преобразованием, с помощью формул, указанных в 11 – 13 строках псевдокода
Обратное преобразование Фурье
Получение исходных данных в виде преобразованных комплексных чисел
Вычисление обратного преобразования по формуле
Реализация
Функция 1 - «recurs»
def recurs(fft):
n = len(fft)
y = [0+0j]*(n)
if n == 1:
return fft
E = cmath.exp(2*cmath.pi*1j/(n))
w = 1
c = True
a0 = []
a1 = []
for x in range(n):
if c==True:
a0.append(fft[x])
c = False
else:
a1.append(fft[x])
c = True
y0 = recurs(a0)
y1 = recurs(a1)
for k in range(int((n)/2)):
y[k] = y0[k]+w*y1[k]
y[k+int((n)/2)] = y0[k] - w*y1[k]
w = w*E
return y
Функция 2 – «fft»
def fft(event):
global fourierback
global countline
n = len(fourier)
try:
if log(n,2).is_integer() == True:
y = [complex(0,0)]*(n)
if n == 1:
return fourier
E = cmath.exp(2*cmath.pi*1j/(n))
w = 1
c = True
a0 = []
a1 = []
for x in range(n):
if c==True:
a0.append(fourier[x])
c = False
else:
a1.append(fourier[x])
c = True
y0 = recurs(a0)
y1 = recurs(a1)
for k in range(int((n)/2)):
y[k] = y0[k]+w*y1[k]
y[k+int((n)/2)] = y0[k] - w*y1[k]
w = w*E
txt1.insert(tkinter.INSERT, '\n')
txt1.insert(tkinter.INSERT,'================================== Список БПФ ==================================')
txt1.insert(tkinter.INSERT, '\n')
countline = False
fourierback = y
for x in range(n):
txt1.insert(tkinter.INSERT,"{0.real:.3f}{0.imag:+.3f}j".format(y[x]))
txt1.insert(tkinter.INSERT,' ')
return y
else:
tkinter.messagebox.showerror('Ошибка!','Количество введенных чисел должно быть равно степени двойки')
except ValueError:
tkinter.messagebox.showerror('Ошибка!','Вы не ввели ни одного числа')
Функция 3 – «count»
def count(event):
global countline
global fourier
Mistake = False
if ent1.get() == '':
a = 0
else:
try:
a = float(ent1.get())
except ValueError:
Mistake = True
tkinter.messagebox.showerror('Ошибка!', 'Ошибка ввода')
if not Mistake:
if ent2.get() == '':
b = 0
else:
try:
b = float(ent2.get())
except ValueError:
tkinter.messagebox.showerror('Ошибка!','Ошибка ввода')
try:
c = complex(a,b)
if countline == False:
txt1.insert(tkinter.INSERT, '\n')
txt1.insert(tkinter.INSERT,'=============================== Исходный список ================================')
txt1.insert(tkinter.INSERT, '\n')
if fourier != []:
for i in range(len(fourier)):
txt1.insert(tkinter.INSERT,"{0.real:.3f}{0.imag:+.3f}j".format(fourier[i]))
txt1.insert(tkinter.INSERT,' ')
countline = True
fourier.append(c)
txt1.insert(tkinter.END,"{0.real:.3f}{0.imag:+.3f}j".format(c))
txt1.insert(tkinter.END, ' ')
except Exception:
next
Функция 4 – «dpf»
def dpf(event):
global fourierback
global countline
n = len(fourier)
fourierback = [complex(0,0)]*n
for i in range(n):
for k in range(n):
fourierback[i] = fourierback[i] + fourier[k]*cmath.exp(2*cmath.pi*1j/n)**(i*k)
txt1.insert(tkinter.INSERT, '\n')
txt1.insert(tkinter.INSERT,'================================== Список ДПФ ==================================')
txt1.insert(tkinter.INSERT, '\n')
countline = False
for i in range(n):
txt1.insert(tkinter.INSERT,"{0.real:.3f}{0.imag:+.3f}j".format(fourierback[i]))
txt1.insert(tkinter.INSERT,' ')
return fourierback
Функция 5 – «opf»
def opf(event):
try:
global fouriertwo
global countline
n = len(fourierback)
fouriertwo = [complex(0,0)]*n
for i in range(n):
for k in range(n):
fouriertwo[i] = fouriertwo[i] + (1/n)*(fourierback[k]*(cmath.exp(2*cmath.pi*1j/n)**(i*k))**(-1))
txt1.insert(tkinter.INSERT, '\n')
txt1.insert(tkinter.INSERT,'================================== Список ОПФ ==================================')
txt1.insert(tkinter.INSERT, '\n')
countline = False
for i in range(n):
txt1.insert(tkinter.INSERT,"{0.real:.3f}{0.imag:+.3f}j".format(fouriertwo[i]))
txt1.insert(tkinter.INSERT,' ')
return fouriertwo
except NameError:
tkinter.messagebox.showerror('Ошибка!','Вы не произвели быстрое или дискретное преобразование')
Функция 6. Заголовок «clrf»
def clrf(event):
global fourier
global fourierback
global fouriertwo
fourier = []
fourierback = []
fouriertwo = []
Функция 7. Заголовок «save»
def save(event):
f = open('testfile.txt','w')
f.write(txt1.get(1.0,tkinter.END))
f.close()
