Численные методы. Учебное пособие для СПО
.pdf
a = 0 b = 3
eps = 0.00001 print(dihotomia(a, b, eps));
#Выводим результаты по временным затратам elapsed_time = timeit.timeit(code_to_test, number=100)/100 print(elapsed_time)
Реализация на языке Matlab
tic %Начало отсчета времени clc;
clear;
% Основные условия
f=@(x) x*(x+3)-5; %это искомая функция
%Начальные данные a=0;
b=3;
e=0.0001;
%Основной цикл while abs(b-a)>e c=(b+a)/2;
if sign(f(c))==sign(f(a)) a=c;
else b=c; end end
disp(['Ответ x=' num2str(c,8)]); disp('для проверки точный ответ ='); syms x;
disp(solve(f(x)));
toc %Конец отсчета времени
11
1.2. МЕТОД НЬЮТОНА
Метод Ньютона (также известный как метод касательных) — это итерационный численный метод решения нелинейных уравнений вида ( ) = 0. На -й итерации в точке ( , ( )) строится касательная к кривой = ( ) и ищется точка пересечения касательной с осью абсцисс.
Описание алгоритма по шагам. Сначала задают начальное приближение, желательно близкое к корню. Далее вычисляют
следующее приближение +1 = − ′( )/ ( ).
Расчеты повторяют, пока не будет достигнута заданная точность. Плюсы алгоритма — квадратичная сходимость (очень быстрая, если начальное приближение удачное), достаточно эффективен особенно для гладких и дифференцируемых функций. К минусам можно отнести то, что алгоритм требует вычислений производной (если она неизвестна, то используют численные аналоги), может расходиться при плохом начальном приближении или если производная стремится к нулю, а также не гарантирует сходимость для произвольных функций. Часто применяется в вычислительной математике, оптимизации и машинном обучении [4].
Реализация на языке Python
import time import math t0=time.time() def f(x):
return x ** 3 + x - 1 def f1(x):
return 3 * x ** 2 + 1
x = 1
12
eps = 0.001
xk = x - f(x) / f1(x) while abs(xk - x) >= eps: x = xk
xk = x - f(x)/f1(x) else:
A = xk B = f(xk)
print(A,B)
t1 = time.time() - t0 print(t1)
1.3. МЕТОД ПРОСТОЙ ИТЕРАЦИИ
Метод простой итерации — это итерационный численный метод, предназначенный для приближенного нахождения корней нелинейных уравнений вида ( ) = 0. Данный метод преобразует исходное уравнение таким образом, чтобы упростить его дальнейшее решение. Соответственно исходное нелинейное уравне-
ние |
( ) = 0 необходимо |
привести |
к |
виду |
= ( ). |
|
|
|
|
В |
качестве ( ) можно |
принять функцию |
( ) = |
|
= − ( )/, где — неизвестная постоянная величина, которая определяется из условия сходимости метода простой итера-
ции 0 < ′( ) <1.
|
Если известно начальное приближение корня = 0, под- |
|||||
ставляя |
это |
значение в |
правую |
часть |
уравнения |
|
= ( ) получаем новое приближение 1 |
= (0). |
|
||||
|
Далее подставляя каждый раз новое значение корня в урав- |
|||||
нение |
= ( ), получаем |
последовательность |
значений: |
|||
|
= ( ). |
Итерационный процесс прекращается, если ре- |
||||
+1 |
|
|
|
|
|
|
13
зультаты |
двух последовательных итераций близки, т.е. |
|
| |
− |
| < . |
+1 |
|
|
Преимущества: простота реализации, не требует вычислений производных. Недостатки: может медленно сходиться, если производная близка к 1, не всегда удается подходящим образом произвести некоторые преобразования.
Геометрическая интерпретация метода простой итерации. Представим себе график функции = ( ) вместе с пря-
мой = . Геометрически задача сводится к поиску точки пересечения этих двух графиков, так как именно в этой точке координаты совпадают, то есть = ( ).
Начало процесса: берем некоторое начальное приближение
= 0.
Следующая итерация: строим вертикальную прямую от точки 0 вверх до пересечения с графиком = ( ), затем гори-
зонтальную прямую вправо |
до |
пересечения с |
прямой |
= . Абсцисса новой точки |
и |
есть следующее |
прибли- |
жение 1.
Эта процедура повторяется многократно, постепенно приближая нас к истинному корню.
Графически метод простой итерации иллюстрирует пошаговое движение вдоль графика ( ) и прямой = вплоть до достижения нужного уровня точности.
Реализация на языке Python
def fun(x):
return (2-0.4*x**2)**0.5+math.cos(x) x1=float(input("Введите приближенное значение Х=")) e=float(input("Введите точность e=")) a=float(input("a="))
b=float(input("b="))
n=int(input("n="))
14
a=abs((fun(a+0.0001)-fun(a))/0.0001) b=abs((fun(b+0.0001)-fun(b))/0.0001) q=max(a,b)
q=(1-q)/q iters=0 x0=x1 x1=fun(x0)
while abs(x1-x0) <= abs(q*e): iters+=1
x0=x1
x1=fun(x0)
print('Точное значение корня:',2.0926) print('Вычисленное значение корня:',x1) print('Число итераций:',iters)
Реализация на языке Matlab
function [root, iterations] = simple_iteration(phi, x0, tol, max_iter)
%Метод простой итерации для решения x = phi(x)
%Входные параметры:
% |
phi |
- функция, задающая итерационный процесс (x = |
phi(x)) |
|
|
% |
x0 |
- начальное приближение |
% |
tol |
- допустимая погрешность (по умолчанию 1e-6) |
%max_iter - максимальное число итераций (по умолчанию
1000)
%Выходные параметры:
% root - найденный корень
%iterations - количество выполненных итераций
%Установка значений по умолчанию
if nargin < 4 max_iter = 1000;
end
if nargin < 3 tol = 1e-6;
15
end
x_prev = x0; iterations = 0; converged = false;
% Итерационный процесс for iterations = 1:max_iter x_next = phi(x_prev);
% Проверка условия сходимости if abs(x_next - x_prev) < tol
converged = true; break;
end
x_prev = x_next; end
if ~converged
warning('Метод не сошелся за %d итераций!', max_iter); end
root = x_next; end
Самостоятельная работа
Теоретические вопросы:
1.Что такое нелинейное уравнение?
2.Какие существуют классы нелинейных уравнений?
3.Назовите основные виды численных методов решения нелинейных уравнений.
4.Опишите суть метода деления отрезка пополам.
16
5.Чем отличаются прямые и итерационные методы решения нелинейных уравнений?
6.Почему важно правильно выбирать начальное приближение при применении метода Ньютона?
7.Объясните принцип работы метода простой итерации.
8.Какой основной недостаток метода простой итерации?
9.Приведите геометрическую интерпретацию метода простой итерации.
10.В чем преимущество метода Ньютона перед другими методами?
Практические задания:
1.Напишите программу на Python для решения нелинейного уравнения методом деления отрезка пополам.
2.Решите уравнение cos( ) − = 0 методом Ньютона с точностью 105.
3.Найдите корень уравнения 3 − 2 − 5 = 0, используя метод простой итерации.
4.Определите подходящий интервал для начала поиска корней уравнения − − 2 = 0.
5.Проверьте сходимость метода Ньютона для уравнения
2 − 4 sin( ) = 0.
6.Составьте программу для сравнения скорости сходимости методов деления отрезка пополам и Ньютона.
7.Примените метод простой итерации для уравнения
√ − ln( ) = 0. Сделайте выводы о выборе подходящего интервала.
8.Постройте график зависимости количества итераций от начальной точки для уравнения tan( ) = 0.
9.Разработайте реализацию метода Ньютона на языке
MATLAB.
10.Оцените эффективность различных методов для ре-
шения одного и того же уравнения и сделайте сравнительную таблицу результатов.
17
2. МЕТОДЫ РЕШЕНИЯ СИСТЕМ ЛИНЕЙНЫХ АЛГЕБРАИЧЕСКИХ УРАВНЕНИЙ
Общий вид системы линейных алгебраических уравнений (СЛАУ) записывается в форме:
11 1 + 12 2 + + 1 = 1
{ 21 1 + 22 2 + + 2 = 2
1 1 + 2 2 + + =
Методы решения систем уравнений можно разделить на две основные группы: точные (прямые) и итерационные.
Точные методы (прямые) в идеальных условиях (без учета ошибок округления) обеспечивают получение точного решения за конечное число операций. К ним относятся, например, метод Гаусса, разложение и метод Холецкого.
Итерационные методы основаны на циклическом процессе, в ходе которого решение уточняется шаг за шагом, приближаясь к точному результату. Эти методы особенно полезны для больших и разреженных систем, где прямые методы могут быть неэффективны.
Таким образом, выбор метода зависит от требуемой точности, размера системы и вычислительных ресурсов.
2.1. МЕТОД ГАУССА
Метод Гаусса — это прямой метод решения СЛАУ вида= , который приводит расширенную матрицу системы к ступенчатому (треугольному) виду с последующей обратной подстановкой.
18
Алгоритм метода начинается с того, что необходимо создать расширенную матрицу — объединение матрицы коэффициентов и вектора правой части в одну матрицу.
Затем приступить к алгоритму исключения переменных. Для каждого столбца необходимо выбрать ведущий элемент
(Чтобы избежать деления на ноль, переставляем строки, чтобы он был максимальным по модулю в столбце). Затем обнулить все элементы ниже ведущего путем преобразований строк матрицы. В результате получим верхнетреугольную матрицу.
Обратный ход: из уравнения находим . Из уравнения− 1 находим −1. И так до первого уравнения. Коэффициенты последнего уравнения называются ведущими элементами исключения неизвестных. Они должны быть отличны от нуля. Если они равны нулю, то, меняя местами строки, необходимо на их место вывести ненулевые элементы.
Данным методом решаются системы уравнений с неизвестными, сложность кубическая. Для уменьшения ошибок округления используется выбор ведущего элемента (частичный или полный).
Реализация на языке Python
import math
import matplotlib.pyplot as pylab import numpy as np
from sympy import diff, symbols, cos, sin import time
start_time = time.time()
def MyGauss(A): # Функция поиска значений методом Гаусса a = A
n = len(A)
for i in range(n-1):
19
if abs(a[i][i]) < 0.00000001: for k in range(i + 1,n):
if abs(a[k][i]) > 0.00000001: for j in range(n+1):
tmp = a[i][j] a[i][j] = a[k][j] a[k][j] = tmp break
if abs(a[i][i]) > 0.00000001: for k in range(i+1,n):
f = -a[k][i] / a[i][i] for j in range(i,n+1):
a[k][j] = a[k][j] + f * a[i][j]
for i in range(n-1,-1,-1): tmp = a[i][n]
for k in range(i+1,n):
tmp = tmp - a[i][k] * a[k][n+1] a[i][n+1] = tmp / a[i][i]
for i in range(n): print(a[i][n+1])return a
x = MyGauss([[13,-2,1,-4,8,0],[2,0,-3,5,-7,0],[4,-1,3,9,1,0],[7,- 5,11,-4,-5,0]])
X = numpy.arange(-3.25, -2, 0.03 ) pylab.plot([x for x in X], [x for x in X]) pylab.grid(True)
print("--- Расчет выполнен за %s секунд ---" % (time.time() - start_time))
20
