Вычисление нулей функции одной переменной
Ряд функций системы MATLAB предназначен для работы с функциями. По аналогии с дескрипторами графических объектов могут использоваться объекты класса дескрипторов функций, задаваемых с помощью символа @, например:
>
>
fe
=
@exp
Примечание
Подфункциями понимаются как встроенные функции, например sin(x) или ехр(х),так и функции пользователя, например f(x), задаваемые как т-файлы-функции.
Численные значения таких функций, заданных дескрипторами, вычисляются с помощью функции feval:
>
>
feval(fe.
1.0
)
ans
=
2.7183
Для совместимости с прежними версиями можно записывать функции в символьном виде в апострофах, использование функции eval для их вычисления может быть более наглядно, не нужно создавать m-файл, но в учебном курсе мы будем стараться использовать новую нотацию, с использованием дескрипторов функций и feval, так как при этом программирование становится "более объектно-ориентированным", повышается скорость, точность и надежность численных методов. Поэтому, хотя везде в нижеследующем тексте вместо @fun можно подставить и символьное значение функции в апострофах, мы будем использовать нотацию @fun в дидактических целях. Все же иногда в интерактивном режиме можно использовать старую запись, чтобы не создавать m-файл функции.
Довольно часто возникает задача решения нелинейного уравнения вида f(x) = 0 или /, (г) =/ 2 (дг). Последнее, однако, можно свести к виду f(x) =f 1 (х) – f 2 (х) = 0. Таким образом, данная задача сводится к нахождению значений аргумента х функции f(x) одной переменной, при котором значение функции равно нулю. Соответствующая функция MATLAB, решающая данную задачу, приведена ниже:
- fzero(@fun,x) – возвращает уточненное значение х, при котором достигается нуль функции fun, представленной в символьном виде, при начальном значении аргумента х. Возвращенное значение близко к точке, где функция меняет знак, или равно NaN, если такая точка не найдена;
- fzero(@fun,[x1 x2]) – возвращает значение х, при котором fun(x)=0 с заданием интервала поиска с помощью вектора x=[xl х2], такого, что знак fun(x(D) отличается от знака fun(x(2)). Если это не так, выдается сообщение об ошибке. Вызов функции fzero с интервалом гарантирует, что fzero возвратит значение, близкое к точке, где fun изменяет знак;
- fzero(@fun,x.tol) – возвращает результат с заданной погрешностью tol;
- fzero(@fun,x.tol.trace) – выдает на экран информацию о каждой итерации;
- fzero(@fun,х.tol.trace,Р1.Р2,…) – предусматривает дополнительные аргументы, передаваемые в функцию fun(x.Pl,P2,…). При задании пустой матрицы для tol или trace используются значения по умолчанию. Пример:
fzero(fun,x,[ ],[ ],P1)
Для функции fzero ноль рассматривается как точка, где график функции fun пересекает ось х, а не касается ее. В зависимости от формы задания функции fzero реализуются следующие хорошо известные численные методы поиска нуля функции: деления отрезка пополам, секущей и обратной квадратичной интерполяции. Приведенный ниже пример показывает приближенное вычисление р/2 из решения уравнения cos(x)=0 с представлением косинуса дескриптором:
>
>
x
=
fzero(@cos.[
1
3
])
x
=
1.5708
В более сложных случаях настоятельно рекомендуется строить график функции f(x) для приближенного определения корней и интервалов, в пределах которых они находятся. Ниже дан пример такого рода (следующий листинг представляет собой содержимое m-файла fun1.m):
%Функция, корни которой ищутся
function
f
=
funl(x)
f
=
0.25
*
x
+
sin(x)
-
1
;
>
>
x
=
0
:
0.1
:
10
;
>
>
plot(x,funl(x));grid
on
;
Из рисунка нетрудно заметить, что значения корней заключены в интервалах [0.5 1], [2 3] и [5 6]. Найдем их, используя функцию fzero:
>
>
x1
=
fzero(@fun1.[
0.5
1
])
x1
=
0.8905
>
>
x2
=
fzero(@fun1.[
2
3
])
x2
=
2.8500
>
>
x3
=
fzero(@fun1,[
5.6
])
x3
=
5.8128
>
>
x3
=
fzero(@fun1.
5.0.001
)
x3
=
5.8111
Обратите внимание на то, что корень х3 найден двумя способами и что его значения в третьем знаке после десятичной точки отличаются в пределах заданной погрешности tol =0.001. К сожалению, сразу найти все корни функция fzero не в состоянии. Решим эту же систему при помощи функции fsolve из пакета Optimization Toolbox, которая решает систему нелинейных уравнений вида f(x)=0 методом наименьших квадратов, ищет не только точки пересечения, но и точки касания, fsolve имеет почти те же параметры (дополнительный параметр – задание якобиана) и почти ту же запись, что и функция lsqnonneg, подробно рассмотренная ранее. Пример:
>
>
fsolve(@fun1,
0
:
10
)
ans
=
Columns
1
through
7
0.8905
0.8905
2.8500
2.8500
2.8500
5.8128
5.8128
Columns
8
through
11
5.8128
2.8500
2.8500
10.7429
Для решения систем нелинейных уравнений следует также использовать функцию solve из пакета Symbolic Math Toolbox. Эта функция способна выдавать результат в символьной форме, а если такого нет, то она позволяет получить решение в численном виде. Пример:
>
>
solve(
0.25
*
x
+
sin(x)
-
1
)
ans
=
.
89048708074438001001103173059554
[Пакеты расширения Symbolic Math ToolBox и Extended Symbolic Math Toolbox MATLAB 6.0 используют ядро Maple V Release 5 [30-35] и являются поэтому исключением: они пока не поддерживают новую нотацию с использованием дескрипторов функций. – Примеч. ред.]