Добавлен: 20.05.2023
Просмотров: 193
Скачиваний: 3
Программирование «сверху вниз», или нисходящее программирование - метод написания программ, в котором первым делом определяются цели решения проблемы, далее разрабатывается последовательная детализация, после чего создаётся детальная программа.
Сперва определяется несколько подпрограмм, служащих для решения глобальных задач (например, инициализация данных, главная часть и завершение), после чего каждый созданный модуль разделяется на несколько более детальных подпрограмм более низкого уровня, которые вновь делятся до тех пор, пока задача не будет выполнена полностью.
В представленном случае программа строится иерархически - сверху вниз: от основной/главной программы к подпрограммам нижнего уровня, важно заметить, что каждый уровень состоит из простых последовательностей инструкций, циклов и условных разветвлений.
Такой подход удобен тем, что позволяет человеку постоянно мыслить на предметном уровне, не опускаясь до конкретных операторов и переменных. Кроме того, появляется возможность некоторые подпрограммы не реализовывать сразу, а временно откладывать, пока не будут закончены другие части. Например, если имеется необходимость вычисления сложной математической функции, то выделяется отдельная подпрограмма такого вычисления, но реализуется она временно одним оператором, который просто присваивает заранее выбранное значение (например, 5). Когда все приложение будет написано и отлажено, тогда можно приступить к реализации этой функции.
Программирование «снизу вверх», или восходящее программирование – это методика разработки программ, начинающаяся с разработки подпрограмм (процедур, функций), в то время когда проработка общей схемы не закончилась.
Такая методика является менее предпочтительной по сравнению с нисходящим программированием так как часто приводит к нежелательным результатам, переделкам и увеличению времени разработки.
Достоинства структурного программирования:
– повышается надежность программ (благодаря хорошему структурированию при проектировании, программа легко поддается тестированию и не создает проблем при отладке);
– повышается эффективность программ (структурирование программы позволяет легко находить и корректировать ошибки, а отдельные подпрограммы можно переделывать (модифицировать) независимо от других);
– уменьшается время и стоимость программной разработки;
– улучшается читабельность программ.
Также создавались функциональные (аппликативные) языки (Пример: Lisp -- англ. LISt Processing, 1958) и логические языки (пример Prolog англ. Programming in LOGic, 1972).
Часть 2. Практическая часть
2.1. Алгоритмические части выбранных примеров
Ниже будут рассмотрены примеры реализации некоторых примеров программ.
Пока кратко опишем их алгоритмы:
Реализован класс генерации синусоидального сигнала заданной частоты и начальной фазы (амплитуды для простоты взяты за единицу), с добавлением белого Гауссовского шума с мат ожиданием равным нулю и единичным СКО.
Класс rnd_test:
Данные:
Целые:
testtime – число дискрет сигнала (порядка сотен тысяч миллионов, по умолчанию равно 1 млн).
colon_count – число столбцов гистограммы для отображения.
colors – цвет гистограммы,
*colons – агрегированные данные в вариационном ряду.
Вещественные:
*data – данные сигнала
mat – мат ожидание
disp – дисперсия
СКО – среднеквадратичное отклонение
timer – таймер затраченного на расчет времени
excess – коэффициент ексцесса,
assimetry – коэффициент ассиметрии,
freq – заданная частота сигнала,
phi – заданная начальная фаза сигнала.
Методы:
Приватные:
static double rnd_test::rnd(); - генератор случайныех чисел равномерного распределения на участве 0..1
static void rnd_test::srnd(int seed); - инициализатор генераторов случайных чисел
static double rnd_test::eyler(); - гернератор случайных чисел по распределению Эйлера
static double rnd_test::next_gauss(); - генератор Гауссовского распределения с парпаметрами (0,1)
static double rnd_test::uniform(double a,double b); - равномерное распределение от а до б.
static double rnd_test::normal(double m, double s); - гауссово распределение с параметрами (m,s)
static double rnd_test::erlang(double m, double s); - генератор потока Эрланга
static double rnd_test::erl();
void rnd_test::distrib_run(); - запуск теста, генерация данных , подсчет основных характеристик сигнала.
int rnd_test::getmax(int *data,int size); - получение минимума и максимума в сигнале
int rnd_test::getmin(int *data,int size);
double rnd_test::signal_func(double x); - функция сигнала (синусоида + гауссов шум).
Публичные методы:
rnd_test(void); - конструктор объекта по умолчанию
rnd_test(int test,int colons, int color, double fr, double ph); - конструктор объекта с параметрами, число дискрет сигнала, число столбцов гистограммы, цвет, частота, фаза.
~rnd_test(void); - деструктор объекта.
void rnd_test::draw(HWND hWnd); - отрисовка распределений, и его характеристик на окне , использован стандартный WIN API.
2.2. Оценка сложности алгоритма
Сложность всех алгоритмов генерации и подсчета характеристик - О(), n – число дискретных значений сигнала.
2.3. Руководство пользователя
Все разработанные программы просты в использовании и не требуют от пользователя особых усилий, данные либо считываются из файла, либо генерируются случайно автоматически. Программы написаны на языке программирования на С++ в среде разработки Microsoft Visual Studio.
Исполняемый файл - random_obj.exe. Исходный код - random_obj.срр и rnd_test.cpp.
При запуске программа автоматически по заданным параметрам генерирует сигнал, отображает первые 50 его значений,
Рис 2.1.
И автоматически строит гистограмму сигнала:
Рис 2.2.
и вычисляет его основные характеристики.
Рис 2.3.
2.4. Тестирование на различных данных
Рис 2.4.
Рис 2.5.
2.5. Выводы
Нами были рассмотрены в том числе на практике, прикладные алгоритмы и методы генерации и моделирования сигналов, вероятностный алгоритм распознавания сигнала в белом Гауссовском шуме.
Получены практические навыки программирования тех или иных задач, оценена сложность алгоритмов.
Нами были рассмотрены, изучены и освоены основные методы использования графических библиотек Win32API в программировании на языках высокого уровня.
Заключение
Были рассмотрены теоретически понятия теории сигналов, классификация сигналов, алгоритмы распознавания сигналов в шуме и практическая реализация одного из них.
Были рассмотрены современные языки программирования, их достаточно мощный арсенал средств по организации и управлению графическими окнами и примитивами, а так же мат и стат. вычислениям.
Получены практические навыки программирования тех или иных задач по работе со случайными числами, генерацией сигналов, в том числе с аддитивным «белым шумом», оценена сложность алгоритмов.
Нами были рассмотрены, изучены и освоены основные методы работе с языками высокого уровня.
Были разработаны, протестированы и получены результаты по ряду программ с использованием API операционной системы.
Результаты проверены на корректность и соответствуют ожидаемым.
Получены практические навыки работы с указателями, ссылочными типами, и прочими динамическими и статическими структурами данных.
Приложение A. Текст тестирующей программы
// random_obj.cpp: определяет точку входа для приложения.
//
#include "stdafx.h"
#include "random_obj.h"
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <commctrl.h>
#include <string.h>
#include "rnd_test.h"
#define MAX_LOADSTRING 100
// Глобальные переменные:
HINSTANCE hInst; // текущий экземпляр
TCHAR szTitle[MAX_LOADSTRING]; // Текст строки заголовка
TCHAR szWindowClass[MAX_LOADSTRING]; // имя класса главного окна
int const maxobj = 100000;
// Отправить объявления функций, включенных в этот модуль кода:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int WINAPI _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: разместите код здесь.
MSG msg;
HACCEL hAccelTable;
// Инициализация глобальных строк
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_RANDOM_OBJ, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Выполнить инициализацию приложения:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_RANDOM_OBJ));
// Цикл основного сообщения:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// ФУНКЦИЯ: MyRegisterClass()
//
// НАЗНАЧЕНИЕ: регистрирует класс окна.
//
// КОММЕНТАРИИ:
//
// Эта функция и ее использование необходимы только в случае, если нужно, чтобы данный код
// был совместим с системами Win32, не имеющими функции RegisterClassEx'
// которая была добавлена в Windows 95. Вызов этой функции важен для того,
// чтобы приложение получило "качественные" мелкие значки и установило связь
// с ними.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_RANDOM_OBJ));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_RANDOM_OBJ);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
//
// ФУНКЦИЯ: InitInstance(HINSTANCE, int)
//
// НАЗНАЧЕНИЕ: сохраняет обработку экземпляра и создает главное окно.
//
// КОММЕНТАРИИ:
//
// В данной функции дескриптор экземпляра сохраняется в глобальной переменной, а также
// создается и выводится на экран главное окно программы.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Сохранить дескриптор экземпляра в глобальной переменной
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// ФУНКЦИЯ: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// НАЗНАЧЕНИЕ: обрабатывает сообщения в главном окне.
//
// WM_COMMAND - обработка меню приложения
// WM_PAINT -Закрасить главное окно
// WM_DESTROY - ввести сообщение о выходе и вернуться.
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Разобрать выбор в меню:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:{
int colors = 255;
int test = 1000000,
col = 5 * int(log(5.0 + 5*test));
double freq = 1e-5, phi = 0.5;
rnd_test r = rnd_test(test, col , colors, freq, phi); //РАНДОМ ТЕСТ
r.draw(hWnd); //и ЕГО ОТРИСОВКА
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Обработчик сообщений для окна "О программе".
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
#pragma once
#include<windows.h>
int static rnd_seed ;
static bool haveNextNextGaussian ;
static double nextNextGaussian;
class rnd_test
{
public:
rnd_test(void);
rnd_test(int test,int colons, int color, double fr, double ph);
~rnd_test(void);
void rnd_test::draw(HWND hWnd);
private:
static double rnd_test::rnd(); //0..1 uniform random generator
static void rnd_test::srnd(int seed); //init rnd
static double rnd_test::eyler(); // exp disrtibution with average = 1
static double rnd_test::next_gauss(); //normal (0,1)
static double rnd_test::uniform(double a,double b);//from a to b
static double rnd_test::normal(double m, double s); //normal light version
static double rnd_test::erlang(double m, double s); //erlang distrinbution
static double rnd_test::erl();
void rnd_test::distrib_run();
int rnd_test::getmax(int *data,int size);
int rnd_test::getmin(int *data,int size);
double rnd_test::signal_func(double x);
void rnd_test::distrib_test();
////////////////// данные
int testtime, colon_count,
colors, *colons;
double *data, mat,disp, timer, excess , assimetry , freq ,phi;
};
#include "StdAfx.h"
#include "rnd_test.h"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
rnd_test::rnd_test(void){
int defcol = 255,
defcolons = 50, deftest = 1000000 ;
double deffreq = 1e-5, def_phi = 0.5;
data = NULL;
colons = NULL;
rnd_test(deftest , defcolons , defcol, deffreq, def_phi);
}
rnd_test::~rnd_test(void){
if (data) free(data);
if (colons) free(colons);
}
rnd_test::rnd_test(int test,int colon, int color, double fr, double ph){
srnd(int(time(NULL)));
testtime = abs(test),
colon_count = abs(colon);
freq = fr;
phi = ph;