//Подключение графики и проверка
int g_driver=9,g_mode=2, g_error;
initgraph(&g_driver,&g_mode,"c:\\BORLAND\\bgi");
g_error=graphresult();
if(g_error!=grOk)
{
puts("error");
printf("\n error=%d, reason=%s\n", g_error, grapherrormsg(g_error));
getch();
exit(1);
}
closegraph();
//Проверка или создание файла
FILE *fail;
if((fail = fopen("form.txt", "r")) == NULL)
if((fail = fopen("form.txt", "w")) == NULL)
{
clrscr();
printf("Ошибка при открытии файла");
getch();
exit;
}
fclose(fail);
//Графическое меню
menu:
initgraph(&g_driver,&g_mode,"c:\\BORLAND\\bgi");
cleardevice();
setbkcolor(5);
setfillstyle(7,8); bar(0,0,getmaxx(),getmaxy());
setfillstyle(1,1); bar(200,45,465,145);
setfillstyle(1,15); bar(203,48,462,142);
setfillstyle(1,1); bar(206,51,459,139);
setcolor(11);
settextstyle(7,0,8);
outtextxy(220,40,"Menu");
setcolor(7);
settextstyle(1,0,4);
outtextxy(100,200,"1.Formyla");
outtextxy(100,240,"2.Reshenie");
outtextxy(100,280,"3.Graphic");
outtextxy(100,320," Exit");
settextstyle(2,0,5);
outtextxy(500,440,"beta ver. 101 c");
settextstyle(1,0,4);
// Выбор пункта меню
if(st==1) goto d1;
else if(st==11) goto d11;
else if(st==12) goto d12;
else if(st==2) goto d2;
else if(st==3) goto d3;
else if(st==4) goto d4;
d1:
setcolor(2);
outtextxy(100,200,"1.Formyla");
setcolor(7);
outtextxy(100,240,"2.Reshenie");
outtextxy(100,320," Exit");
if(W==0)
{
W=1;
setfillstyle(7,1);
for(i=0;i<35;i++)
{
bar(280+i*7,190,287+i*7,260);
delay(5);
}
setfillstyle(7,8);
}
outtextxy(300,185,"Enter");
outtextxy(300,215,"Open in fails");
vst=getch();
if(vst==72)
{
st=4;
for(i=0;i<35;i++)
{
bar(530-i*7,190,523-i*7,260);
delay(5);
}
goto izm;
}
else if(vst==80)
{
st=2;
for(i=0;i<35;i++)
{
bar(530-i*7,190,523-i*7,260);
delay(5);
}
goto izm;
}
else if(vst==77) { st=11; goto izm; }
else goto d1;
d11:
setfillstyle(7,1);
bar(280,190,530,260);
setfillstyle(7,8);
setcolor(2);
outtextxy(300,185,"Enter");
setcolor(7);
outtextxy(100,200,"1.Formyla");
outtextxy(100,240,"2.Reshenie");
outtextxy(100,320," Exit");
outtextxy(300,215,"Open in fails");
vst=getch();
if(vst==72) { st=12; goto izm; }
else if(vst==80) { st=12; goto izm; }
else if(vst==75) { st=1; goto izm; }
else if(vst==13) { vv=1; vv1=1; closegraph(); goto resh; }
else goto d11;
d12:
setfillstyle(7,1);
bar(280,190,530,260);
setfillstyle(7,8);
setcolor(2);
outtextxy(300,215,"Open in fails");
setcolor(7);
outtextxy(100,200,"1.Formyla");
outtextxy(100,240,"2.Reshenie");
outtextxy(100,320," Exit");
outtextxy(300,185,"Enter");
vst=getch();
if(vst==72) { st=11; goto izm; }
else if(vst==80) { st=11; goto izm; }
else if(vst==75) { st=1; goto izm; }
else if(vst==13) { vv=1; vv1=2; closegraph(); goto resh; }
else goto d12;
d2:
setfillstyle(1,5);
setfillstyle(7,8);
bar(280,160,600,400);
setcolor(2);
outtextxy(100,240,"2.Reshenie");
setcolor(7);
outtextxy(100,200,"1.Formyla");
outtextxy(100,280,"3.Graphic");
vst=getch();
if(vst==13) { vv=2; closegraph(); goto resh; }
else if(vst==72) { st=1; W=0; goto izm; }
else if(vst==80) { st=3; goto izm; }
else goto d2;
d3:
setcolor(2);
outtextxy(100,280,"3.Graphic");
setcolor(7);
outtextxy(100,240,"2.Reshenie");
outtextxy(100,320," Exit");
vst=getch();
if(vst==13) { vv=3; closegraph(); goto resh; }
else if(vst==72) { st=2; goto izm; }
else if(vst==80) { st=4; goto izm; }
else goto d3;
d4:
setfillstyle(1,5);
setfillstyle(7,8);
bar(280,160,600,400);
setcolor(2);
outtextxy(100,320," Exit");
setcolor(7);
outtextxy(100,200,"1.Formyla");
outtextxy(100,240,"2.Reshenie");
outtextxy(100,280,"3.Graphic");
vst=getch();
if(vst==13) { vv=4; closegraph(); goto resh; }
else if(vst==72) { st=3; goto izm; }
else if(vst==80) { st=1; W=0; goto izm; }
else goto d4;
//Ввод данных
resh:
if(vv==1)
{
if(vv1==1)
{
C1=0;C2=0;C3=0;C4=0;
clrscr();
printf("\n\n Выбор формулы решения\n");
for(i=1;i<10;i++)
formyl(i);
printf("\n\n нажмите любой номер: ");
while(2)
{
nom=getch()-48;
if((nom>0)&(nom<10))
break;
}
while(3)
{
clrscr();
printf("\n поокончаниивводаконстантнажать - Esc");
printf("\n\n выбронная формула имеет вид\n ");
formyl(nom);
printf("\n\n\n\n ввод констант в формулу дифференциального уравнения:\n\n ");
formyl2(nom,C1,C2,C3,C4);
printf("\n\n\n C");
i=getch();
if(i==49)
{
printf("1 = ");
scanf("%lf",&C1);
}
else if(i==50)
{
printf("2 = ");
scanf("%lf",&C2);
}
else if(i==51)
{
printf("3 = ");
scanf("%lf",&C3);
}
else if(i==52)
{
printf("4 = ");
scanf("%lf",&C4);
}
else if(i==27)
{
break;
}
}
AB:
clrscr();
printf("\n\n\n выброннаяформулаимеетвид\n ");
formyl(nom);
printf("\n\n\n\n ввод констант в формулу дифференциального уравнения:\n\n ");
formyl2(nom,C1,C2,C3,C4);
printf("\n\n\n уточните границы изменения Х, от A= ");
scanf("%lf",&A);
clrscr();
printf("\n\n\n выбронная формула имеет вид\n ");
formyl(nom);
printf("\n\n\n\n ввод констант в формулу дифференциального уравнения:\n\n ");
formyl2(nom,C1,C2,C3,C4);
printf("\n\n\n уточните границы изменения Х, от A= %.2f до B= ",A);
scanf("%lf",&B);
if(B<=A)
{
printf("\n\n неправильно заданны границы!!! ");
delay(1000);
goto AB;
}
clrscr();
printf("\n\n\n выбронная формула имеет вид\n ");
formyl(nom);
printf("\n\n\n\n ввод констант в формулу дифференциального уравнения:\n\n ");
formyl2(nom,C1,C2,C3,C4);
printf("\n\n\n уточните границы изменения Х, от A= %.2f до B= %.2f",A,B);
printf("\n задайте начальное значение Y(%.2f) = ",A);
scanf("%lf",&y[0]);
printf("\n\n сохранить данные в файле (Да/Нет) ");
while(11)
{
i=getch();
if((i==76)||(i==108)||(i==132)||(i==164))
{
printf("Да");
delay(300);
fopen("form.txt", "w");
fwrite(&nom,1,2,fail);
fwrite(&C1,1,8,fail);
fwrite(&C2,1,8,fail);
fwrite(&C3,1,8,fail);
fwrite(&C4,1,8,fail);
fwrite(&A,1,8,fail);
fwrite(&B,1,8,fail);
fwrite(&y[0],1,8,fail);
fclose(fail);
break;
}
else if((i==89)||(i==121)||(i==141)||(i==173))
{
printf("Нет");
delay(300);
break;
}
}
goto menu;
}
if(vv1==2)
{
fopen("form.txt", "r");
fread(&nom,1,2,fail);
fread(&C1,1,8,fail);
fread(&C2,1,8,fail);
fread(&C3,1,8,fail);
fread(&C4,1,8,fail);
fread(&A,1,8,fail);
fread(&B,1,8,fail);
fread(&y[0],1,8,fail);
fclose(fail);
clrscr();
printf("\n\n\n выбраннаяформулаимеетвид\n");
formyl(nom);
printf("\n\n\n\n ввод констант в формулу дифференциального уравнения:\n\n ");
formyl2(nom,C1,C2,C3,C4);
printf("\n\n\n уточните границы изменения Х, от A= %.2f до B= %.2f",A,B);
printf("\n задайте начальное значение Y(%.2f) = %.2f",A,y[0]);
printf("\n\n\n\n данные были прочитаны из ранее сохраненного файла");
getch();
goto menu;
}
}
//Решение примера
else if(vv==2)
{
if((A==0)&(B==0))
{
clrscr();
printf("\n\n\n\n Сперва необходимо записать пример!");
delay(2000);
goto menu;
}
clrscr();
printf("\n\n\n для решения этой задачи нужно:\n\n");
printf("задать количество отрезков, на которое разделится\n промежуток AB=[%.2f,%.2f] N= ",A,B);
scanf("%d",&N);
ii=B; jj=A;
h=(B-A)/N;
N++;
for(i=0;i<N;i++)
{
x[i]=A+h*i;
y[i+1]=formyl3(nom,h,x[i],y[i],C1,C2,C3,C4);
}
clrscr();
printf("\n\n\n Решение задачи:\n\n");
printf("\n");
printf(" ¦ i ¦ x=h*i ¦ y(i) ¦\n");
printf("\n");
for(i=0;i<N; i++)
printf(" ¦ %3d ¦ %11lf ¦ %14f ¦ \n",i+1,x[i],y[i]);
printf(" L========¦===================¦========================-\n");
getch();
}
//график
else if(vv==3)
{
if(N==0)
{
clrscr();
printf("\n\n\n\n Сперва необходимо решить пример!");
delay(2000);
goto menu;
}
initgraph(&g_driver,&g_mode,"c:\\BORLAND\\bgi");
cleardevice();
setbkcolor(0);
setcolor(11);
settextstyle(4,0,5);
outtextxy(100,280,"Open graphic...");
setfillstyle(1,7);
bar(218,238,422,252);
setfillstyle(1,5);
bar(220,240,420,250);
setcolor(9);
for(i=0;i<200;i=i+2)
{
line(221+i,241,221+i,249);
delay(10);
}
M=5;
while(31)
{
// фон
clrscr();
cleardevice();
setbkcolor(0);
setcolor(10);
settextstyle(5,0,4);
// Вывод данных по графику
printf(" выход в меню - Esc");
printf("\n график дифференциального уравнения - ");
formyl2(nom,C1,C2,C3,C4);
printf("\n построенный с шагом h = %f",h);
printf(" на промежутке от %.2f до %.2f",A,B);
printf("\n выполненный в масштабе %.4f: 1",M);
printf("\n\n найти решение в точке - Enter");
printf("\n изменение масштаба увеличить - +");
printf("\n уменьшить - -");
// обводка слов
setcolor(3);
line(455,0,630,0);
line(455,15,630,15);
line(455,0,455,15);
line(630,0,630,15);
setcolor(9);
// оси
setcolor(10);
line(50,250,600,250);
line(580,245,600,250);
line(580,255,600,250);
line(325,50,325,440);
line(325,50,330,70);
line(325,50,320,70);
setcolor(15);
settextstyle(1,0,1);
outtextxy(600,260,"X");
outtextxy(345,50,"Y");
outtextxy(300,260,"O");
// единичные насечки
if(M>4)
for(i=1;i<70;i++)
{
if(i*M<=255)
{
line(325+M*i,248,325+M*i,252);
line(325-M*i,248,325-M*i,252);
}
if(i*M<=170)
{
line(323,250-M*i,327,250-M*i);
line(323,250+M*i,327,250+M*i);
}
}
//Выход из программы
else if(vv==4)
{
exit(2);
}
//Ввод программы в бесконечный цикл
goto menu;
}
Приложение 1. Результаты работы программы
Приведем расчет дифференциального уравнения первого, второго и третьего порядка методом Эйлера
1. Пусть дано дифференциальное уравнение первого порядка: y/ =2x-y
Требуется найти решение на отрезке [0,1] c шагом h=(1-0)/5=0,2
Начальные условия: у0 =1;
Пользуясь рекуррентными формулами (4), находим:
1) x1 =0,2; х1/2 =0,1; y(x1 )=y(x0 )+б0 h; y(x1/2 )=y(x0 )+f(x0 ,y0 )h/2;
f(x0 ,y0)=2*0-1=-1
y(x1/2)=1-1*0,1=0,9
б0 =2*0,1-0,9=-0,7
y1 =1-0,1*0,2=0,86
2).y (x2) = y(x1 )+б1 h; x2 =0,2+0,2=0,4; x1+1/2 =x1 +h/2=0,2+0,1=0,3
н (x1+1/2 )=y(x1 )+f(x1 ,y(x1 ))h/2
f (x1 ,y1 )=2*0,2-0,86=-0,46
y(x1+1/2 )=0,86-0,46*0,1=0,814
б1 =2*0,3-0,814=-0,214
y2 =0,86-0,214*0,2=0,8172
3). x3 =0,4+0,2=0,6; x2+1/2 =x2 +h/2=0,4+0,1=0,5
f(x2 ,y2 )=2*0,4-0,8172=-0,0172
y2+1/2 =0,8172-0,0172*0,1=0,81548
б2 =2*0,5-0,81548=0,18452
y3 =0,8172+0,18452*0,2=0,854104
4).x4 =0,8; x3+1/2 =x3 +h/2=0,6+0,1=0,7
f(x3 ,y3 )=2*0,6-0,854104=0,345896
y3+1/2 =0,854104+0,345896*0,1=0,8886936
б3 =2*0,7-0,89=0,5113064
y4 =0,854104+0,5113064*0,2=0,95636528
5).x5 =1; x4+1/2 =0,8+0,1=0,9
f(x4 ,y4 )=2*0,8-0,956=0,64363472
y4+1/2 =0,956+0,643*0,1=1,020728752;
б4 =2*0,9-1,02=0,779271248
y5 =0,956+0,7792*0,2=1,11221953
4. Описание программы
Программа весьма проста. В ней много предусмотрено моментов неправильного ввода данных, о которых программа предупреждает пользователя и сразу же просит повторно ввести данные.
С самого начала программа предоставляет пользователю меню выполняемых функций, которые выделяются при помощи стрелок ^ и v выбор клавишей Enter:
Formyla -> Enter
-> Open in fails
Reshenie
Graphic
Exit
После запуска программы нужно выбрать Formyla -> Enter, эта опция позволит из предложенного списка формул выбрать одну, по которой компьютер будет производить расчет и строить график. Все предложенные формулы имеют номерацию; чтобы выбрать интересующий вас пример нажмите на цифру равную номеру примера, и сразу же появится новое окно, в котором сверху будет записан ваш пример. Также в окне будет этот же пример но с нулями на месте констант. Под примером будет высвечена большая буква С, это используется для ввода констант. Для этого вам нужно нажать номер константы, он появится, и после знака равно запишите чему она равна (вводятся целые и вещественные значения). По окончании набора нажать Enter. Операцию повторять пока не будут введены все числа. По окончании нажать Esc. После появится строчка «уточните границы изменения Х, от A= до B= » здесь нужно занести данные на каком промежутке абсциссы будет рассматриваться функция. Следующая строчка попросит ввести начальные данные y(A)=. Следующей строчкой будет вопрос: «сохранить данные в файле? Да/Нет» ответить на этот вопрос с помощью клавиш Д и Н (рус), после чего программа вернется в первоначальное меню. Если данные были сохранены (в папке с программой появляется файл form.txt), то в следующий раз чтобы не набирать снова выберите в меню опцию Formyla -> Open in fails и на экране появятся введенные данные с пометкой снизу, сообщая что данные были прочитаны из файла.
Следующая опция Reshenie. После нажатия в окне просят ввести N(целое число) - число промежутков, на которые разделится рассматриваемый участок (ось ОХ). После появится таблица рассчитанных данных (номер точки, значение абсциссы, значение ординаты). При нажатии любой клавиши произойдет переход в меню.
Graphic эта опция позволяет визуально видеть решение, а так же на этом графике прописываются все данные: начальная формула, шаг и промежуток построения графика, масштаб, данные об его изменении(клавишами +(увеличить) и -(уменьшить), а также возможность определить точное значение функции в любой точке.
Опция Exit применяется для выхода из программы.
Результатом выполнения курсового проекта является готовый программный продукт, позволяющий решать дифференциальные уравнения по методу Эйлера, демонстрирующий возможности численного решения поставленной задачи с заданной степенью точности.
Программа решает заданную пользователем дифференциальное уравнение за минимальный промежуток времени. При этом пользователю предоставляется возможность визуально оценить решение, рассматривая график полученного решения.
К достоинствам программы можно отнести также удобный пользовательский интерфейс, возможность ввода пользовательских дифференциальных уравнений, а также довольно высокая стабильность работы. Однако имеются и некоторые недостатки. К недостаткам программы можно отнести: критичность к вводимым пользователем уравнений, отсутствие обработки исключительных событий. Это, естественно, ограничивает возможности программы.
Цель, выводы по задачам
1 Лапчик М.П. Численные методы: Учебное пособие для студенческих вузов - М.: Издательский центр «Академия», 2004
2. Ракитин В.И., Первушин В.Б. Практическое руководство по методам вычислений c приложением программ для персональных компьютеров