- •В.В. Чуркин численные методы
- •Содержание
- •Нелинейных уравнений Краткие сведения
- •1 Метод деления пополам (метод дихотомии, метод бисекций)
- •2 Метод хорд
- •3 Метод касательных (метод Ньютона)
- •4 Метод секущих
- •5 Метод итераций
- •5 Комбинированные методы решений нелинейных уравнений
- •Решение нелинейных уравнений в системе Mathcad
- •Пример построения графика функции и решения нелинейного уравнения
- •Лабораторная работа 1
- •Задание
- •Контрольные вопросы
- •Краткие сведения
- •Интерполирование в системе Mathcad
- •Лабораторная работа 2
- •Содержание отчета
- •Контрольные вопросы
- •Краткие сведения Алгебра матриц
- •Алгоритмы формирования матриц
- •Методы разложения матриц
- •Методы обращения матриц
- •Операции с векторами и матрицами в системе Mathcad
- •Лабораторная работа 3
- •Задание
- •Содержание отчета
- •Контрольные вопросы
- •Методы решений систем линейных алгебраических уравнений (слау) Краткие сведения
- •Прямые методы решений слау Метод Гаусса
- •Метод ортогонализации строк
- •Метод решения системы с ленточными матрицами
- •Метод Холецкого
- •Метод квадратного корня Пусть требуется решить слау с симметрической положительно определенной матрицей Матрица приводится к виду где
- •Метод прогонки
- •Метод вращений
- •Итерационные методы решений слау
- •Метод релаксации
- •Вычисление матричных выражений
- •Пример решения слау в системе Mathcad
- •Лабораторная работа 4
- •Контрольные вопросы
- •Лабораторная работа 5
- •Контрольные вопросы
- •Краткие сведения
- •Выполнение аппроксимации (регрессии) в системе Mathcad
- •Пример проведения регрессий – линейной и линейной общего вида
- •Лабораторная работа 6
- •Задание
- •Содержание отчета
- •Контрольные вопросы
- •Краткие сведения
- •Вычисление первообразных и интегралов в системе Mathcad
- •Лабораторная работа 7
- •Задание
- •Варианты вычисляемых интегралов и методов (формул) вычислений представлены в таблицах 1 и 2
- •Контрольные вопросы
- •Краткие сведения
- •Метод интегрирования оду с помощью ряда Тейлора
- •Метод Эйлера
- •Метод Рунге-Кутта третьего порядка рк3
- •Ошибки методов
- •Интегрирование систем оду и оду высших порядков
- •Методы прогноза и коррекции
- •Первый вариант метода Адамса
- •Второй вариант метода Адамса
- •Метод на основе методов Милна и Адамса-Башфорта
- •Метод Хемминга
- •Интегрирование систем оду в системе Mathcad
- •Пример 2
- •Контрольные вопросы
Пример построения графика функции и решения нелинейного уравнения
Рис.1.13 – алгоритм комбинированного метода
хорд и касательных
Рис.1.14 – алгоритм комбинированного метода
деления пополам и итераций
Рис.1.15 – алгоритм расчета зависимости затрат машинного времени от задаваемой ошибки для метода деления пополам
Лабораторная работа 1
ИССЛЕДОВАНИЕ МЕТОДОВ РЕШЕНИЙ НЕЛИНЕЙНЫХ УРАВНЕНИЙ
Задание
1. В Mathcad’е по заданному из таблицы варианту (см.примечание) уравненияпостроить графикв диапазоне значений аргументаи найти значение корня(корней, если их несколько). Затем построить графикв диапазоне значений аргументаи нанести на график линии сетки так, чтобы одна из горизонтальных линий проходила через нуль по оси ординат.
Примечание: 1 – метод деления пополам, 2 – метод хорд, 3 – метод касательных, 4 – метод секущих, 5 – метод итераций.
2. Составить алгоритм и написать код для отделения корня (корней) уравнения в диапазоне значений аргумента с шагом
3. Составить алгоритм и написать код для уточнения значения корня (или одного из корней, если их несколько) заданным методом (методами). Получить таблицу и графики зависимостей временных затрат на уточнение корня от задаваемой погрешности (диапазон изменения). Пример алгоритма представлен на рис.1.15.
Таблица
Вариант |
Уравнение |
Используемый метод |
1 |
13 (комбинация) | |
2 |
24 (комбинация) | |
3 |
14 (комбинация) | |
4 |
25 (комбинация) | |
5 |
15 (комбинация) | |
6 |
135 | |
7 |
24 | |
8 |
123 | |
9 |
23 (комбинация) | |
10 |
45 | |
11 |
134 | |
12 |
23 | |
13 |
15 | |
14 |
35 | |
15 |
24 | |
16 |
12 | |
17 |
13 (комбинация) | |
18 |
15 (комбинация) | |
19 |
235 | |
20 |
145 | |
21 |
234 | |
22 |
13 | |
23 |
24 | |
24 |
14 | |
25 |
25 | |
26 |
13 | |
27 |
24 | |
28 |
123 | |
29 |
245 | |
30 |
13 (комбинация) |
Рассмотрим пример проектирования приложения для исследования методов деления пополам и секущих при решении нелинейного уравнения . Решение уравнения выполняют в два этапа.
Этап 1. Отделить корень (корни) уравнения в диапазоне значений аргумента с шагом.
Этап 2. Уточнить значение корня (или одного из корней, если их несколько) методами деления пополам и секущих. Получить таблицы и графики зависимостей временных затрат на уточнение корня от задаваемой погрешности (диапазон изменения).
Создайте для проектов приложений по численным методам папку (каталог) с именем ЧИСЛ_МЕТ и запустите C++Builder6.
Создайте новый проект командой Файл/Новый/Приложение.
Сохраните файлы модуля и проекта командой Файл/Сохранить всепод именамиLR1 иPR_LR1. Для этого удобно использовать соответствующую быструю кнопку (Сохранить все). В последующих сеансах работы сохраненный проект можно открыть командойФайл/Открыть проект (илиПовторно открыть). Теперь перейдем к проектированию приложения - переносам на форму необходимых компонентов и заданию их свойствам значений, а в обработчиках событий – размещению кодов соответствующих алгоритмов. (Рекомендуется нажимать кнопку Сохранить всепо окончании работы с каждым компонентом.) В результате проектирования получим форму, представленную на рис.1.16. Выделите форму, щелкнув на ней левой кнопкой мыши, и в свойствоCaption(надпись) впишитеМЕТОДЫ РЕШЕНИЙ НЕЛИНЕЙНЫХ УРАВНЕНИЙ.
Рис.1.16 – форма по окончании проектирования
В левый верхний угол формы поместите метку Label1(со страницыСтандартбиблиотеки компонентов). Выделив метку щелчком на ней, установите свойствоFont – жирный, размер 12. В свойствоCaptionметки впишите.
Ниже метки, по горизонтали, расположите на форме три метки: LabeledEdit1,LabeledEdit2иLabeledEdit3 (страницаДополнительно). Для всех трех меток свойствуLabelPosition присвойте значениеlpLeft(из выпадающего списка), свойству Font – жирный, размер 10, свойствуText – значения -5; 5; 0,1 соответственно. Раскрывая свойствоEditLabel, для всех трех меток установите подсвойствоFont – жирный, размер 10, а в подсвойствеCaptionвпишите соответственноxn=,xk=,dx=.
Ниже меток поместите кнопку Button1(страницаСтандарт), для которой установите свойство Font – жирный, размер 10, а в свойствоCaption впишитеОтделение корней.
Ниже кнопки поместите окно редактирования многострочного текста - компонент Memo1(страница Стандарт), для которого установите шрифтFont – обычный, размер 10.
Двойным щелчком на кнопке Button1перейдите в обработчик события – щелчка на кнопке. Перед обработчиком впишите определение функции, а в обработчик щелчка на кнопкеButton1поместите код алгоритма отделения корней (курсив):
//--------------------------------------------------
float f(float x)
{return 3*cos(2*x)+exp(-0.5*x)-2;}
//---------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
float xn,xk,dx,x,y,y1,a,b;
int m;
xn=StrToFloat(LabeledEdit1->Text);
xk=StrToFloat(LabeledEdit2->Text);
dx=StrToFloat(LabeledEdit3->Text);
x=xn; y=f(x); m=0;
Memo1->SetFocus();
Memo1->Clear();
AnsiString s;
P:x+=dx;
s="";
if(x>xk){s=s+"Всего корней: "+IntToStr(m);
Memo1->Lines->Add(s);
LabeledEdit4->SetFocus();
return;}
else
{ y1=f(x);
if(y*y1<=0) {m++; b=x; a=b-dx;
s=s+IntToStr(m)+"-й корень:";
if(a>=0)s=s+" a= ";
else s=s+" a=";
s=s+FloatToStrF(a,ffFixed,4,2);
if(b>=0)s=s+" b= ";
else s=s+" b=";
s=s+FloatToStrF(b,ffFixed,4,2);
Memo1->Lines->Add(s);}}
y=y1; goto P;
}
Кроме того, в этом же файле, файле LR1.cpp, после директивы #include "LR1.h" поместите директиву #include<math.h>.
Быстрой кнопкой “Переключатель Форма/Модуль F12”или клавишей F12вызовите на экран форму. Ниже окна редактированияMemo1поместите кнопкуButton2, в свойствоCaptionкоторой впишитеУточнение корня в промежутке жирным шрифтом размера 10.
В обработчике щелчка на кнопке Button2напишите (курсив):
void __fastcall TForm1::Button2Click(TObject *Sender)
{
StringGrid1->Cells[0][0]=" eps";
StringGrid1->Cells[1][0]=" корень x";
StringGrid1->Cells[2][0]=" f(x)";
StringGrid1->Cells[3][0]=" n";
StringGrid2->Cells[0][0]=" eps";
StringGrid2->Cells[1][0]=" корень x";
StringGrid2->Cells[2][0]=" f(x)";
StringGrid2->Cells[3][0]=" n";
}
Под кнопкой Button2по горизонтали разместите две меткиLabeledEdit (4 и 5). СвойствуLabelPosition меток присвойте значениеlpLeft(из выпадающего списка), свойству Font – жирный, размер 10, свойствуText- значения -5 и 5 соответственно. Раскрывая свойствоEditLabel, для обеих меток установите подсвойствоFont – жирный, размер 10, а в подсвойствеCaptionвпишите соответственноа=,b=.
Внизу формы, по всей ее ширине, разместите две таблицы - два компонента StringGrid1иStringGrid2(страницаДополнительно), а над ними – соответственно – кнопкиButton3 иButton4. В свойствоCaptionкнопок внесите соответственно (шрифтFont– жирный, размер 10)Метод деления пополамиМетод секущих, а в обработчиках щелчка на кнопках напишите коды соответствующих алгоритмов (курсив):
void __fastcall TForm1::Button3Click(TObject *Sender)
{ double a,b,c,d,eps,x,y,y1;
int n,i;
c=StrToFloat(LabeledEdit4->Text);
d=StrToFloat(LabeledEdit5->Text);
Series1->Clear();
for(eps=0.01,i=1;eps>0.000001;eps*=0.1,i++)
{ a=c; b=d;
n=0;
A: x=a;
y=f(x); n++;
x=(a+b)/2; y1=f(x); n++;
if(y*y1<=0) {if(fabs(x-a)>=eps){b=x; goto A;}}
else {if(fabs(x-b)>=eps){a=x; goto A;}}
StringGrid1->Cells[0][i]=FloatToStrF(eps,ffFixed,5,5);
StringGrid1->Cells[1][i]=FloatToStrF(x,ffFixed,9,8);
StringGrid1->Cells[2][i]=FloatToStrF(y1,ffExponent,5,2);
StringGrid1->Cells[3][i]=IntToStr(n);
Series1->AddXY(eps,n,"",clBlack);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{ double a,b,eps,x0,x1,y0,y1,t;
int n,i;
a=StrToFloat(LabeledEdit4->Text);
b=StrToFloat(LabeledEdit5->Text);
Series2->Clear();
for(eps=0.01,i=1;eps>0.000001;eps*=0.1,i++)
{ x0=a; x1=b;
y0=f(x0); y1=f(x1); n=2;
do{
t=y1/((y1-y0)/(x1-x0));
x0=x1; x1-=t;
y0=y1; y1=f(x1); n++;
}while(fabs(t)>=eps);
StringGrid2->Cells[0][i]=FloatToStrF(eps,ffFixed,5,5);
StringGrid2->Cells[1][i]=FloatToStrF(x1,ffFixed,9,8);
StringGrid2->Cells[2][i]=FloatToStrF(y1,ffExponent,5,2);
StringGrid2->Cells[3][i]=IntToStr(n);
Series2->AddXY(eps,n,"",clBlue);
}
}
Теперь файл LR1.cppбудет выглядеть следующим образом:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "LR1.h"
#include<math.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
float f(float x)
{return 3*cos(2*x)+exp(-0.5*x)-2;}
//---------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{float xn,xk,dx,x,y,y1,a,b;
int m;
xn=StrToFloat(LabeledEdit1->Text);
xk=StrToFloat(LabeledEdit2->Text);
dx=StrToFloat(LabeledEdit3->Text);
x=xn; y=f(x); m=0;
Memo1->SetFocus();
Memo1->Clear();
AnsiString s;
P:x+=dx;
s="";
if(x>xk){s=s+"Всего корней: "+IntToStr(m);
Memo1->Lines->Add(s);
LabeledEdit4->SetFocus();
return;}
else
{ y1=f(x);
if(y*y1<=0) {m++; b=x; a=b-dx;
s=s+IntToStr(m)+"-й корень:";
if(a>=0)s=s+" a= ";
else s=s+" a=";
s=s+FloatToStrF(a,ffFixed,4,2);
if(b>=0)s=s+" b= ";
else s=s+" b=";
s=s+FloatToStrF(b,ffFixed,4,2);
Memo1->Lines->Add(s);}}
y=y1; goto P;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{StringGrid1->Cells[0][0]=" eps";
StringGrid1->Cells[1][0]=" корень x";
StringGrid1->Cells[2][0]=" f(x)";
StringGrid1->Cells[3][0]=" n";
StringGrid2->Cells[0][0]=" eps";
StringGrid2->Cells[1][0]=" корень x";
StringGrid2->Cells[2][0]=" f(x)";
StringGrid2->Cells[3][0]=" n";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
double a,b,c,d,eps,x,y,y1;
int n,i;
c=StrToFloat(LabeledEdit4->Text);
d=StrToFloat(LabeledEdit5->Text);
Series1->Clear();
for(eps=0.01,i=1;eps>0.000001;eps*=0.1,i++)
{ a=c; b=d;
n=0;
A: x=a;
y=f(x); n++;
x=(a+b)/2; y1=f(x); n++;
if(y*y1<=0) {if(fabs(x-a)>=eps){b=x; goto A;}}
else {if(fabs(x-b)>=eps){a=x; goto A;}}
StringGrid1->Cells[0][i]=FloatToStrF(eps,ffFixed,5,5);
StringGrid1->Cells[1][i]=FloatToStrF(x,ffFixed,9,8);
StringGrid1->Cells[2][i]=FloatToStrF(y1,ffExponent,5,2);
StringGrid1->Cells[3][i]=IntToStr(n);
Series1->AddXY(eps,n,"",clBlack);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{ double a,b,eps,x0,x1,y0,y1,t;
int n,i;
a=StrToFloat(LabeledEdit4->Text);
b=StrToFloat(LabeledEdit5->Text);
Series2->Clear();
for(eps=0.01,i=1;eps>0.000001;eps*=0.1,i++)
{ x0=a; x1=b;
y0=f(x0); y1=f(x1); n=2;
do{
t=y1/((y1-y0)/(x1-x0));
x0=x1; x1-=t;
y0=y1; y1=f(x1); n++;
}while(fabs(t)>=eps);
StringGrid2->Cells[0][i]=FloatToStrF(eps,ffFixed,5,5);
StringGrid2->Cells[1][i]=FloatToStrF(x1,ffFixed,9,8);
StringGrid2->Cells[2][i]=FloatToStrF(y1,ffExponent,5,2);
StringGrid2->Cells[3][i]=IntToStr(n);
Series2->AddXY(eps,n,"",clBlue);
}
}
//---------------------------------------------------------------------------
Установим в компонентах StringGrid1иStringGrid2 следующие значения свойств: шрифтFont – обычный, размер 10,ColCount – 4, RowCount – 5, FixedCols– 0,FixedRows – 1, FixedColor – clWhite, ScrollBars –ssNone.
В правую верхнюю часть формы поместите компонент Chart1(страницаAdditional). Установим в нем те значения свойств, которые могут быть заданы или известны к данному моменту времени. Щелкните правой кнопкой мыши на компонентеChart1и в появившемся меню выберитеEdit Chart…. На экране появится окноРедактора Диаграмм(Editing Chart1) с открытой страницейChart,которая имеет несколько закладок. На закладкеPanel, нажав кнопкуPanel Color…, выберите белый цвет. На закладкеSeries щелкните на кнопкеAdd…- добавить серию. В появившемся окне выберите тип графика –Line и выключите индикатор3D. После щелчка наOKснова появится окноEditing Chart1. Перейдите на закладкуTitles. В окне редактирования, которое в данный момент соответствуетTitle– заголовку графика, сотритеTChartи напишите (шрифтFont…- черный, жирный, размер 10)Зависимости временных затрат от ошибки. В группе кнопокAlignment оставьте нажатой кнопку Center. Цвет фонаBack Color.. установите белый. В выпадающем списке от окна редактированияTitle перейдите в окно редактированияFootи напишите тем же шрифтомошибка eps. В группе кнопокAlignment нажмите кнопку Right. Цвет фонаBack Color.. также установите белый. Перейдите на закладкуAxisдля задания координатных характеристик осей. Оставьте в группеAxisнажатой кнопкуLeftи включенным индикаторAutomatic. Затем нажмите в группеAxisкнопкуBottom, выключите индикаторAutomatic и включите индикатор Logarithmic. Нажмите нижнюю кнопкуChange…и в окнеValue редактораMinimum Bottom Axisвпишите значение 0,00001. Аналогичные действия выполните с верхней кнопкойChange…, но впишите число 0,01. Затем перейдите на закладкуLabelsи в окне редактированияValues Formatзначение # ##0,### замените, добавив в него справа ##, на значение # ##0,#####. Перейдите на закладку Series, кнопкойAdd…добавьте еще один график Lineпри выключенном индикаторе3D. ВыделивSeries 1, кнопкойTitle… вызовитеChange Series Title, где дайте заголовок первому графику –Методделения пополам. Действуя подобным образом, т.е. выделивSeries 2, дайте заголовок второму графику –Метод секущих. На вкладкеLegendнажмите кнопкуTop. Перейдите со страницы Chartна страницуSeries. Здесь на закладкеFormatзадают параметры линий графиков. Требуемый график (Методделения пополам,Метод секущих) выбирается из выпадающего списка. В группеLineчерез кнопкуBorder…устанавливается толщина (Width) линии графика, а через кнопкуColor…- цвет линии графика. Для обоих графиков следует выключить индикаторColor Each. Задайте для первого графика тройную толщину линии черного цвета, для другого – двойную толщину линии черного цвета.
Рис.1.17 – результаты выполнения задания
Выше на закладке Axisзадавались координатные характеристики осей. При этом в группеAxisпри нажатой кнопкеLeftбыл оставлен включенным индикаторAutomatic, поскольку по оси ординат (Left) неизвестен диапазон откладываемых значенийn. Чтобы установить его и этим завершить проектирование приложения, запустим приложение на выполнение, нажав быстрые кнопкиСохранить всеиЗапуск. (Забегая вперед, приведем форму по окончании выполнения задания – рис.1.17).
После компиляции щелкните на кнопке Отделение корней. Результат отделения корней будет выведен вMemo1. Введите границы промежутка для одного из корней, например,a=0,5b=0,6. Щелкните на кнопкеУточнение корня в промежутке, что вызовет появление заголовков таблиц. Затем щелкните на кнопкахМетод деления пополамиМетод секущих. Из таблиц видно, что максимальное значениеnоказалось равным 28.
Щелкните на кнопке формы “Закрыть”, чтобы продолжить проектирование приложения. Вернитесь к заданию координатных характеристик осей компонентаChart1 на закладкеAxis. В группеAxisпри нажатой кнопкеLeftвыключите индикаторAutomatic. Нажав нижнюю кнопкуChange…, выставите минимальное значение, равное 0, а затем при нажатой верхней кнопкеChange…выставите максимальное значение, равное 30. На этом проектирование приложения завершается.
Сохранив изменения, запустите проект на выполнение. Результаты выполнения задания представлены на рис.1.17.
Для завершения работы щелкните на кнопке формы “Закрыть” и выйдите из средыBuilder.
Содержание отчета
Задание
Формулы и иллюстрации методов
Результаты выполнения задания в Mathcad’е .
Блок-схема алгоритма с таблицей идентификаторов
Исходный код
Результаты выполнения работы в виде таблицы и графиков.
Библиографический список.