How store evolution of x over the iterations of lsqnonlin?

34 次查看(过去 30 天)
Hi,
I'm solving a nonlinear system of equations with lsqnonlin and want to save the evolution of values of X.
The ouput of the system is defined by a function file 'error.m', which takes X with size 4x1 and returns a vector of residuals with size 8x1.
I run a script with the structure below that sets the some fixed parameters for error.m, then calls the lsqnonlin solver and error.m for n cases.
clear all,clc,close all
load measure;
%initialization: set some constant inputs for 'error.m' and options for the
%solver
% solve nCases
for i=1:nCases
inputs.measured=measure(i);
X=lsqnonlin(@(x)error(inputs,x),x0,lb,ub,options)
save X X;
end
I want to store the values of X over the iterations, not only the solution. There are these examples in Optimization Solver Output Functions, but they use nested functions and I don't know how to adapt them to my script structure.
function stop = myoutput(x,optimvalues,state);
stop = false;
if isequal(state,'iter')
history = [history; x];
end
end
How will the output function 'myoutput' access the variable X inside the lsqnonlin?
I've tried to write the myoutput at the end of the main script, predefined history = [ ] in the for loop i=1:nCases and set options = optimset('OutputFcn', @myoutput);
However, the function 'myoutput' doesn't find th ehistory variable to append. Why is that happening?
  1 个评论
Marcus
Marcus 2024-7-18,17:53
移动:Torsten 2024-7-18,18:01
I just want to save the values and plot them to evaluate the convergence.

请先登录,再进行评论。

回答(2 个)

Torsten
Torsten 2024-7-18,17:48
编辑:Torsten 2024-7-18,18:00
If you can't use the nested approach, define "history" as a persistent variable and call "myoutput" after the computation has finished with a specific value of the "state" variable (e.g. 'plot') to plot deduced results from the "history" matrix.
function stop = myoutput(x,optimvalues,state);
persistent history
if isempty(history)
history = [];
end
stop = 0;
if strcmp(state,'iter')
history = [history; x];
end
end
  2 个评论
Marcus
Marcus 2024-7-18,18:38
Thanks Torsten,
I used your code and the values of X are appended now. Just had to change the name of variable to 'evX'. It seems that 'history' has a conflict with some function in the Datafeed toolbox.
However, I didn't understand how to pass the evX matrix as an output after the lsqnonlin has finished. The variable evX is empty the output function, unless I definy it as a global variable instead of persistent.
Torsten
Torsten 2024-7-18,22:01
编辑:Torsten 2024-7-18,22:07
Most probably there is an easier way, but do you get the idea ?
for i = 1:2
fun();
end
[~,hout] = fun()
hout = 1x3
1 2 3
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
function [stop,hout] = fun()
persistent h s
if isempty(h)
h = [];
s = 0;
end
stop = 0;
s = s + 1;
h = [h,s];
hout = h;
end

请先登录,再进行评论。


Steven Lord
Steven Lord 2024-7-18,17:44
The ouput of the system is defined by a function file 'error.m',
Please rename this function! error already has a very important meaning in MATLAB.
I want to store the values of X over the iterations, not only the solution.
What are you hoping to do with this information? Are you trying to avoid evaluating your function repeatedly for the same inputs? If so use memoize instead of trying to build your own cache.
In fact, you could consider going the memoize route regardless of your goal. Set the CacheSize property to a sufficiently large value then ask for the stats of the MemoizedFunction returned by memoize afterwards.
f = memoize(@factorial);
clearCache(f)
f.CacheSize = 100;
for k = randi(10, 1, 20) % 20 random numbers between 1 and 10
tic
y = f(k);
t = toc;
fprintf("Computed factorial of %02d in %f seconds.\n", k, t)
end
Computed factorial of 05 in 0.005255 seconds. Computed factorial of 08 in 0.003171 seconds. Computed factorial of 05 in 0.000807 seconds. Computed factorial of 09 in 0.001112 seconds. Computed factorial of 09 in 0.000207 seconds. Computed factorial of 10 in 0.000096 seconds. Computed factorial of 04 in 0.000072 seconds. Computed factorial of 06 in 0.000111 seconds. Computed factorial of 04 in 0.000042 seconds. Computed factorial of 02 in 0.000200 seconds. Computed factorial of 05 in 0.000034 seconds. Computed factorial of 04 in 0.000016 seconds. Computed factorial of 08 in 0.000019 seconds. Computed factorial of 02 in 0.000017 seconds. Computed factorial of 10 in 0.000017 seconds. Computed factorial of 10 in 0.000016 seconds. Computed factorial of 01 in 0.000095 seconds. Computed factorial of 03 in 0.000071 seconds. Computed factorial of 10 in 0.000026 seconds. Computed factorial of 10 in 0.000019 seconds.
s = stats(f);
s.Cache
ans = struct with fields:
Inputs: {{1x1 cell} {1x1 cell} {1x1 cell} {1x1 cell} {1x1 cell} {1x1 cell} {1x1 cell} {1x1 cell} {1x1 cell}} Nargout: [1 1 1 1 1 1 1 1 1] Outputs: {{1x1 cell} {1x1 cell} {1x1 cell} {1x1 cell} {1x1 cell} {1x1 cell} {1x1 cell} {1x1 cell} {1x1 cell}} HitCount: [2 1 1 4 2 0 1 0 0] TotalHits: 11 TotalMisses: 9
s.Cache.Inputs{1}
ans = 1x1 cell array
{[5]}
This tells me factorial was called three times (from HitCounts) with input 5 (once initially then twice more with the result returned from the cache.) If you look at the list, you can see that the second and third calls were much faster than the first.

类别

Help CenterFile Exchange 中查找有关 Linear Least Squares 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by