Доброго времени суток. В этой статье мы разберем решение простых нелинейных уравнений с помощью средств Matlab. Посмотрим в действии как стандартные функции, так и сами запрограммируем три распространенных метода для решения нелинейных уравнений.
Общая информация
Уравнения, которые содержат переменные, находящиеся в степенях, отличающихся от единицы, или имеющие нелинейные математические выражения (корень, экспонента, логарифм, синус, косинус и т.д.), а также имеющие вид f(x) = 0 называются нелинейными. В зависимости от сложности такого уравнения применяют методы для решения нелинейных уравнений.
В этой статье, помимо стандартных функций Matlab, мы рассмотрим следующие методы:
- Метод перебора
- Метод простых итераций
- Метод половинного деления
Рассмотрим коротко их алгоритмы и применим для решения конкретной задачи.
Стандартные функции Matlab
Для решения нелинейных уравнений в Matlab есть функция fzero. Она принимает в качестве аргументов саму функцию, которую решаем, и отрезок, на котором происходит поиск корней нелинейного уравнения.
И сразу же разберем пример:
Решить нелинейное уравнение x = exp(-x), предварительно определив интервалы, на которых существуют решения уравнения.
Итак, для начала следует привести уравнение к нужному виду: x - exp(-x) = 0
, а затем определить интервалы, в которых будем искать решение уравнения. Методов для определения интервалов множество, но так как пример достаточно прост мы воспользуемся графическим методом.
x = -4.0 : 0.001 : 4.0; y = x - exp(-x); plot(x,y); grid on;
Здесь задали примерные границы по оси x, чтобы можно было построить график и посмотреть как ведет себя функция. Вот график:
Из графика видно, что на отрезке [0;1] есть корень уравнения (там, где y = 0), соответственно в дальнейшем будем использовать этот интервал. Чем точнее выбран интервал, тем быстрее метод придет к решению уравнения, а для сложных уравнений правильный выбор интервала определяет погрешность, с которой будет получен ответ.
x0 = fzero('(x - exp(-x))', [0.0 1.0]); x0 = 0.5671
С помощью стандартной функции Matlab находим корень нелинейного уравнения и выводим. Теперь для проверки отобразим все это графически:
plot(x,y); grid on; hold on; plot(x0,0,'r*');
Как вы видите, все достаточно точно просчиталось. Теперь мы исследуем эту же функцию с помощью других методов и сравним полученные результаты.
Метод перебора Matlab
Самый простой метод, который заключается в том, что сначала задается какое то приближение x (желательно слева от предполагаемого корня) и значение шага h. Затем, пока выполняется условие f(x) * f(x + h) > 0, значение x увеличивается на значение шага x = x + h. Как только условие перестало выполняться — это значит, что решение нелинейного уравнения находится на интервале [x; x + h].
Теперь реализуем метод перебора в Matlab:
f = inline('x - exp(-x)'); h = 0.0001; % задаем шаг x = 0.0; % начальное приближение i = 0; % счетчик итераций while (f(x)*f(x+h)) > 0 x = x + h; i = i + 1; end x % выводим решение i % и затраченное количество итераций
Лучше всего создать новый m-файл, в котором и прописать код. После вызова получаем такой вывод:
x = 0.5671 i = 5671
Функцию объявляем с помощью очень полезной команды inline, в цикле пока выполняется условие отсутствия корней (или их четного количества), прибавляем к x значение шага. Очевидно, что чем точнее начальное приближение, тем меньше итераций необходимо затратить.
Метод простых итераций Matlab
Этот метод заключается в том, что функцию преобразуют к виду: x = g(x). Эти преобразования можно сделать разными способами, в зависимости от вида начальной функции. Помимо этого следует задать интервал, в котором и будет производиться итерационный процесс, а также начальное приближение. Сам процесс строится по схеме xn= g(xn-1). То есть итерационно проходим от предыдущего значения к последующему.
Процесс заканчивается как только выполнится условие: , то есть, как только будет достигнута заданная точность. И сразу же разберем реализацию метода простых итераций в Matlab для примера, который был приведен выше.
f = inline('x - exp(-x)'); x0 = 0.0; % начальное приближение eps = 0.00001; % точность N = 100; % количество итераций, чтобы не было зацикливаний g = inline('exp(-x)'); x1 = g(x0); % первое значение for i = 1 : N % делаем максимум 100 итераций if abs(x1 - x0) <= eps break end x0 = x1; x1 = g(x0); end x1 i
Здесь должно быть все понятно, кроме одного: зачем задавать число итераций? Это нужно для того, чтобы программа не зацикливалась и не выполняла ненужные итерации, а также потому что не всегда программа может просчитать решение с нужной точностью — поэтому следует ограничивать число итераций.
А вот и вывод программы:
x1 = 0.5671 i = 22
Очевидно, что метод простых итераций работает гораздо быстрее и получает точное решение.
Метод половинного деления Matlab
Метод достаточно прост: существует отрезок поиска решения [a;b], сначала находят значение функции в точке середины c, где c = (a+b)/2. Затем сравнивают знаки f(a) и f(c). Если знаки разные — то решение находится на отрезке [a;c], если нет — то решение находится на отрезке [c;b]. Таким образом мы сократили область в 2 раза. Такое сокращение происходит и дальше, пока не достигнем заданной точности.
Перейдем к реализации метода в Matlab:
f = inline('x - exp(-x)'); eps = 0.00001; a = 0.0; b = 1.0; i = 0; while abs(a - b) > eps c = (a + b) / 2; if ((f(c) * f(a)) < 0) b = c; else a = c; end i = i + 1; end c i
Все самое важное происходит в цикле: последовательно сокращаем область нахождения решения, пока не будет достигнута заданная точность.
Вот что получилось в выводе:
c = 0.5671 i = 17
Этот метод хорошо работает, когда правильно определен интервал, на котором находится решение. Тем не менее, метод простых итераций считается наиболее точным и быстрым.
Заключение
Сегодня мы рассмотрели решение нелинейных уравнений в Matlab. Теперь нам известны методы перебора, половинного деления, простых итераций. А также, когда нам не важно реализация метода, то можно использовать стандартную функцию в Matlab.
На этом все — спасибо за внимание. В следующей статье мы разберем решение систем нелинейных уравнений в matlab.
Спасибо за довольно неплохо изложенный материал.