- •Графики функций sin X и .
- •В чем заключается задача о численном решении уравнений
- •Задача о нахождении корня уравнения с заданной точностью.
- •Отделение корней
- •График функции
- •Графики, полученные при помощи plot (верхний) и fplot (нижний).
- •Различное число корней в зависимости от значения параметра .
- •Основные способы обращения к fzero
- •Графики функций
- •Способы задания уравнения для fzero
- •Решение уравнения, зависящего от параметров
- •Интерфейс fzero, получение информации о вычислениях, параметры вычислительного процесса
- •Выходные аргументы fzero
- •Входные аргументы fzero
- •Прерывание работы fzero, пример приложения с кнопкой Stop
Прерывание работы fzero, пример приложения с кнопкой Stop
В этом разделе мы рассмотрим способ прерывания работы функции fzero при нахождении корня. Эта проблема возникает, если исследуемая функция вычисляется достаточно долго, а для нахождения корня нужно сделать довольно много итераций.
Для прерывания работы fzero требуется запрограммировать управляющую функцию, которая будет вызываться на каждом шаге алгоритма fzero. У этой функции может быть несколько входных аргументов, при помощи которых в нее передается информация из fzero для выяснения необходимости остановки вычислений. Управляющая функция должна возвращать 1 или 0. Если она возвращает 0, то работа fzero продолжается, а если 1, то останавливается. Для того, чтобы fzero на каждом шаге вызывала данную функцию, следует обратиться к fzero с третьим входным аргументом, который является структурой с управляющими ходом вычислений опциями (см. Входные аргументы fzero). Поле OutputFcn этой структуры должно содержать указатель на управляющую функцию.
Интерфейс управляющей функции следующий:
flag_stop = outfun(x, optimValues, state)
Функция fzero передает следующую информацию в управляющую функцию:
x — приближение к корню, полученное на текущей итерации;
optimValues — структура, содержащая информацию о текущей итерации;
state — текущий этап алгоритма.
Смысл полей структуры optimValues следующий
funccount — суммарное на данный момент количество вычислений исследуемой функции;
iteration — номер текущей итерации;
intervaliteration — число проделанных итераций для отделения корня;
fval — текущее значение исследуемой функции;
procedure — применяемая в данный момент процедура (отделение корня, интерполяция или половинное деление);
intervala —левая граница текущего интервала;
fvala — значение исследуемой функции на левой границе интервала;
intervalb —правая граница текущего интервала;
fvalb — значение исследуемой функции на правой границе интервала.
Значением входного аргумента state может быть одно из следующих:
‘init’ — алгоритм fzero находится в стадии инициализации;
'interrupt' — в fzero выполняется итерация;
'iter' — в fzero происходит завершение итерации;
'done' — итерации завершены, выполняется последний этап алгоритма fzero.
Приведем пример приложения с графическим интерфейсом пользователя solgui, в котором кнопка Stop служит для прерывания работы fzero. Окно приложения приведено на рисунке ниже. Оно содержит строку ввода для ввода исследуемой функции или имени вычисляющей ее m-функции, кнопку Start для начала вычислений и область вывода результата.
В основной функции приложения создается графическое окно, строка ввода, две кнопки и текстовая область. С событием Callback кнопки Start связывается функция btnStart_Callback, а событием Callback кнопки Stop — функция btnStop_Callback (программирование приложений с графическим интерфейсом пользователя рассматривается в разделе Приложения с GUI и дескрипторная графика
В функции btnStart_Callback происходит считывание содержимого строки ввода (т.е. функции), далее при помощи optimset формируется структура options, поле которой OutputFcn принимает значение указателя на управляющую функцию stop_by_user. Переменной flag_stop присваивается значение 0 и она сохраняется в данных приложения при помощи функции guidata. После этого вызывается функция fzero с третьим входным аргументом options. Таким образом, fzero знает, что stop_by_user является управляющей функцией. В зависимости от значения третьего выходного аргумента exitflag функции fzero (см. раздел Выходные аргументы fzero) либо выводится ответ, либо сообщение о том, что при нахождении корня возникли проблемы.
Управляющая функция stop_by_user реализована как вложенная функция (nested function) в функцию btnStart_Callback. В ней выполняется единственный оператор — из данных приложения извлекается значение флага остановки, которое и становится значением выходного аргумента управляющей функции stop_by_user. Единственное место в приложении, где значение флага изменяется — функция btnStop_Callback обработки события Callback кнопки Stop. В этой функции флагу присваивается единица и его значение сохраняется в данных приложения при помощи функции guidata.
function solgui
% основная функция приложения
% создание графического окна
figure('MenuBar', 'none',...
'NumberTitle', 'off', ...
'Name', 'solgui', ...
'Position', [300 300 400 100])
% создание области ввода
uicontrol('Style', 'edit',...
'position',[10 70 210 20],...
'Tag', 'edtFun')
% создание кнопки Start
uicontrol('Style', 'pushbutton',...
'position',[240 70 70 20],...
'String', 'Start',...
'Callback', @btnStart_Callback)
% создание кнопки Stop
uicontrol('Style', 'pushbutton',...
'position',[320 70 70 20],...
'String', 'Stop',...
'Callback', @btnStop_Callback)
% создание области вывода результата
uicontrol('Style', 'text',...
'position',[10 10 380 50],...
'FontSize', 12,...
'Tag', 'txtOuttext')
end
function btnStart_Callback(src, evt)
% функция обработки нажатия на кнопку Start
function stop = stop_by_user(x, optimValues, state)
% управляющая функция
% чтение значения флага остановки
stop = guidata(src);
end
% получаем структуру указателей на объекты приложения
handles = guihandles(src);
% считываем в fun содержимое строки ввода
fun = get(handles.edtFun, 'String');
% формируем структуру options, заполняя поле с управляющей функцией
options = optimset('OutputFcn', @stop_by_user);
% пока присваиваем флагу остановки 0
flag_stop = 0;
% сохраняем значение флага остановки
guidata(src, flag_stop)
% вызываем fzero
[x,f, exitflag] = fzero(fun, 1, options);
% в зависимости от значения exitflag выводим результат или сообщение о том,
% что корень не найден
if exitflag == 1
outtext = char(['x = ' num2str(x)], ['f = ' num2str(f)]);
else
outtext = 'There were some problems when finding the root';
end
set(handles.txtOuttext, 'String', outtext)
end
function btnStop_Callback(src, evt)
% функция обработки нажатия на кнопку Stop
% привсаиваем 1 флагу остановки
flag_stop = 1;
% сохраняем его значение в данных приложения
guidata(src, flag_stop)
end
Для демонстрации работы приложения solgui понадобится функция, вычисление которой занимает достаточно долгое время. Для теста можно воспользоваться приведенной ниже функцией, в которой организована пауза в 4 секунды.
function y = myfun(x)
y = sin(x);
pause(4)
Итак, после запуска приложения, вода имени myfun в строку ввода и нажатия на кнопку Start начинаются вычисления, которые останавливаются нажатием на кнопку Stop.
