26 Usar lsqnonlin para resolver el problema de mínimos cuadrados (programa matlab)

1. Breve descripción

      

Sintaxis de la función
x = lsqnonlin(fun,x0)
La función se usa para:

Resolución de problemas de mínimos cuadrados no lineales (ajuste de datos no lineal)
Resolución de problemas de ajuste de curvas de mínimos cuadrados no lineales de la forma

Los límites superior e inferior de la variable x son ub y lb,

x = lsqnonlin(fun,x0) encuentra la suma de cuadrados más pequeña para la función descrita en fun, comenzando en el punto x0. La función fun debería devolver un vector (o matriz), no una suma de valores al cuadrado. (El algoritmo calcula implícitamente la suma de los cuadrados de los elementos de fun(x).)
 

2. Código

Programa principal:

%% Resolver el problema de mínimos cuadrados con lsqnonlin
borrar todo
x0 = [0.3 0.4]; % Punto de valor inicial
[x,resnorm] = lsqnonlin(@f1211,x0) % Llamar a la función de optimización para encontrar x y la suma cuadrada residual

Subrutina:

function [xCurrent,Resnorm,FVAL,EXITFLAG,OUTPUT,LAMBDA,JACOB] = lsqnonlin(FUN,xCurrent,LB,UB,options,varargin) %LSQNONLIN
resuelve problemas de mínimos cuadrados no lineales.
% LSQNONLIN intenta resolver problemas de la forma:
% min sum {FUN(X).^2} donde X y los valores devueltos por FUN pueden ser   
% X vectores o matrices.
%
% LSQNONLIN implementa dos algoritmos diferentes:
% reflectante de región de confianza y Levenberg-Marquardt. Elija uno a través de la opción Algorithm: para
% instancia, para elegir Levenberg-Marquardt, configure 
% OPTIONS = optimoptions('lsqnonlin', 'Algorithm','levenberg-marquardt'), 
% y luego pase OPTIONS a LSQNONLIN.
%    
% X = LSQNONLIN(FUN,X0) comienza en la matriz X0 y encuentra un mínimo X para 
% la suma de los cuadrados de las funciones en FUN. FUN acepta la entrada X 
% y devuelve un vector (o matriz) de valores de función F evaluados
% en X. NOTA: FUN debe devolver FUN(X) y no la suma de cuadrados 
% sum(FUN(X).^2) ). (FUN(X) se suma y eleva implícitamente al cuadrado en el
algoritmo %.) 
%
% X = LSQNONLIN(FUN,X0,LB,UB) define un conjunto de límites superior e inferior en
% las variables de diseño, X, de modo que la solución está en el rango LB <= X
% <= UB. Use matrices vacías para LB y UB si no existen límites. Establezca LB(i)
% = -Inf si X(i) no está acotado por debajo; establecer UB(i) = Inf si X(i) es
% ilimitado arriba.
%
%X = LSQNONLIN(FUN,X0,LB,UB,OPTIONS) se minimiza con los
parámetros de optimización % predeterminados reemplazados por valores en OPCIONES, un argumento
% creado con la función OPTIMOPTIONS. Ver OPTIMOPCIONES para más detalles.
% Use la opción SpecificObjectiveGradient para especificar que FUN también
% devuelve un segundo argumento de salida J que es la matriz jacobiana en el
% punto X. Si FUN devuelve un vector F de m componentes cuando X tiene una longitud n,
% entonces J es un m- matriz by-n donde J(i,j) es la derivada parcial de
%F(i) con respecto a x(j). (Tenga en cuenta que el jacobiano J es el % transpuesto
del gradiente de F).
%
% X = LSQNONLIN(PROBLEMA) resuelve el problema de mínimos cuadrados no lineales 
% definido en PROBLEMA. PROBLEMA es una estructura con la función DIVERSIÓN en 
% PROBLEMA.objetivo, el punto de inicio en PROBLEMA.x0, los límites inferiores en 
% PROBLEMA.lb, los límites superiores en PROBLEMA.ub, la estructura de opciones en 
% PROBLEMA.opciones y solucionador nombre 'lsqnonlin' en PROBLEM.solver. Use 
% esta sintaxis para resolver en la línea de comandos un problema exportado desde 
% OPTIMTOOL. 
%
% [X,RESNORM] = LSQNONLIN(FUN,X0,...) devuelve 
% el valor de la norma 2 al cuadrado del residual en X: sum(FUN(X).^2). 
%
% [X,RESNORM,RESIDUAL] = LSQNONLIN(FUN,X0,...) devuelve el valor del 
% residual en la solución X: RESIDUAL = FUN(X).
%
% [X,RESNORM,RESIDUAL,EXITFLAG] = LSQNONLIN(FUN,X0,...) devuelve un
% EXITFLAG que describe la condición de salida. Los posibles valores de EXITFLAG
% y las condiciones de salida correspondientes se enumeran a continuación. Consulte la
documentación de % para obtener una descripción completa.
%
% 1 LSQNONLIN convergió a una solución.
% 2 Cambio en X demasiado pequeño.
% 3 Cambio en RESNORM demasiado pequeño.
% 4 La dirección de búsqueda calculada es demasiado pequeña.
% 0 Demasiadas evaluaciones o iteraciones de funciones.
% -1 Detenido por la función de salida/gráfico.
% -2 Los límites son inconsistentes.
%
% [X,RESNORM,RESIDUAL,EXITFLAG,OUTPUT] = LSQNONLIN(FUN,X0,...) devuelve un 
% estructura SALIDA con el número de iteraciones realizadas en
% SALIDA.iteraciones, el número de evaluaciones de función en
% SALIDA.funcCount, el algoritmo utilizado en OUTPUT.algoritmo, el número
% de iteraciones CG (si se utilizan) en SALIDA.cgiteraciones, el % de optimización de primer orden
(si se usa) en OUTPUT.firstorderopt, y el mensaje de salida en
% OUTPUT.message.
%
% [X,RESNORM,RESIDUAL,EXITFLAG,OUTPUT,LAMBDA] = LSQNONLIN(FUN,X0,...) 
% devuelve el conjunto de multiplicadores lagrangianos, LAMBDA, en la solución: 
% LAMBDA.inferior para LB y LAMBDA.superior para la UB.
%
% [X,RESNORM,RESIDUAL,EXITFLAG,OUTPUT,LAMBDA,JACOBIAN] = LSQNONLIN(FUN,
% X0,...) devuelve el jacobiano de FUN en X.   
%
% Ejemplos
% FUN se puede especificar usando @:
% x = lsqnonlin(@myfun,[2 3 4])
%
% donde myfun es una función de MATLAB como:
%
% function F = myfun(x)
% F = sin( X);
%
% FUN también puede ser una función anónima:
%
% x = lsqnonlin(@(x) sin(3*x),[1 4])
%
% Si FUN está parametrizado, puede usar funciones anónimas para capturar el 
% problema- parámetros dependientes. Suponga que desea resolver el 
problema de mínimos cuadrados % no lineal dado en la función myfun, que está 
% parametrizado por su segundo argumento c. Aquí myfun es una función de % de archivo MATLAB 
como
%
% función F = myfun(x,c)
% F = [ 2*x(1) - exp(c*x(1))
% -x(1) - exp(c*x(2))
% x(1 ) - x(2) ];
%
% Para resolver el problema de mínimos cuadrados para un valor específico de c, primero 
% asigne el valor a c. Luego cree una función anónima de un argumento 
% que capture ese valor de c y llame a myfun con dos argumentos. 
% Finalmente, pase esta función anónima a LSQNONLIN:
%
% c = -1; % definir primero el parámetro
% x = lsqnonlin(@(x) myfun(x,c),[1;1])
%
% Consulte también OPTIMOPTIONS, LSQCURVEFIT, FSOLVE, @, INLINE.

% Copyright 1990-2018 MathWorks, Inc.

% ------------Inicialización----------------
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','disperso(unos(Jrows,Jcols))',...
    'MaxFunEvals',[],...
    'MaxIter',400,...
    'MaxPCGIter','max(1,floor(númeroDeVariables/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 );

% Si solo se pasa 'predeterminado', devuelve las opciones predeterminadas en X
si nargin==1 && nargout <= 1 && strcmpi(FUN,'defaults')
   xCurrent = defaultopt; final
   de retorno

si nargin < 5
    opciones = [];
    si nargin < 4
        UB = [];
        si nargin < 3
            LB = [];
        final
    final
final

problemaEntrada = falso;
if nargin == 1
    if isa(FUN,'struct')
        problemInput = true;
        [FUN,xCurrent,LB,UB,opciones] = separarOptimStruct(FUN);
    else % Entrada única y sin estructura.
        error(mensaje('optim:lsqnonlin:InputArg'));
    final
final

% No se aprobó ninguna opción. Configure las opciones directamente en defaultopt después de
allDefaultOpts = isempty(options);

% Prepare las opciones para el solucionador
options = prepareOptionsForSolver(options, 'lsqnonlin');

% Establece las opciones por defecto si no se pasó ninguna opción.
si allDefaultOpts
    % Las opciones son todas las opciones predeterminadas
    = defaultopt;
fin

if nargin < 2 && ~problemInput
  error(message('optim:lsqnonlin:NotEnoughInputs'))
end

% Comprobar entradas no dobles
msg = isoptimargdbl('LSQNONLIN', {'X0','LB','UB'}, ...
                               xCurrent,LB, UB);
si ~isempty(msg)
    error('optim:lsqnonlin:NonDoubleInput',msg);
fin

llamador = '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
    devuelve % de devolución prematura debido a un problema detectado en lsqnsetup()
end

xActual(:) = xinicio; % remodelar de nuevo a la forma del usuario antes de la evaluación
% Detectar cualquier error en el objetivo del usuario durante la evaluación inicial solo
cambiar 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);
            volver a lanzar (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)         intento    
        final

            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)
        fin
    de lo contrario
        error(mensaje('optim:lsqnonlin:UndefCallType'))
fin

% Comprueba los valores de tipo de datos no dobles que devuelven las funciones de usuario 
si ~isempty( isoptimargdbl('LSQNONLIN', {'F','J'}, initVals.F, initVals.J) )
    error('optim:lsqnonlin:NonDoubleFunVal ',getString(mensaje('optimlib:commonMsgs:NonDoubleFunVal','LSQNONLIN')));
fin

% Indicador para determinar si buscar el mensaje de salida.
flags.makeExitMsg = lógico(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. Ejecución de resultados

 

Supongo que te gusta

Origin blog.csdn.net/m0_57943157/article/details/132011964
Recomendado
Clasificación