- •Графики функций sin X и .
- •В чем заключается задача о численном решении уравнений
- •Задача о нахождении корня уравнения с заданной точностью.
- •Отделение корней
- •График функции
- •Графики, полученные при помощи plot (верхний) и fplot (нижний).
- •Различное число корней в зависимости от значения параметра .
- •Основные способы обращения к fzero
- •Способы задания уравнения для fzero
- •Графики функций
- •Решение уравнения, зависящего от параметров
- •Интерфейс fzero, получение информации о вычислениях, параметры вычислительного процесса
- •Выходные аргументы fzero
- •Входные аргументы fzero
- •Прерывание работы fzero, пример приложения с кнопкой Stop
Графики функций
Из графиков видно, что абсцисса точки пересечения примерно равна 3.2. Выберем ее в качестве начального приближения для функции fzero:
fun = inline('sqrt(x-pi)-x^2+10');
x = fzero(fun, 3.2)
Exiting fzero: aborting search for an interval containing a sign change
because complex function value encountered during search.
(Function value at 3.0609 is 0.63086+0.28406i.)
Check function or try again with a different starting value.
x =
NaN
Мы обнаруживаем, что решение не найдено (NaN означает «не число» от Not a Number), а в командное окно вывелось предупреждение о прекращении поиска интервала, на границах которого функция изменяет знак, поскольку в процессе вычислений появилось комплексное значение. Это произошло потому, что функция fzero при поиске отрезка выбрала значение, не принадлежащее области определения нашей функции [Π,+∞] .
Правильным решением в данном примере является предварительное отделение корня. Из графиков g (x) и h (x) видно, что функция меняет знаки на [Π,1.25] . Укажем его в качестве второго аргумента fzero
x = fzero(fun, [pi 3.25])
В этом случае получаем верный ответ
x =
3.200386655543571e+000
В этом разделе мы использовали inline-функции для задания их в качестве входного аргумента fzero. В следующем разделе мы рассмотрим другие способы задания функций.
Способы задания уравнения для fzero
В предыдущем разделе Основные способы обращения к fzero мы использовали только один способ для задания левой части уравнения f (x)=0 при помощи inline-функции. Такой способ удобен, если требуется найти корень достаточно простой функции. В этом разделе мы рассмотрим другие способы задания исследуемых функций.
Функция может быть задана в первом входном аргументе fzero строкой, содержащей записанное по правилам MATLAB выражение. В это выражение могут входить имеющиеся в MATLAB математические функции. Для вывода списка математических функций MATLAB в командное окно удобно использовать
>> help elfun
Пример задания функции строкой.
>> x = fzero('x-exp(-x)', [0,1])
x =
0.5671
Кроме того, исследуемая функция может быть задана при помощи анонимной функции (anonymous function). Разберем создание анонимных функций. В самом простом случае анонимная функция является функцией одного аргумента. Например, функция f(x)=x-e-x может быть задана при помощи анонимной функции следующим образом:
>> f = @(x) x-exp(-x)
f =
@(x) x-exp(-x)
Знак @ используется для получения указателя на функцию и в переменную f записан указатель на созданную функцию. Далее в круглых скобках помещаются аргументы функции (в нашем случае только один аргумент, а если их несколько — то через запятую). После списка аргументов следует выражение для функции, записанное в соответствии с правилами MATLAB, в которое могут входить математические функции.
Указатель на созданную анонимную функцию может быть теперь указан в качестве первого входного аргумента fzero:
>> x = fzero(f, [0,1])
x =
0.5671
Анонимные функции позволяют искать корни функций, зависящих от параметров. Об этом написано в разделе Решение уравнения, зависящего от параметров.
Заметим, что строка с выражением для функции, inline-функция или анонимная функция может содержать не только математические функции MATLAB. В качестве примера рассмотрим следующую задачу. Требуется найти первый следующий за нулем корень уравнения, содержащего интеграл с переменным верхним пределом:
Левая часть уравнения является функцией от x. Для вычисления этой функции при заданном x, т.е. для вычисления интеграла от 0 до x , воспользуемся функцией численного интегрирования quadl. Ее первым входным аргументом должна быть подынтегральная функция, которую можно задать строковым выражением. При записи выражения необходимо использовать поэлементные операции, в нашем примере — поэлементное умножение, задаваемое точкой со звездочкой. Вторым и третьим аргументами quadl являются, соответственно, нижний и верхний пределы интегрирования. Функцию quadl вместе со своими аргументами укажем в качестве выражения для анонимной функции:
>> f = @(x)quadl('exp(-t).*sin(t)-exp(t).*cos(t)',0, x);
Для
отделения корней построим график
зависимости
от x на
отрезке [0, 3] при помощи fplot:
>> fplot(f,[0 3])
>> grid on
Из графика следует, что искомый корень заключен между 2 и 2.5. Уточним его при помощи функции fzero:
>> x = fzero(f, [2 2.5])
Получаем результат:
x =
2.2009
В приведенном выше примере с интегралом с переменным верхним пределом мы применили анонимную функцию для вычисления зависимости интеграла от верхнего предела. Аналогичным образом можно было задать интеграл и при помощи inline-функции. При этом следует учесть, что выражение inline-функции заключается в апострофы, однако само выражение есть обращение к функции quadl, первый входной аргумент которой является строкой с подынтегральной функцией. Таким образом, в строке содержится символ апостроф, а в соответствии с правилами MATLAB для его задания следует ставить два идущих подряд знака апострофа.
Правильное выражение для inline-функции таково:
>> f = inline('quadl(''exp(-t).*sin(t)-exp(t).*cos(t)'',0, x)')
Отделение корня при помощи fplot и его уточнение функцией fzero производится аналогично.
Рассмотрим теперь примеры, в которых поиск корня связан с программированием функции.
Функцию, корни которой требуется определить с привлечением fzero, можно запрограммировать в m-файле. В случае достаточно сложных функций без этого не обойтись. Дело даже не в том, что функция может быть задана длинным и сложным выражением, а в том, что она может являться результатом решения некоторой промежуточной задачи.
В качестве примера рассмотрим следующую задачу, в которой требуется выяснить, при каком минимальное собственное число матрицы A=B3, где
станет
равным 2. Запрограммируем функцию,
которая по заданному x возвращает
,
где
—
минимальное собственное число
матрицы A.Текст
соответствующей функции eq3 приведен
ниже (она должна быть сохранена в файле
eq3.m, который находится в текущем каталоге
или в каталоге, путь к которому известен
MATLAB).
function f = eq3(x)
B = [x 1 1 1
1 x 1 1
1 1 x 1
1 1 1 x];
A = B.^3;
f = min(eig(A))-2;
Перед нахождением отделим корень (см. разд. Отделение корней) для чего построим график исследуемой функции, например при помощи fplot. Для задания функции в fplot используем указатель на функцию eq3, обозначаемый символом @
>> fplot(@eq3, [0 2])
>> grid on
Итак, корень между 0 и 2. Для его уточнения вызовем fzero, обратившись к исследуемой функции по указателю так же, как и в случае fplot:
>> x = fzero(@eq3, [0 2])
Получаем результат:
x =
1.4422
В этом примере к функции можно было обратиться не только по указателю, но и по имени, заключенному в апострофы:
>> x = fzero('eq3', [0 2])
Результат будет тем же самым.
Теперь разберем пример, в котором обращение к функции по указателю и по имени не одно и тоже. Предположим, что программируется функция, в которой требуется решить уравнение. Левая часть уравнения может быть запрограммирована в подфункции данной основной функции. Рассмотрим совсем простой случай, когда основная функция eqsolve содержит вызов fzero, а fzero обращается к подфункции eq3 при помощи указателя на нее (предполагаем, что функция eqsolve и подфункция eq3 сохранены в файле eqsolve.m, который содержится в текущем каталоге, или путь к которому известен MATLAB).
function x = eqsolve
x = fzero(@eq3, [0 2]);
function y = eq3(x);
y = 1-x;
После вызова основной функции
>> x = eqsolve
x =
1
получаем верное решение уравнения 1-x=0. Однако, если мы в fzero обратимся к функции не по указателю, а по имени, т.е. напишем
x = fzero(eq3, [0 2]);
вместо
x = fzero(@eq3, [0 2]);
то получим непредсказуемый результат. Он зависит от того, есть ли в текущем каталоге (или путях поиска MATLAB) функция eq3. Если есть, то fzero попытается решить уравнение именно с ней, а если нет — выведется сообщение о том, что функция не найдена. Итак, в основной функции ссылаться на подфункции следует по указателю.
Еще один способ задания функций для fzero состоит в применении вложенных функций (nested functions). Его мы разберем в следующем разделе, т.к. он удобен для решения уравнений, зависящих от одного или нескольких параметров.
