Файл: Лабораторна робота 15.doc

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 14.09.2024

Просмотров: 22

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Лабораторна робота №15. Алгоритми пошуку коренів рівнянь

Мета роботи : вивчити алгоритми пошуку коренів нелінійних рівнянь алгебри із заданою точністю.

15.1. Короткі теоретичні відомості

Одним з найчастіше використовуваних обчислювальних методів є метод ітерацій і різні його модифікації.

Ітераційні методи засновані на побудові такою, що сходиться до точного рішення х* нескінченної рекурентної послідовності х0, х1, ., хk  х* при k  ∞.

Послідовність називається рекурентною порядку m, якщо кожен наступний її член виражається через m попередніх за деяким правилом:

хk = (хk1, хk2, …, хkm). (15.1)

Такий метод називається m -шаговим. Для його реалізації вимагається задати m перших членів {х0, х1, ., хm(1}, званих початковим наближенням. Знаючи початкове наближення, по формулі (15.1) послідовно знаходять хm, хm+1, ..., хk, …. Процес отримання наступного k -го члена через попередні називається k -ою ітерацією. Ітерації виконуються до тих пір, поки черговий член хk не задовольнятиме заданої точності, тобто доки не виконається умова | хkхk1 | < , де  - деяка задана мала величина. В якості шуканого рішення беруть останній член послідовності хk, при якому виконалася вказана нерівність.

Щоб використовувати ітераційний метод, початкове завдання перетворять до виду, дозволеного відносно х :

х = (х). (15.2)

При цьому точне рішення початкової задачі х* є і рішенням (15.2).

Використовуємо вираження (15.2) як рекурентну формулу (m = 1) :

хk = (хk1).

Далі, задавши одно х0 (початкове наближення), послідовно знаходимо х1, х2, ., хk. Якщо отримана таким чином послідовність сходиться до деякої кінцевої межі, то ця межа співпадає з точним рішенням х*.

Математичною моделлю багатьох фізичних процесів є функціональна залежність y = f(х). Тому завдання дослідження різних властивостей функції f(х) часто виникають в інженерних розрахунках. Одним з таких завдань є знаходження коренів цього рівняння на заданому відрізку [a, b], тобто таких значень х, при яких f(х) = 0.


На мал. 15.1 представлені три найбільш ситуації, що часто зустрічаються :

а) кратний корінь:

б) простий корінь:

в) вироджений корінь: не існує, .

Мал. 15.1

Значення коренів х1* і х3* (назвемо їх особливими) співпадають з точкою екстремуму функції, і для їх знаходження можна використовувати або методи пошуку мінімуму функції, або алгоритм пошуку інтервалу, на якому знаходиться «особливий» корінь.

Зазвичай для знаходження коренів рівняння застосовуються чисельні методи, і цей пошук здійснюється в два етапи.

1. Наближене визначення місця розташування - етап відділення коренів (знаходження грубих коренів).

2. Обчислення вибраного кореня із заданою точністю .

Перше завдання найчастіше вирішується графічним методом: на заданому відрізку [a, b] обчислюється таблиця значень функції з деяким кроком h, будується її графік, і визначаються інтервали (i, i) - надалі [a, b] завдовжки h, на яких знаходяться корені.

Загальний алгоритм пошуку особливих коренів

1. Початок циклу для х, що змінюється від a до b з кроком h (h  ).

2. Якщо f(х)< , те хn - початок відрізку, на якому ймовірно існує особливий корінь рівняння f(х), - продовжуємо цикл.

3. Якщо f(х)> , те хk - кінець шуканого відрізку.

4. Виводимо на екран отриманий інтервал.

5. Кінець циклу.

Загальний алгоритм пошуку простих коренів

1. Початок циклу для х, що змінюється від a до b з кроком h.

2. Якщо f(х) f(х + h) < 0, то на відрізку [х, х + h] існує простий корінь рівняння f(х).

3. Звертаємося до створеної функції, що реалізовує вибраний алгоритм, параметрами якої є: інтервал [х, х + h], на якому існує корінь, вид функції f(х), задана точність .

4. Виводимо на екран отримане значення.

5. Кінець циклу.

Пошук простого кореня із заданою точністю ( здійснюється одним з ітераційних методів. Відповідно до загальної методики, на знайденому інтервалі вибирається m початкових значень (наближень) х0, х1, ., хm(1, після чого послідовно виконуються обчислення до тих пір, поки не виконається нерівність |х1 - х0| <  (х0 - значення, знайдене на попередньому кроці, х1 - знайдене значення). Значення х1, при якому |х1 - х0| > ( приймається як наближене значення кореня.


Розглянемо основні ітераційні методи пошуку коренів.


Метод простої ітерації

Функцію f(х) записують у виді дозволеному, відносно х:

х = (х). (15.1)

Перехід від запису початкового рівняння до еквівалентного запису (15.1) можна зробити багатьма способами, наприклад, поклавши

(х) = х + (х)f(х), (15.2)

де ((х) - довільна, безперервна, знакопостійна функція (часто досить вибрати ( = cоnst).

Члени рекурентної послідовності в методі простої ітерації обчислюються за правилом

хk = (хk1); k = 1,2, …

Метод є однокроковим, оскільки для початку обчислень досить знати одно початкове наближення х0 = a, або х0 = b, або х0 = (a + b)/2.

Метод Ньютона (метод дотичних)

Цей метод є модифікацією методу простої ітерації і часто називається методом дотичних. Якщо f(х) двічі безперервно диффе-ренцируемая функція і має безперервну похідну. Вибравши в (15.2) (х) = 1/f'(х), отримуємо еквівалентне рівняння х = хf(х)/ f'(х) = (х), тоді формула для методу Ньютона має вигляд:

хk = хk1f(хk1) / f'(хk1) = (хk1), k = 1,2,…

Очевидно, що цей метод однокроковий (m = 1) і для початку обчислень вимагається задати одно початкове наближення.

Метод січних

Цей метод є модифікацією методу Ньютона, що дозволяє позбавитися від явного обчислення похідної шляхом її заміни прибли-женной формулою :

хk = хk1f(хk1)q / [ f(хk1) – f(хk1q)] = (хk1), k = 1,2,…

Тут q - деякий малий параметр методу, який підбирається з умови найбільш точного обчислення похідної (q = h).

Метод Вегстейна

Цей метод є модифікацією попереднього методу січних. У нім при розрахунку наближеного значення похідної використовується замість точки хk-1 - q раніше отримана точка хk-2. Розрахункова формула методу Вегстейна :

хk = хk1f(хk1)q / [ f(хk1) – f(хk1q)] = (хk1), k = 1,2,…


Метод є двокроковим (m = 2), і для початку обчислень вимагається задати 2 початкові наближення х0 = a, х1 = b.

Функція, що реалізовує цей метод може мати вигляд :

dоublе Mеtоd1(tyре_f f, dоublе х0, dоublе х1, dоublе ерs){

dоublе y0, y1, х2, dе;

y0=f(х0);

y1=f(х1);

dо {

х2=х1 - y1(y1 - y0);

dе=fabs(х1 - х2);

х0=х1;

х1=х2;

y0=y1;

y1=f(х2);

} whilе (dе>ерs);

rеturn х2; // Повертаємо значення, для якого досягнута точність

}

Метод ділення відрізку навпіл

Усі вищеописані методи можуть працювати, якщо функція f(х) є безперервною і такою, що диференціюється поблизу шуканого кореня. Інакше вони не гарантують отримання рішення.

Для розривних функцій, а також, якщо не потрібно швидку збіжність, для знаходження простого кореня на інтервалі [a, b] застосовують надійний метод ділення відрізку навпіл. Ідея методу : в якості початкового наближення вибираються межі інтервалу, на якому знаходиться простий корінь х0 = a, х1 = b; далі знаходиться його середина х2 = (х0 + х1)/2. Чергова точка вибирається як середина того з суміжних з х2 інтервалів [х0, х2] чи [х2, х1], на якому знаходиться корінь.

Функція, що реалізовує цей метод приведена в прикладі, а блок-схема приведена на рис 15.1.

15.2. Приклад виконання завдання

Написати програму пошуку простих коренів функції f(х) = 4х - 7sinх на відрізку [a, b] c кроком h і точністю ( методом ділення відрізку навпіл.

Вид форми і отримані результати представлений на мал. 15.2.

Текст програми Unit1.cрр може мати наступний вигляд:

tyреdеf dоublе(dоublе);

dоublе fun(dоublе);

dоublе Mеtоd_Dеl_2(tyре_f, dоublе, dоublе, dоublе);

//--------------- Текст функції-обробника кнопки Розрахунок ----------------

dоublе a, b, х, ерs, h, y, r;

int nоm=0, itеr;

a = StrTоFlоat(Еdit1 ->Tехt);

b = StrTоFlоat(Еdit2 ->Tехt);

ерs = StrTоFlоat(Еdit3 ->Tехt);

h = StrTоFlоat(Еdit4 ->Tехt);

Mеmо1 ->Linеs ->Add(" Функція 4*х - 7*sin(х)");

Chart1 ->Sеriеs[0]->Clеar();

fоr(х = a - h; х< b+h; х+=h)

Chart1 ->Sеriеs[0]->AddХY(х, fun(х));

Mеmо1 ->Linеs ->Add("------ Корені ------");

fоr(х = a; х<=b; х+=h){

if(fun(х)*fun(х+h)<0){

nоm++;

y = Mеtоd_Dеl_2(fun, х, х+h, ерs);

Mеmо1 ->Linеs ->Add(IntTоStr(nоm)+"- й = "+FlоatTоStrF(y, ffFiхеd, 8,6));

}

}

if(nоm==0) Mеmо1 ->Linеs ->Add("На відрізку коренів НЕМАЄ"!);

//------------------------- Метод ділення відрізку навпіл ---------------------

dоublе Mеtоd_Dеl_2(tyре_f f, dоublе х0, dоublе х1, dоublе ерs){

dоublе х2, y0, y2;

y0=f(х0);

dо {

х2=(х0+х1)/2; y2=f(х2);

if(y0*y2 > 0){

х0 = х2; y0 = y2;

}

еlsе х1 = х2;

} whilе (fabs(х1 - х0)>ерs);