2013-02-16 2 views
0

Ниже приведен простой пример для обобщения и иллюстрации проблемы, которую я имею.Нарушение рекурсивных вызовов функций в matlab

Если у меня есть функция, как следующее:

function newtraph(initialguess,funct,dfunct) 
ht = funct(initialguess); 
if abs(ht) < 10^(-6) 
    disp(initialguess); return 
elseif abs(ht) > 10^6 
    disp('Fix Guess'); return 
end 
newtraph(initialguess-(ht/dfunct(initialguess)), funct, dfunct); 

Единственный способ (что я знаю), чтобы выйти из через использование этих заявлений возвращения. Но я хочу назначить вывод функций из этого многообразия переменным в базовом рабочем пространстве. Я хочу сделать некоторые вещи, как:

function out = newtraph(initialguess,funct,dfunct) 
ht = funct(initialguess); 
if abs(ht) < 10^(-6) 
    out = initialguess; return 
elseif abs(ht) > 10^6 
    disp('Fix Guess'); return 
end 
newtraph(initialguess-(ht/dfunct(initialguess)), funct, dfunct); 

Это не работает, return предотвращает выход от назначения.

Output argument "out" (and maybe others) not assigned 

Некоторые идеи у меня есть для решения используют глобалам или evalin. Но есть ли какой-то более простой способ, который мне не хватает. Я просто хочу передать выход из функций этого стиля обратно в базовое рабочее пространство?

Тестовый пример, на всякий случай:

[email protected](x) -x-cos(x); [email protected](x) sin(x)-1; initialguess=1; 

Спасибо за ваше время.

Ну, я идиот. Это был просто случай забывания окончательного задания:

function out = newtraph(initialguess,funct,dfunct) 
ht = funct(initialguess); 
if abs(ht) < 10^(-6) %Tolerance 
    out = initialguess; return 
elseif abs(ht) > 10^6 
    out=0; return 
end 
out = newtraph(initialguess-(ht/dfunct(initialguess)), funct, dfunct); 

Благодарим за помощь!

ответ

1

Ваш пример функции, которая не работает, почти там. Вам просто нужно назначить

out = newtraph(...) 

на последней строке, чтобы вы могли записать результат.

Возможно, вам также необходимо присвоить значение = 0 или некоторое фиктивное значение, когда вы сообщаете «исправить предположение», чтобы ветвь кода также возвращала значение.

0

Просто угадайте здесь: разве вам не хватает задания в последней строке? А также вам не нужно инициализировать в вашем elseif в случае, если раньше не было назначено? То есть

ht = funct(initialguess); 
if abs(ht) < 10^(-6) 
    out = initialguess; 
    return 
elseif abs(ht) > 10^6 
    disp('Fix Guess'); 
    if ~exist('out') 
     out=1; % you need some default value if you ever reach this code without ever initializing out 
    end 
    return 
end 
out = newtraph(initialguess-(ht/dfunct(initialguess)), funct, dfunct); 
0

Этот ответ может быть немного запоздалым, но я думаю, что это достаточно важно, чтобы заслужить упоминание здесь. Чтобы сделать рекурсию яснее, я рекомендую здесь другой подход.

function out = newtraph(initialguess,funct,dfunct,counter) 
maxCount = % yourValue; 
ht = funct(initialguess); 
if abs(ht) > 10^(-6) || abs(ht) < 10^6 || counter<maxCount % Break out after x tries 
    counter = counter+1; 
    out = newtraph(initialguess-(ht/dfunct(initialguess)), funct, dfunct,counter); 
elseif abs(ht) < 10^(-6) %Tolerance 
    out = initialguess; 
else 
    warning('Convergence were not reached!'); 
    out=0; 
end 

структура может предпочитал быть личной, но таким образом, ясно, что вы продолжайте идти, пока не достиг критерия остановки, а именно функция конвергентной или была расходящимися.

Также, Рекурсивные функции опасны из-за того, что единственный способ остановить их - выполнить критерий выхода или когда программа вылетает. У Matlab есть предел того, сколько раз рекурсия может продолжаться, а затем выдает ошибку. Скорее всего, вы захотите обработать ошибку самостоятельно (как вы уже сделали, установив). Кроме того, ограничение Matlabs - это 500 рекурсивных вызовов, и вы, скорее всего, захотите прекратить выполнение функции раньше, возможно, при 8-20 вызовах, в зависимости от вашего алгоритма.

Смежные вопросы