Main Content

Mínimos cuadrados no lineales, sin y con matrices jacobianas

Este ejemplo muestra cómo resolver un problema de mínimos cuadrados no lineales de dos formas. El ejemplo resuelve primero el problema sin usar una función jacobiana. Después, muestra cómo incluir una matriz jacobiana e ilustra la eficiencia mejorada resultante.

El problema tiene 10 términos con dos incógnitas: encontrar x, un vector bidimensional, que minimiza

k=110(2+2k-ekx1-ekx2)2,

comenzando en el punto x0 = [0.3,0.4].

Dado que lsqnonlin asume que la suma de cuadrados no se forma explícitamente en la función del usuario, la función pasada a lsqnonlin debe calcular la función de valor vectorial

Fk(x)=2+2k-ekx1-ekx2,

para k = 1 a 10 (es decir, F debe tener 10 componentes).

Resolver el problema sin matriz jacobiana

La función auxiliar myfun definida al final de este ejemplo implementa la función objetivo de valor vectorial sin información de las derivadas. Resuelva la minimización restringida comenzando por el punto x0.

x0 = [0.3,0.4]; % Starting guess
[x,resnorm,res,eflag,output] = lsqnonlin(@myfun,x0); % Invoke optimizer
Local minimum possible.
lsqnonlin stopped because the size of the current step is less than
the value of the step size tolerance.

Examine la solución y el número de evaluaciones de función.

disp(x)
    0.2578    0.2578
disp(resnorm)
  124.3622
disp(output.funcCount)
    72

Resolver el problema con matriz jacobiana

La función objetivo es lo suficientemente simple como para que pueda calcular su matriz jacobiana. De acuerdo con la definición en Matrices jacobianas de funciones vectoriales, una función jacobiana representa la matriz

Jkj(x)=Fk(x)xj.

En este caso, Fk(x) es el k-ésimo componente de la función objetivo. Este ejemplo tiene

Fk(x)=2+2k-ekx1-ekx2,

así que

Jk1(x)=-kekx1Jk2(x)=-kekx2.

La función auxiliar myfun2 definida al final de este ejemplo implementa la función objetivo con la matriz jacobiana. Establezca las opciones para que el solver utilice la matriz jacobiana.

opts = optimoptions(@lsqnonlin,'SpecifyObjectiveGradient',true);

Ejecute el solver.

lb = []; % No bounds
ub = [];
[x2,resnorm2,res2,eflag2,output2] = lsqnonlin(@myfun2,x0,lb,ub,opts);
Local minimum possible.
lsqnonlin stopped because the size of the current step is less than
the value of the step size tolerance.

La solución es la misma que la solución anterior.

disp(x2)
    0.2578    0.2578
disp(resnorm2)
  124.3622

La ventaja de utilizar una matriz jacobiana es que el solver necesita muchas menos evaluaciones de función.

disp(output2.funcCount)
    24

Funciones auxiliares

Este código crea la función auxiliar myfun.

function F = myfun(x)
k = 1:10;
F = 2 + 2*k-exp(k*x(1))-exp(k*x(2));
end

Este código crea la función auxiliar myfun2.

function [F,J] = myfun2(x)
k = 1:10;
F = 2 + 2*k-exp(k*x(1))-exp(k*x(2));
if nargout > 1
    J = zeros(10,2);
    J(k,1) = -k.*exp(k*x(1));
    J(k,2) = -k.*exp(k*x(2));
end
end

Temas relacionados