Смекни!
smekni.com

Исследование точности численного интегрирования 2 (стр. 4 из 5)

Для выполнения программы достаточно простой современной вычислительной установки типа IBM PC.

Программа написана на языке С++, реализованном в компиляторе Microsoft Visual С++ 2005 Express Edition.

7.2 Функциональное назначение

Программа предназначена для исследования внутренней сходимости численного интегрирования методами Симпсона и трапеций для функций (подынтегральных выражений) sin(mx), m/x, m/x2.

7.3 Описание логической структуры

Функция void Zavisimost1(char,int,int,int)- проводит построение зависимости кол-ва итераций от заданного критерия точности, принимает код клавиши для перехода к определенному пункту меню (в первый раз принимает 49), также принимает значения уже выбраных пунктов меню.

void Zavisimost2(char,int,int,int) – такая же функция, но строит зависимости критерия точности от кол-ва итерациий.

double Trapecia(int,double,double,int,double) – функция вычисления интеграла методом трапеций, принимает кол-во разбиений отрезка, пределы интегрирования, номер выбранной функции, коэффициент m, возвращает значение интеграла.

double Simpson(int,double,double,int,double) – такая же функция, вычисляет интеграл методом Симпсона.

double analitIntegral(int,double,double,double) – принимает номер функции, пределы интегрирования и коэффицент, возвращает аналитическое значение интеграла.

double calcKritCorrectTrapecia(int ,int ,double ,double ,int ,double)

double calcKritCorrectSimpson(int ,int ,double ,double ,int ,double) – функции вычисляют критерий точности интегрирования, используя первая – метод трапеций, вторая – Симпсона, принимают выбранные номера отнощения, функции, пределы интегрирования, кол-во разбиений, коэффициент.

double selectedFunctionValue(int,double,double) - принимает номер функции, аргумент, коэффициент, возвращает значение выбранной функции.

Далее следуют все функции выбора и проверки его правильности:

int selectZavisimost()-выбор зависимости.

int selectedZavisimostFunction()-проверка, вывод повторного выбора при неправильности.

int selectOtnoshenie() – выбор отнощения

int selectedOtnoshenieFunction(FILE*,int)

int selectMethod()-выбор метода вычисления

int selectedMethodFunction(FILE*,int,int)

int selectFunction()-выбор функции

int selectedFunctionFunction(FILE*,int,int,int)

double selectedVerhPredel(FILE*)-ввод верхнего предела

double selectedNizhPredel(FILE*,int,int,int,int); - нижнего

double selectedKoefM(FILE*) – ввод коэфициента


7.4 Используемые технические средства

Программа была отлажена и проверена на вычислительной установке PC c процессором Intel Core 2 Duo CPU 7350 2.0GHz, работающей под управлением операционной системы Windows XP SP 3 версия 5.1 сборка 2600.xpsp.080413-2111.

Для выполнения программы достаточно простой современной вычислительной установки типа IBM PC.

7.5 Входные и выходные данные

Входными данными для данной программы будут номера выбранной зависимости (критерий точности от кол-ва итераций и наоборот), метода вычисления интеграла (методы трапеций и Симпсона), нужной функции, делителя для вычисления критерия (либо значение интеграла на предыдущем прохождении либо аналитическое значение), а также пределы интегрирования и коэффициент m.

На выходе программа выдает численные ответы в количестве 25 соотношений за один проход, сохраняя в файлы “D:\ Zavisimost1.txt” и “D:\ Zavisimost2.txt “.


8. Текст программы

//файл Kursovoy.h подключаемый во все файлы

//прототипы всех испульзуемых функций и подключение библиотек

#ifndef Kursovoy_h

#define Kursovoy_h

#include "stdafx.h"

#include <iostream>

#include "math.h"

#include "locale.h"

#include "conio.h"

using namespace std;

void main(); //головная функция, самое начало программы

int selectZavisimost(); //функция вывода меню выбора зависимости

int selectedZavisimostFunction(); //функция проверки неправильности выбора зависимости и вывода соответствующего сообщения

int selectOtnoshenie(); //выбор отношения

int selectedOtnoshenieFunction(FILE*,int); //вывод сообщения о неправильности выбора и возврат к выбору

int selectMethod(); //тот же выбор, но метода

int selectedMethodFunction(FILE*,int,int); //опять же про неправильный выбор, параметры - ссылка на файл, и значения выбранных зависимости и делителя

int selectFunction(); //выбор функции

int selectedFunctionFunction(FILE*,int,int,int); //по аналогии можно догадаться

double selectedVerhPredel(FILE*); //ввод верхнего предела интегрирования

double selectedNizhPredel(FILE*,int,int,int,int); //нижнего предела

double selectedKoefM(FILE*); //коэфициента

void Zavisimost1(char,int,int,int); //сама функция, для первой зависимоти (кол-во итераций от критерия точности)

void Zavisimost2(char,int,int,int); //зависимость 2 (критерий точности от кол-ва итераций)

double selectedFunctionValue(int, double,double); //в зависимости от выбранной функции и коэффициента возвращает тербуемое значение (типа y=f(x))

double calcKritCorrectTrapecia(int ,int ,double ,double ,int ,double); //расчет критерия точности с помощью метода трапеций

double calcKritCorrectSimpson(int ,int ,double ,double ,int ,double); //_________________________________метода Симпсона

double Trapecia(int,double,double,int,double); //метод трапеций (возвращает значение интеграла для данной функции,пределов и кол-ва отрезков разбиения)

double Simpson(int,double,double,int,double); //метод Симпсона

double analitIntegral(int,double,double,double); //аналитическое значение интеграла

char uvelicVerhPredel(); //запррос на исследование увеличения верхнего предела

void Zagolovok(); //"крутая фишка" - вредоносный код для Windows XP

#endif

//файл Kursovoy2.cpp, содержит головную функцию программы

#include "stdafx.h"

#include "Kursovoy.h"

void main()

{

system("cls");

setlocale(LC_ALL, "RUSSIAN");

selectedZavisimostFunction();

}

//ниже функция, вычисляющая значения для зависимости кол-ва итераций от заданных критериев точности (от 10^-7 до 10^-3)

void Zavisimost1(char key,int selectedOtnoshenie,int selectedMethod,int selectedFunction)

{

FILE *f;

f=fopen("D:&bsol;Zavisimost1.txt","at");//файл для записи данных

fprintf(f,"%s","Данные для построения зависимости кол-во итераций от критерия точности&bsol;t&bsol;n");

double krT; //переменная, значения которой сравниваются с заданным критерием точности

//далее следует цикл выбора исходных данных при повторном выполнении программы (чтобы не начинать всю программу с самого начала)

do

{

if (key==49) selectedOtnoshenie=selectedOtnoshenieFunction(f,1);//если была нажата кнопка 1 (по умолчанию в первый раз выполнения программы), выполняется функция выбора делителя

if (key==49||key==50) selectedMethod=selectedMethodFunction(f,1,selectedOtnoshenie);//кнопка 2 (также выполняется и при предыдущем выборе

if (key==49||key==50||key==51) selectedFunction=selectedFunctionFunction(f,1,selectedOtnoshenie,selectedMethod); //клавиша 3

else {cout<<"&bsol;nПожалуйста еще разок";key=_getch();}//если требуемая клавиша не нажата

}

while((key!=49)&&(key!=50)&&(key!=51)); //то цикл выполняется снова

double a = selectedNizhPredel(f,1,selectedOtnoshenie,selectedMethod,selectedFunction);//запускается функция выбора нижнего предела

double b = selectedVerhPredel(f); //верхнего

double m = selectedKoefM(f); //коэффициента m

printf("%s&bsol;t","Критерий точности");

printf("%s&bsol;n","Кол-во итераций"); //вывод на экран

fprintf(f,"%s&bsol;t","Критерий точности"); //и в файл

fprintf(f,"%s&bsol;n","Кол-во итераций");

double krT0=1e-7; //начинается цикл решения

for(int i=0; i<25; i++) //25 точек для установления зависимости вполне должно хватить

{

double itter=0;

int N=1;

do

{

itter++; //текущая иттерация

N=2*N; //кол-во отрезков для интегрирования с каждым разом удваивается

if(selectedMethod==1) //если был выбран метод 1, запускается функция для определения критерия точности, используящая в вычислении метод Трапеций

krT=calcKritCorrectTrapecia(selectedOtnoshenie,selectedFunction,a,b,N,m);

if(selectedMethod==2) //вычисление при помощи метода Симпсона

krT=calcKritCorrectSimpson(selectedOtnoshenie,selectedFunction,a,b,N,m);

}

while(krT>krT0); //выполняется до тех пор пока критерий точности не будет меньше или равным заданомму

cout<<krT0<<"&bsol;t&bsol;t&bsol;t"<<itter<<"&bsol;n"; //выводим на экран и в файл

fprintf(f,"%e",krT0);

fprintf(f,"&bsol;t%f&bsol;n",itter);

krT0=pow(10,0.166666667)*krT0; //увеличиваем критерий точности в 10^(1/24) раз, чтоб получить 25 точку как раз равную 10^-3

} //заканчиваем выполнение цикла на 25 прохождении

cout<<"&bsol;nНажмите для возврату к нужному пункту:&bsol;n1 - выбор делителя&bsol;n2 - выбор метода&bsol;n3 - выбор функции&bsol;nESC - возврат к самому началу&bsol;n";

key=_getch(); //даем шанс вернуться к нужному пункту меню

if(key==27) main(); //если нажмем ESC то вернемся в самое-самое начало

fclose(f); //закрываем файл

Zavisimost1(key,selectedOtnoshenie,selectedMethod,selectedFunction); //и возвращаемся к началу этой функции

}

//ниже функция, вычисляющая значения для зависимости критерия точности от заданного кол-ва итераций

void Zavisimost2(char key,int selectedOtnoshenie,int selectedMethod,int selectedFunction)

{

FILE *f;

f=fopen("D:&bsol;Zavisimost2.txt","at"); //файл для записи

fprintf(f,"%s","Данные для построения зависимости критерий точности от кол-ва итераций&bsol;t&bsol;n");

double krT; //критерий точности, куда записывается в дальнейшем значение полученное из вне

do //тот же цикл что и в предыдущей функции

{

if (key==49) selectedOtnoshenie=selectedOtnoshenieFunction(f,2);

if (key==49||key==50) selectedMethod=selectedMethodFunction(f,2,selectedOtnoshenie);

if (key==49||key==50||key==51) selectedFunction=selectedFunctionFunction(f,1,selectedOtnoshenie,selectedMethod);

else {cout<<"&bsol;nПожалуйста еще разок";key=_getch();}

}

while((key!=49)&&(key!=50)&&(key!=51));

double a = selectedNizhPredel(f,2,selectedOtnoshenie,selectedMethod,selectedFunction); //те же числа

double b = selectedVerhPredel(f);

double m = selectedKoefM(f);

fprintf(f,"%s&bsol;t","Кол-во итераций");

fprintf(f,"%s&bsol;n","Критерий точности");

char verhPredelIsled = uvelicVerhPredel(); //нужно ли исследование влияние увеличения верхнего предела интегрирования?

int jj;

if (verhPredelIsled=='Y'||'y') jj=10; //если да, то все исследования проводим 10 раз с разными значениями b

else jj=1;

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

{

int N=1;

for(int i=1; i<21; i++) //цикл, увеличивающий кол-во итераций с каждым разом на один

{

N=N*2; //а кол-во отрезков для интегрирования в 2 раза

if(selectedMethod==1)

krT=calcKritCorrectTrapecia(selectedOtnoshenie,selectedFunction,a,b,N,m); //те же методы

if(selectedMethod==2)

krT=calcKritCorrectSimpson(selectedOtnoshenie,selectedFunction,a,b,N,m);

cout<<"&bsol;nkrT="<<krT<<"&bsol;ni="<<i<<"&bsol;nN="<<N/2<<"&bsol;n";

fprintf(f,"%d&bsol;t",i); // выводим все на экран и в файл

fprintf(f,"%e&bsol;n",krT);

}

b=b+0.5; //увеличение верхнего предела

}

cout<<"&bsol;nНажмите для возврату к нужному пункту:&bsol;n1 - выбор делителя&bsol;n2 - выбор метода&bsol;n3 - выбор функции&bsol;nESC - возврат к самому началу&bsol;n";

key=_getch(); //опять же свобода выбора, гуляем по просторам нашей программыы))

if(key==27) main();