Глава 5. Решение уравнений и оптимизация
Предварительно в редакторе m-файлов вводится следующий код для функции, определяющей решаемое уравнение (оно такое же, как в предыдущем случае):
function z=f(x) z=2*sin(x)^2+sin(x)-1; end
Окно редактора m-файлов с этим кодом представлено на рис. 5.3.
Рис. 5.3. Код функции в окне редактора m-файлов
Для решения уравнения с передачей ссылки на функцию двумя разными способами используем такой код:
>>z=fzero(@f,pi/4)
z =
0.5236
>>z=fzero('f',3*pi/4)
z =
2.6180
Вкоманде z=fzero(@f,pi/4) первым аргументом функции fzero() передается указатель на функцию. Для получения указателя перед именем функции указываем инструкцию @, в результате получаем @f. Вто-
рым аргументом указывается начальное приближение для корня уравнения pi/4. Это означает, что корень ищется в окрестности точки π 4 .
Врезультате находим (в числовом виде) корень x = π 6 . В команде z=fzero('f',3*pi/4) в качестве ссылки на функцию передается имя файла, в котором описана функция, определяющая уравнение. В качестве
начального для поиска корня здесь указано значение 3*pi/4. Как результат, находится корень x = 5π
6 .
На заметку
Из того, что мы ищем корень в окрестности какой-то точки, еще не означает, что именно в окрестности этой точки будет найдено решение. Более того, нет гарантии, что вообще будет найдено хоть какое-то решение.
201
Самоучитель Matlab
При вызове функции fzero() можно узнать не только корень уравнения, но и ряд других параметров. В частности, помимо корня, в качестве результата функцией fzero() возвращается значение функции, определяющей уравнение, для найденного корня.
На заметку
Кроме того, дополнительными параметрами в результате возвращаются: статус результата вычисления корня, использованный алгоритм, количество итераций и так далее.
Еще один пример использования функции fzero() приведен в документе на рис. 5.4.
Рис. 5.4. Функцией fzero() возвращается корень и значение функции в этой точке
Основу кода составляют две команды, которые рассмотрим по отдельности. Первой командой F=@(x)(sin(x)+cos(x)) задается функция F(x) = sin(x) + cos(x). Специфика этой команды в ее синтаксисе. Такой синтаксис используется для объявления анонимных функций. Общий синтаксис такой: инструкция @, в круглых скобках список аргументов, а в следующей паре круглых скобок указывается выражение, определяющее функцию, то есть @(аргументы)(выражение). Если такую конструкцию присвоить в качестве значения переменной, то эта переменная будет указателем на соответствующую функцию. Собственно, этим правилом мы
ивоспользовались при определении функции для уравнения.
На заметку
Пожалуй, главное преимущество в использовании анонимных функций состоит в том, что с их помощью функции можно объявлять прямо в командном окне.
202
Глава 5. Решение уравнений и оптимизация
Еще одна команда, которую мы использовали, – это [z,res]= fzero(F,[0 pi]). Думается, аргументы функции fzero() особых вопросов не вызовут. А результат вызова функции fzero() записывается в две переменные: переменная z в качестве значения получает корень уравнения (на интервале от 0 до π - это значение x = 3π
4 ), а в переменную res записывается значение функции F() в точке - корне уравнения.
На заметку
Если корень уравнения найден точно, то значение функции уравнения в точке должно равняться нулю. Обычно значение корня является приближенным, поэтому и функция в соответствующей точке отличается от нуля. Чем ближе значение функции уравнения в найденной точке решения, тем точнее вычислен корень. Тем не менее, не следует путать точность вычисления корня с отклонением функции уравнения от нулевого значения в найденной точке решения.
Для решения систем уравнений (или отдельных уравнений) используют функцию fsolve(). Принципиальное отличие функции fsolve() от fzero() состоит в том, что первым аргументом функции fsolve()можно передавать ссылку не только на скалярную, но и на векторную функцию. Именно это обстоятельство позволяет решать с помощью функции fsolve() системы дифференциальных уравнений. Все способы вызова функции fsolve() здесь рассматривать не будем. Ограничимся лишь основными. Обратимся к примерам. Начнем с отдельного (скалярного уравнения). Соответствующий документ представлен на рис. 5.5.
Командный код имеет следующий вид (для удобства команды пользователя выделены жирным шрифтом, а текстовое сообщение, выводимое в результате вычисления корня, выделено курсивом):
>>F=@(x)(2*sin(x)^2+sin(x)-1);
>>[x,res]=fsolve(F,pi/5)
Equation solved.
fsolve completed because the vector of function values is near zero as measured by the default value of the function tolerance, and the problem appears regular as measured by the gradient.
<stopping criteria details> x =
0.5236 res =
8.2934e-013
Командой F=@(x)(2*sin(x)^2+sin(x)-1) непосредственно в командном окне задается функциональная зависимость F(x) = 2 sin(x)2 + sin(x) −1 . Уравнение 2 sin(x)2 + sin(x) −1 = 0 решаем командой [x,res]=fsolve (F,pi/5). Здесь первым аргументом функции fsolve(F,pi/5) передается указатель на функцию, определяющую решаемое уравнение. Второй
203
Самоучитель Matlab
Рис. 5.5. Решение скалярного уравнения с помощью функции fsolve()
аргумент – начальное приближение для корня уравнения. Результат возвращается в виде значения корня уравнения (переменная z) и значения функции уравнения в найденном корне (переменная res). Помимо непосредственно результатов вычислений функцией fsolve() выводится текстовое сообщение с пояснениями, насколько успешно прошли вычисления
ипочему функция fsolve() завершила работу.
На заметку
Функция завершает работу, если корень, удовлетворяющий определенным критериям, найден или если, например, функция не может найти корень. Иногда формальное решение найдено, но нет уверенности, что это правильное решение. Эту и другую полезную информацию можно получить из текстового сообщения.
Как отмечалось выше, важным преимуществом функции fsolve() является то, что с ее помощью можно решать системы уравнений. Для этого необходимо создать векторную функцию, которая описывает систему уравнений, и передать ее первым аргументом функции fsolve(). Вторым аргументом передается список начальных значений по каждой из переменных, относительно которых решается уравнение. Рассмотрим простой пример (рис. 5.6).
204
Глава 5. Решение уравнений и оптимизация
Рис. 5.6. Решение системы уравнений
Сначала командой F=@(x)[(x(1)^2+x(2)^2-25),((x(1)+1)*x(2)- 16)] задается вектор-функция из двух элементов. Эта вектор-функция определяет решаемую систему уравнений. Определяем ее в командном окне в виде указателя на анонимную функцию.
На заметку
Анонимную вектор-функцию в командном окне мы определяем так. Сначала, как обычно, указывается инструкция @, затем в круглых скобках один (векторный!) аргумент и затем две функциональные зависимости, реализованные в виде вектор-столбца. Для этого в квадратных скобках указывается два выражения, разделенные точкой с запятой. Векторный аргумент функции обозначен как x. Поскольку вектор-функция состоит из двух элементов, то вполне логично, что аргумент x также состоит из двух элементов (количество уравнений в системе должно равняться количеству неизвестных, относительно которых решается система). Поэтому ссылки на неизвестные переменные, относительно которых решается система уравнений, имеют вид x(1) и x(2). Именно эти ссылки используются в выражениях для элементов вектор-функции.
В соответствии с теми выражениями, которые указаны при определе-
нии вектор-функции, решается система уравнений x12 + x22 −25 = 0 и x1x2 −12 = 0 . У этой системы есть точное решение x1 = 3 и x2 = 4 . Это решение и пытаемся найти. Чтобы поиск был удачным, желательно указать начальную точку как можно ближе к точке решения. Мы выбираем в качестве начальной точку x1 = 0 и x2 = 1.
205