">
Математика Геометрия
Информация о работе

Тема: Решение сложной функции методом половинного деления

Описание: Метод половинного деления. Фнализ графической функции. Последующие действия в программе. Математические процессы. График и решение функции в математическом процессоре Wolfram Alpha. Решение функции. Точность графика.
Предмет: Математика.
Дисциплина: Геометрия.
Тип: Курсовая работа
Дата: 16.08.2012 г.
Язык: Русский
Скачиваний: 0
Поднять уникальность

Похожие работы:

НИУ ИТМО  Курсовая работа  Решение сложной функции методом половинного деления      18.05.2012  

Функция - 

Метод половинного деления основывается на анализе графика, когда график делится пополам, и далее анализируется та часть, где находится решение (корень) функции. Обычно математически решение находится также анализом задаваемого промежутка, когда в дальнейшее рассмотрение берется та часть промежутка, на котором произведение значений функции на принадлежащем этой части конце промежутка и значении функции на середине промежутка имеет отрицательный знак. Однако, в данной работе для большей наглядности я использовал непосредственно анализ графической функции, выводимой на экран. Таким образом, решение функции находится пошагово и с участием пользователя.

Задача была реализована на языке C (версия языка C90, компилятор QuickC) с использованием подключаемой библиотеки “graph.h”.

Сначала программа запрашивает у пользователя первоначальные границы для построения графика. Далее инициализируется видеорежим ДОС для возможности графического вывода информации. По первоначально заданным пользователем границам (на оси Ох) рассчитываются границы по оси Оy. Задается реальная система координат (отрисовка графики теперь возможна с указанием реальных величин, а не пиксельных эквивалентов на экране). Далее запускается функция отрисовки основных и вспомогательных координатных осей и подписей к ним, и возвращается значение ширины одного пикселя на экране в реальных величинах (в которых и будет производиться расчет). После этого в цикле строится сам график функции, в процессе чего и определяется приблизительное решение функции визуально на графике, что также выводится пользователю на экран. Далее идет часть взаимодействия с пользователем: он может рассмотреть график вне текущей видимой области, переместив эту область с помощью стрелок на клавиатуре, либо уточнить текущее решение функции, нажав клавишу ‘d’. Это действие определит, в какой части графика находится решение функции, и уменьшит и отцентрирует его на решении, повысив точность этого самого решения (вышеуказанные способы взаимодействия вызывают функцию перерисовки координатных осей и целевой функции). Пользователь может увеличивать график до достижения точности в 0.0000001, либо до желаемой меньшей точности. Как показывает проверка на математических процессорах, программа высчитывает решение правильно в пределах своей точности. Выйти из программы можно, нажав клавишу ‘c’.

Окно программы после запуска

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

График и решение функции в математическом процессоре Wolfram Alpha

Исходный код программы:

#define M_E 2.718281828459 //e constant

#include

#include

#include

#include

double interface(double x_start, double x_finish, double y_min, double y_max, double *y_draw_x_line);

void redraw(double x_start, double x_finish, double y_min, double y_max, double *x_approx);

int main(void)

{

struct _fontinfo my_font;

struct videoconfig my_vc;

double x, x_start, x_finish, y_max, y_min, glass;

double previous_y_f, font_height;

double previous_x, cost_x, x_approx, y_draw_x_line;

int c;

char xapr[255];

printf("y=e^x -(x+0.5)^2 +1.2 !!! If graphic is stretched in X axis, roll it left !!! ");

printf("d key for divide, c key for exit arrow keys for navigation ")

printf("!!! Solution is in the middle of that segment !!! ");

printf("Enter x start and x finish ([-7;7] or less recommended) ");

printf("In case of bad input program will be SHUT DOWN! ");

while(1)

{fflush(stdin);

scanf("%lf%lf", &x_start, &x_finish);

if ((x_finish <= x_start)||(fabs(x_finish-x_start)>=20.0)||(x_finish>10.0)) //checking input for "good" x borders

{

puts("Input error. Please retry ");

continue;

}

_setvideomode(_VRES16COLOR); //setting up graphic DOS videomode

_getvideoconfig(&my_vc); //getting structure with videoinfo

y_max=pow(M_E,x_start)-pow((x_start+0.5),2)+1.2;

y_min=pow(M_E,x_start)-pow((x_start+0.5),2)+1.2;

for (x=x_start;x {

if (pow(M_E,x)-pow((x+0.5),2)+1.2>y_max) y_max=pow(M_E,x)-pow((x+0.5),2)+1.2;

if (pow(M_E,x)-pow((x+0.5),2)+1.2 }

_setwindow(1, x_start, y_min, x_finish, y_max); //setting up coordinats with growing up y and real numbers

previous_y_f = pow(M_E,x_start)-pow((x_start+0.5),2)+1.2;

previous_x = x_start;

cost_x = interface(x_start, x_finish, y_min, y_max, &y_draw_x_line); //getting size of one pixel and drawing an interface

for (x = x_start+cost_x; x <= x_finish + cost_x / 4.0; x += cost_x) //drawing function

{

_setcolor(4);//red

_moveto_w(previous_x, previous_y_f);

_lineto_w(x, pow(M_E,x)-pow((x+0.5),2)+1.2);//lining previous and current graphic points

previous_y_f = pow(M_E,x)-pow((x+0.5),2)+1.2; //vvv_counting approx. x in segment on X axis_vvv

if (previous_y_f>(y_draw_x_line-(y_max-y_min)/my_vc.numypixels)&&(previous_y_f<(y_draw_x_line+(y_max-y_min)/my_vc.numypixels))) x_approx=x;

previous_x = x;

}

_registerfonts("doslike.FON"); //registering font

_setfont("DOSLIKE");

_getfontinfo(&my_font);//getting structure with font properties

font_height = ((y_max - y_min) / my_vc.numypixels) * my_font.pixheight;

_setcolor(4);

_moveto_w(x_start + cost_x*5, y_max - font_height * 2);

if(y_min*y_max>0)sprintf(xapr,"approx. x undefined");//while X axis remain unseen approx. x is undefined

else sprintf(xapr,"approx. x=%g",x_approx);

_outgtext(xapr);//writing approximate x on the screen

_unregisterfonts();

while(c!=c)//c key is exit

{

c=getch();

switch (c)//scanning for key input

{ //moving screen to 1/4 of current coordinates to setted up direction

case 75://left

{ glass=x_start;

x_start-= (x_finish-x_start)/4;

x_finish-= (x_finish-glass)/4;

redraw(x_start, x_finish, y_min, y_max, &x_approx);

break;

}

case 77://right

{ glass=x_start;

x_start+= (x_finish-x_start)/4;

x_finish+= (x_finish-glass)/4;

redraw(x_start, x_finish, y_min, y_max, &x_approx);

break;

}

case 72://up

{ glass=y_max;

y_max+= (y_max-y_min)/4;

y_min+= (glass-y_min)/4;

redraw(x_start, x_finish, y_min, y_max, &x_approx);

break;

}

case 80://down

{ glass=y_max;

y_max-= (y_max-y_min)/4;

y_min-= (glass-y_min)/4;

redraw(x_start, x_finish, y_min, y_max, &x_approx);

break;

}

case d://enter ("divide")

{

glass=x_finish;

x_finish=x_approx+(x_finish-x_start)/4.0;

x_start=x_approx-(glass-x_start)/4.0; //dividing x by 2

y_max=pow(M_E,x_finish)-pow((x_finish+0.5),2)+1.2; //and choosing right y

y_min=pow(M_E,x_start)-pow((x_start+0.5),2)+1.2;

for (x=x_start;x {

if (pow(M_E,x)-pow((x+0.5),2)+1.2>y_max) y_max=pow(M_E,x)-pow((x+0.5),2)+1.2;

if (pow(M_E,x)-pow((x+0.5),2)+1.2 }

redraw(x_start, x_finish, y_min, y_max, &x_approx);

break;

}

}

}

fflush(stdin);

_clearscreen(_GWINDOW);//clearing screen

_setvideomode(_DEFAULTMODE);//returning to the console videomode

return 0;

}

}

double interface(double x_start, double x_finish, double y_min, double y_max, double *y_draw_x_line)

{//drawing axes and subaxes in the right x and y borders

struct _fontinfo my_font;

struct videoconfig my_vc;

double cost_x, cost_y, font_height, font_width, border_x, border_y;

double y_draw_x_text, legend, x,y, glass;

double x_draw_y_line;

char rab[255], rab_2[255], lgnd[255];

_getvideoconfig(&my_vc);

cost_x = (x_finish - x_start) / my_vc.numxpixels; //counting elementary

cost_y = (y_max - y_min) / my_vc.numypixels; //length of one pixel

border_x = cost_x * 5;//borders for unexpected

border_y = cost_y * 5;//graphic types (when we cannot see some of axises)

_registerfonts("doslike.FON");

_setfont("DOSLIKE");

_getfontinfo(&my_font);

font_height = cost_y * my_font.pixheight;

font_width = cost_x * my_font.pixwidth;

if (y_min > 0.0)

{

*y_draw_x_line = y_min + border_y;

y_draw_x_text = y_min + font_height * 2 + border_y;

} //

else if (y_max < 0.0) //what if axis is not within the screen

{ //

*y_draw_x_line = y_max - border_y;

y_draw_x_text = y_max - font_height - border_y;

}

else

{

*y_draw_x_line = 0.0;

if (fabs(y_min) > y_max)y_draw_x_text = 0.0;

else y_draw_x_text = font_height;

}

_setcolor(7);

_moveto_w(x_start, *y_draw_x_line); //OX axis

_lineto_w(x_finish, *y_draw_x_line);

_setcolor(1);

sprintf(rab, "x_min=%g", x_start);

_moveto_w(x_start, y_draw_x_text-font_height);

_outgtext(rab);

sprintf(rab, "x_max=%g", x_finish); //writing border values

_moveto_w(x_finish - cost_x * _getgtextextent(rab), y_draw_x_text-font_height); //

_outgtext(rab);

if (x_start > 0.0) x_draw_y_line = x_start + border_x;

else if (x_finish < 0.0) x_draw_y_line = x_finish - border_x;

else x_draw_y_line = 0.0;

_setcolor(7);

_moveto_w(x_draw_y_line, y_max);//OY axis

_lineto_w(x_draw_y_line, y_min);

_setcolor(5);

sprintf(rab, "y_max=%7.5g", y_max);

_moveto_w(x_draw_y_line-font_width*12.5, y_max);

_outgtext(rab);

sprintf(rab_2, "y_min=%7.5g", y_min);

_moveto_w(x_draw_y_line-font_width*12.5, y_min + font_height);

_outgtext(rab_2);

glass=fabs(x_finish-x_start);

for (x=x_start+glass/my_vc.numxpixels; x {

_setcolor(8);

_moveto_w(x,y_max);

_lineto_w(x,y_min);

_setcolor(1);

_moveto_w(x, y_draw_x_text);

if(glass>0.00005)sprintf(lgnd,"%-6.5g",x);

else sprintf(lgnd,"%-9.8g",x);

_outgtext(lgnd);

}

if (x_finish>0) {

_setcolor(7);

_moveto_w(0,y_max);

_lineto_w(0,y_min);

_moveto_w(0, y_draw_x_text);

_setcolor(1);

sprintf(lgnd,"0");

_moveto_w(0, y_draw_x_text);

_outgtext(lgnd);}

glass=fabs(y_max-y_min);

for (y=y_min+glass/my_vc.numypixels; y{

_setcolor(8);

_moveto_w(x_start,y);

_lineto_w(x_finish,y);

_setcolor(5);

if (x_finish<0) _moveto_w(x_draw_y_line-font_width*5.5, y);

else _moveto_w(x_draw_y_line, y);

sprintf(lgnd,"%-6.4g",y);

_outgtext(lgnd);

}

if(y_max*y_min<0){

_setcolor(7);

_moveto_w(x_start,0.0);

_lineto_w(x_finish,0.0);}

_unregisterfonts();

return cost_x;

}

void redraw(double x_start, double x_finish, double y_min, double y_max, double *x_approx)//redraw graphic function

{ struct _fontinfo my_font;

struct videoconfig my_vc;

double cost_x, previous_y_f, previous_x, x, y_draw_x_line, font_height;

char xapr[255];

_clearscreen(_GWINDOW);//clearing screen

_setwindow(1, x_start, y_min, x_finish, y_max); //also setting real coordinates

previous_y_f = pow(M_E,x_start)-pow((x_start+0.5),2)+1.2;

previous_x = x_start;

_getvideoconfig(&my_vc);

cost_x = interface(x_start, x_finish, y_min, y_max, &y_draw_x_line);//drawing interface

for (x = x_start+cost_x; x <= x_finish + cost_x / 4.0; x += cost_x/2.0)//drawing changed function

{

_setcolor(4);

_moveto_w(previous_x, previous_y_f);

_lineto_w(x, pow(M_E,x)-pow((x+0.5),2)+1.2);

previous_y_f = pow(M_E,x)-pow((x+0.5),2)+1.2; //vvv__also counting approx. x in the divided function__vvv

if (previous_y_f>=(y_draw_x_line-(y_max-y_min)/my_vc.numypixels)&&(previous_y_f<=(y_draw_x_line+(y_max-y_min)/my_vc.numypixels))) *x_approx=x;

previous_x = x;

}

_registerfonts("doslike.FON");

_setfont("DOSLIKE");

_getfontinfo(&my_font);

font_height = ((y_max - y_min) / my_vc.numypixels) * my_font.pixheight;

_setcolor(4);

_moveto_w(x_start + cost_x*5, y_max - font_height * 2);

if(y_min*y_max>0)sprintf(xapr,"approx. x undefined");

else sprintf(xapr,"approx. x=%-9.8g",*x_approx);

_outgtext(xapr);

_unregisterfonts();

return;}