Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Решение уравнений.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
480.48 Кб
Скачать

Прерывание работы 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.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]