필터 지우기
필터 지우기

OutputFcn for selfmade function to show iteration steps

조회 수: 2 (최근 30일)
Nico Lange
Nico Lange 2020년 12월 22일
댓글: Nico Lange 2020년 12월 23일
Hello there,
I have written my own Levenberg-Marquardt Algorithm as shown below.
Now I want to show every step of the Iteration. Normally I do this with OutputFcn, but this won't work because OutputFun is only for Matlab functions (so I think).
How can I do this otherwise? Is there another option to integrate an OutputFcn? Otherwise I would need to save every x of the iteration, but I don't know how.
(By the way, there is a mistake in the Algorithm, where if eps_mu <=beta 0 x = x-s is wrong. There should be x(k+1) = x(k) which I also don't know how to do, but I am working on this ;) )
Thanks für every help :)
function x=levenberg_marquardt(f,dF,x0,mu0,beta0,beta1,maxit,tol)
n=length(x0);
k=0;
mu=mu0;
x=x0;
s=-(dF(x0)'*dF(x0) + mu^2*eye(n))\(dF(x0)'*f(x0));
while norm(s)>tol && k<maxit
for k=k+1
s=-(dF(x)'*dF(x)+mu^2*eye(n))\(dF(x)'*f(x));
eps_mu=0.5*((f(x)'*f(x)-(f(x+s)'*f(x+s)))/(-s'*dF(x)'*f(x)));
if eps_mu <= beta0
x=x-s;
mu=mu/2;
else
x=x+s;
if eps_mu >= beta1
mu=2*mu;
end
end
end
end
end
  댓글 수: 5
Walter Roberson
Walter Roberson 2020년 12월 23일
In the time since then, I have had activity on more than 70 Questions. I have been working so much on responding to people the last while that I am very behind in my Christmas preparations..
Nico Lange
Nico Lange 2020년 12월 23일
It was not meant as an insult to you, I am sorry,
It was just a general question, if maybe someone else has an answer.

댓글을 달려면 로그인하십시오.

채택된 답변

Walter Roberson
Walter Roberson 2020년 12월 23일
You are permitted to call your plotting function manually.
I kept the interface to the plot function compatible with having it called from lsqnonlin . I added an extra optimvalues field whose presense or absence is detected for backwards compatibility. The field indicates which line to update, so that you can have multiple lines on the same update, as you specifically requested that the LM updates go on the same figure as the other updates (presumably for comparison.)
This code assumes that every iteration you are wanting to update the existing circle rather that draw a new one -- since each iteration you would be getting a better-refined position.
If you wanted to add to the plot, then probably the easiest way would be to use animatedline() and add in new coordinates with an extra nan on the end of them to cause a line break from the next set of circles. If you are wanting to add to the plot, then I worry that the legend is going to overflow.
function x=levenberg_marquardt(f,dF,x0,mu0,beta0,beta1,maxit,tol)
n=length(x0);
k=0;
mu=mu0;
x=x0;
s=-(dF(x0)'*dF(x0) + mu^2*eye(n))\(dF(x0)'*f(x0));
while norm(s)>tol && k<maxit && mu^2>tol
for k=k+1
s=-(dF(x)'*dF(x)+mu^2*eye(n))\(dF(x)'*f(x));
eps_mu=0.5*((f(x)'*f(x)-(f(x+s)'*f(x+s)))/(-s'*dF(x)'*f(x)));
if eps_mu <= beta0
x=x-s;
mu=mu/2;
else
x=x+s;
if eps_mu >= beta1
mu=2*mu;
end
end
outfunlsq(x, struct('iteration', k, 'plotnum', 2), 'iter');
end
end
end
function stop = outfunlsq(xlsq,optimvalues,state)
stop = false;
persistent p
switch state
case 'iter'
if (optimvalues.iteration) > 0
fprintf(['Iterationen = ', num2str(optimvalues.iteration)])
xlsq
phi = linspace(0,2*pi,100);
xlsqplot = xlsq(3) * cos(phi) + xlsq(1);
ylsqplot = xlsq(3) * sin(phi) + xlsq(2);
if isfield(optimvalues, 'plotnum')
plotnum = optimvalues.plotnum;
else
plotnum = 1;
end
if length(p) < plotnum || ~isvalid(p(plotnum))
fig = figure(1);
ax = gca(fig);
specs = {'r', 'b'};
p(plotnum) = line(ax, nan, nan, specs{plotnum}, 'LineWidth', 3);
hold(ax, 'on')
legend(ax, 'show')
end
set(p(plotnum), 'XData', xlsqplot, 'YData', ylsqplot, ...
'DisplayName', "plot#" + plotnum + " Iteration " + optimvalues.iteration);
drawnow()
end
end
end

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Programming에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by