Should lsqcurvefit reshape the initializing parameter vector?
4 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
When I run the following simple test of lsqcurvefit in R2018a,
function test
ctrue=[1;2;3];
xdata=rand(3);
ydata=F(ctrue,xdata);
lb=-inf(3,1); ub=+inf(3,1);
lb(1)=1; ub(1)=1;
opts=optimoptions(@lsqcurvefit, 'SpecifyObjectiveGradient',true);
c=lsqcurvefit(@F,[0;0;0],xdata,ydata,lb,ub,opts);
with this model function,
function [out,Jac]=F(c,xd)
assert( isequal(size(c),[3,1]) , ...
['c is expected to be 3x1, but it is ',...
num2str(size(c,1)),'x' num2str(size(c,2)) ])
out=xd*c;
Jac=xd;
the assert is triggered and I get,
Error using test>F (line 21)
c is expected to be 3x1, but it is 1x3
So lsqcurvefit is passing c as a 1x3 row vector, even though the initial c that I provided was a 3x1 column vector [0;0;0]. Should this occur? Shouldn't I be able to count on the initial vector's shape to determine the shape of the parameter arrays that get passed to the model function?
5 commentaires
Alan Weiss
le 6 Mai 2021
Both documentation sections are correct, but I can now see that the section on linear indices is not helpful. What happens is that, internally, solvers use linear indices for computing values, but for nonlinear objective and constraint functions the arguments are reshaped back to the x0 shape when used.
I will update the doc.
FYI, linear indices are crucial for linear constraint matrices A and Aeq, because for those arguments the x argument is reshaped to a column vector no matter the shape of x0.
Alan Weiss
MATLAB mathematical toolbox documentation
Plus de réponses (1)
Alan Weiss
le 11 Oct 2018
It is possible that the behavior of solvers is inconsistent, so when the vector orientation matters, I suggest that you be proactive and force the dimensions you like. For example,
function [out,Jac]=F(c,xd)
c = c(:); % for column c
c = c(:).'; % for row c
c = reshape(c,3,1); % another possibility
Alan Weiss
MATLAB mathematical toolbox documentation
7 commentaires
Bruno Luong
le 27 Avr 2021
Modifié(e) : Bruno Luong
le 27 Avr 2021
You can do like this (I use Matt's example)
ctrue=[1;2;3];
xdata=rand(3);
ydata=F(ctrue,xdata);
lb=-inf(3,1);
ub=+inf(3,1);
lb(1)=1; ub(1)=1;
opts=optimoptions(@lsqcurvefit, 'SpecifyObjectiveGradient',true);
% This is original code, that throw error
%c=lsqcurvefit(@F,[0;0;0],xdata,ydata,lb,ub,opts);
% Use a wrapper
c=lsqcurvefit(@(varargin) Fexpand(lb < ub, varargin{:}), ...
[0;0;0],xdata,ydata,lb,ub,opts);
% Wrarpper to expand back decision variables
function varargout = Fexpand(b, varargin)
c = varargin{1};
try % newer MATLAB has fix the bug
c(b) = c;
end
varargout = cell(1,nargout);
[varargout{:}] = F(c, varargin{2:end}); % <- Call original model
end
% This is the original model, intended to used with lsqcurvefit
function [out,Jac]=F(c,xd)
out=xd*c;
Jac=xd;
end
dong
le 6 Mai 2021
Thank you very much!
It is appreciate that you offer me the function Fexpand. it is useful.
% Wrarpper to expand back decision variables
function varargout = Fexpand(b, varargin)
c = varargin{1};
try % newer MATLAB has fix the bug
c(b) = c;
end
varargout = cell(1,nargout);
[varargout{:}] = F(c, varargin{2:end}); % <- Call original model
end
Though I understand it with a little bit difficult, it successfully solves the problems I have encountered.
But I had a new problem.
What does this line codes mean below?
@(varargin) Fexpand(lb < ub, varargin{:})
and if the original model “F” return a function handle,how can I use the function of Fexpand?
I'm so depressed that I don't know how to solve the problem. Hope to get your help,thanks.
email:lidong@nim.ac.cn
Voir également
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!