1. 简述
函数语法
x = lsqnonlin(fun,x0)
函数用于:
解决非线性最小二乘(非线性数据拟合)问题
解决非线性最小二乘曲线拟合问题的形式
变量x的约束上下限为ub和lb,
x = lsqnonlin(fun,x0)从x0点开始,找到fun中描述的函数的最小平方和。函数fun应该返回一个向量(或数组),而不是值的平方和。(该算法隐式地计算了fun(x)元素的平方和。)
2. 代码
主程序:
%% 用lsqnonlin求解最小二乘问题
clear all
x0 = [0.3 0.4]; % 初值点
[x,resnorm] = lsqnonlin(@f1211,x0) % 调用最优化函数求 x 和 平方和残差
子程序:
function [xCurrent,Resnorm,FVAL,EXITFLAG,OUTPUT,LAMBDA,JACOB] = lsqnonlin(FUN,xCurrent,LB,UB,options,varargin)
%LSQNONLIN solves non-linear least squares problems.
% LSQNONLIN attempts to solve problems of the form:
% min sum {FUN(X).^2} where X and the values returned by FUN can be
% X vectors or matrices.
%
% LSQNONLIN implements two different algorithms: trust region reflective
% and Levenberg-Marquardt. Choose one via the option Algorithm: for
% instance, to choose Levenberg-Marquardt, set
% OPTIONS = optimoptions('lsqnonlin', 'Algorithm','levenberg-marquardt'),
% and then pass OPTIONS to LSQNONLIN.
%
% X = LSQNONLIN(FUN,X0) starts at the matrix X0 and finds a minimum X to
% the sum of squares of the functions in FUN. FUN accepts input X
% and returns a vector (or matrix) of function values F evaluated
% at X. NOTE: FUN should return FUN(X) and not the sum-of-squares
% sum(FUN(X).^2)). (FUN(X) is summed and squared implicitly in the
% algorithm.)
%
% X = LSQNONLIN(FUN,X0,LB,UB) defines a set of lower and upper bounds on
% the design variables, X, so that the solution is in the range LB <= X
% <= UB. Use empty matrices for LB and UB if no bounds exist. Set LB(i)
% = -Inf if X(i) is unbounded below; set UB(i) = Inf if X(i) is
% unbounded above.
%
% X = LSQNONLIN(FUN,X0,LB,UB,OPTIONS) minimizes with the default
% optimization parameters replaced by values in OPTIONS, an argument
% created with the OPTIMOPTIONS function. See OPTIMOPTIONS for details.
% Use the SpecifyObjectiveGradient option to specify that FUN also
% returns a second output argument J that is the Jacobian matrix at the
% point X. If FUN returns a vector F of m components when X has length n,
% then J is an m-by-n matrix where J(i,j) is the partial derivative of
% F(i) with respect to x(j). (Note that the Jacobian J is the transpose
% of the gradient of F.)
%
% X = LSQNONLIN(PROBLEM) solves the non-linear least squares problem
% defined in PROBLEM. PROBLEM is a structure with the function FUN in
% PROBLEM.objective, the start point in PROBLEM.x0, the lower bounds in
% PROBLEM.lb, the upper bounds in PROBLEM.ub, the options structure in
% PROBLEM.options, and solver name 'lsqnonlin' in PROBLEM.solver. Use
% this syntax to solve at the command line a problem exported from
% OPTIMTOOL.
%
% [X,RESNORM] = LSQNONLIN(FUN,X0,...) returns
% the value of the squared 2-norm of the residual at X: sum(FUN(X).^2).
%
% [X,RESNORM,RESIDUAL] = LSQNONLIN(FUN,X0,...) returns the value of the
% residual at the solution X: RESIDUAL = FUN(X).
%
% [X,RESNORM,RESIDUAL,EXITFLAG] = LSQNONLIN(FUN,X0,...) returns an
% EXITFLAG that describes the exit condition. Possible values of EXITFLAG
% and the corresponding exit conditions are listed below. See the
% documentation for a complete description.
%
% 1 LSQNONLIN converged to a solution.
% 2 Change in X too small.
% 3 Change in RESNORM too small.
% 4 Computed search direction too small.
% 0 Too many function evaluations or iterations.
% -1 Stopped by output/plot function.
% -2 Bounds are inconsistent.
%
% [X,RESNORM,RESIDUAL,EXITFLAG,OUTPUT] = LSQNONLIN(FUN,X0,...) returns a
% structure OUTPUT with the number of iterations taken in
% OUTPUT.iterations, the number of function evaluations in
% OUTPUT.funcCount, the algorithm used in OUTPUT.algorithm, the number
% of CG iterations (if used) in OUTPUT.cgiterations, the first-order
% optimality (if used) in OUTPUT.firstorderopt, and the exit message in
% OUTPUT.message.
%
% [X,RESNORM,RESIDUAL,EXITFLAG,OUTPUT,LAMBDA] = LSQNONLIN(FUN,X0,...)
% returns the set of Lagrangian multipliers, LAMBDA, at the solution:
% LAMBDA.lower for LB and LAMBDA.upper for UB.
%
% [X,RESNORM,RESIDUAL,EXITFLAG,OUTPUT,LAMBDA,JACOBIAN] = LSQNONLIN(FUN,
% X0,...) returns the Jacobian of FUN at X.
%
% Examples
% FUN can be specified using @:
% x = lsqnonlin(@myfun,[2 3 4])
%
% where myfun is a MATLAB function such as:
%
% function F = myfun(x)
% F = sin(x);
%
% FUN can also be an anonymous function:
%
% x = lsqnonlin(@(x) sin(3*x),[1 4])
%
% If FUN is parameterized, you can use anonymous functions to capture the
% problem-dependent parameters. Suppose you want to solve the non-linear
% least squares problem given in the function myfun, which is
% parameterized by its second argument c. Here myfun is a MATLAB file
% function such as
%
% function F = myfun(x,c)
% F = [ 2*x(1) - exp(c*x(1))
% -x(1) - exp(c*x(2))
% x(1) - x(2) ];
%
% To solve the least squares problem for a specific value of c, first
% assign the value to c. Then create a one-argument anonymous function
% that captures that value of c and calls myfun with two arguments.
% Finally, pass this anonymous function to LSQNONLIN:
%
% c = -1; % define parameter first
% x = lsqnonlin(@(x) myfun(x,c),[1;1])
%
% See also OPTIMOPTIONS, LSQCURVEFIT, FSOLVE, @, INLINE.
% Copyright 1990-2018 The MathWorks, Inc.
% ------------Initialization----------------
defaultopt = struct(...
'Algorithm','trust-region-reflective',...
'DerivativeCheck','off',...
'Diagnostics','off',...
'DiffMaxChange',Inf,...
'DiffMinChange',0,...
'Display','final',...
'FinDiffRelStep', [], ...
'FinDiffType','forward',...
'FunValCheck','off',...
'InitDamping', 0.01, ...
'Jacobian','off',...
'JacobMult',[],...
'JacobPattern','sparse(ones(Jrows,Jcols))',...
'MaxFunEvals',[],...
'MaxIter',400,...
'MaxPCGIter','max(1,floor(numberOfVariables/2))',...
'OutputFcn',[],...
'PlotFcns',[],...
'PrecondBandWidth',Inf,...
'ScaleProblem','none',...
'TolFun', 1e-6,...
'TolFunValue', 1e-6, ...
'TolPCG',0.1,...
'TolX',1e-6,...
'TypicalX','ones(numberOfVariables,1)',...
'UseParallel',false );
% If just 'defaults' passed in, return the default options in X
if nargin==1 && nargout <= 1 && strcmpi(FUN,'defaults')
xCurrent = defaultopt;
return
end
if nargin < 5
options = [];
if nargin < 4
UB = [];
if nargin < 3
LB = [];
end
end
end
problemInput = false;
if nargin == 1
if isa(FUN,'struct')
problemInput = true;
[FUN,xCurrent,LB,UB,options] = separateOptimStruct(FUN);
else % Single input and non-structure.
error(message('optim:lsqnonlin:InputArg'));
end
end
% No options passed. Set options directly to defaultopt after
allDefaultOpts = isempty(options);
% Prepare the options for the solver
options = prepareOptionsForSolver(options, 'lsqnonlin');
% Set options to default if no options were passed.
if allDefaultOpts
% Options are all default
options = defaultopt;
end
if nargin < 2 && ~problemInput
error(message('optim:lsqnonlin:NotEnoughInputs'))
end
% Check for non-double inputs
msg = isoptimargdbl('LSQNONLIN', {'X0','LB','UB'}, ...
xCurrent,LB, UB);
if ~isempty(msg)
error('optim:lsqnonlin:NonDoubleInput',msg);
end
caller = 'lsqnonlin';
[funfcn,mtxmpy,flags,sizes,~,xstart,lb,ub,EXITFLAG,Resnorm,FVAL,LAMBDA, ...
JACOB,OUTPUT,earlyTermination] = lsqnsetup(FUN,xCurrent,LB,UB,options,defaultopt, ...
allDefaultOpts,caller,nargout,length(varargin));
if earlyTermination
return % premature return because of problem detected in lsqnsetup()
end
xCurrent(:) = xstart; % reshape back to user shape before evaluation
% Catch any error in user objective during initial evaluation only
switch funfcn{1}
case 'fun'
try
initVals.F = feval(funfcn{3},xCurrent,varargin{:});
catch userFcn_ME
optim_ME = MException('optim:lsqnonlin:InvalidFUN', ...
getString(message('optim:lsqnonlin:InvalidFUN')));
userFcn_ME = addCause(userFcn_ME,optim_ME);
rethrow(userFcn_ME)
end
initVals.J = [];
case 'fungrad'
try
[initVals.F,initVals.J] = feval(funfcn{3},xCurrent,varargin{:});
catch userFcn_ME
optim_ME = MException('optim:lsqnonlin:InvalidFUN', ...
getString(message('optim:lsqnonlin:InvalidFUN')));
userFcn_ME = addCause(userFcn_ME,optim_ME);
rethrow(userFcn_ME)
end
case 'fun_then_grad'
try
initVals.F = feval(funfcn{3},xCurrent,varargin{:});
catch userFcn_ME
optim_ME = MException('optim:lsqnonlin:InvalidFUN', ...
getString(message('optim:lsqnonlin:InvalidFUN')));
userFcn_ME = addCause(userFcn_ME,optim_ME);
rethrow(userFcn_ME)
end
try
initVals.J = feval(funfcn{4},xCurrent,varargin{:});
catch userFcn_ME
optim_ME = MException('optim:lsqnonlin:InvalidFUN', ...
getString(message('optim:lsqnonlin:InvalidJacobFun')));
userFcn_ME = addCause(userFcn_ME,optim_ME);
rethrow(userFcn_ME)
end
otherwise
error(message('optim:lsqnonlin:UndefCallType'))
end
% Check for non-double data typed values returned by user functions
if ~isempty( isoptimargdbl('LSQNONLIN', {'F','J'}, initVals.F, initVals.J) )
error('optim:lsqnonlin:NonDoubleFunVal',getString(message('optimlib:commonMsgs:NonDoubleFunVal','LSQNONLIN')));
end
% Flag to determine whether to look up the exit msg.
flags.makeExitMsg = logical(flags.verbosity) || nargout > 4;
[xCurrent,Resnorm,FVAL,EXITFLAG,OUTPUT,LAMBDA,JACOB] = ...
lsqncommon(funfcn,xCurrent,lb,ub,options,defaultopt,allDefaultOpts,caller,...
initVals,sizes,flags,mtxmpy,varargin{:});
3. 运行结果