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
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
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
En este caso, es el k-ésimo componente de la función objetivo. Este ejemplo tiene
así que
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