Resolver un sistema no lineal, sin y con matrices jacobianas
Este ejemplo muestra la reducción en evaluaciones de función cuando proporciona derivadas para un sistema de ecuaciones no lineales. Como se explica en Escribir funciones objetivo de vector y de matriz, la matriz jacobiana de un sistema de ecuaciones es . Proporcione esta derivada como segunda salida para su función objetivo.
Por ejemplo, la función multirosenbrock
es una generalización -dimensional de la función de Rosenbrock (consulte Resolver un problema no lineal restringido, basado problemas) para cualquier valor positivo par de :
La solución del sistema de ecuación es el punto , .
Para esta función objetivo, todos los términos jacobianos son cero excepto los términos donde y difieren en al menos uno. Para valores impares de , los términos distintos de cero son
La función auxiliar multirosenbrock
al final de este ejemplo crea la función objetivo y su matriz jacobiana .
Resuelva el sistema de ecuaciones comenzando en el punto para valores impares de y para valores pares de . Especifique .
n = 64; x0(1:n,1) = -1.9; x0(2:2:n,1) = 2; [x,F,exitflag,output,JAC] = fsolve(@multirosenbrock,x0);
Equation solved. fsolve completed because the vector of function values is near zero as measured by the value of the function tolerance, and the problem appears regular as measured by the gradient.
Examine la distancia de la solución calculada x
a la solución real y el número de evaluaciones de función que fsolve
necesita para calcular la solución.
disp(norm(x-ones(size(x))))
0
disp(output.funcCount)
1043
fsolve
encuentra la solución y necesita más de 1.000 evaluaciones de función para hacerlo.
Resuelva el sistema de ecuaciones de nuevo, ahora utilizando la matriz jacobiana. Para hacerlo, establezca la opción 'SpecifyObjectiveGradient'
en true
.
opts = optimoptions('fsolve','SpecifyObjectiveGradient',true); [x2,F2,exitflag2,output2,JAC2] = fsolve(@multirosenbrock,x0,opts);
Equation solved. fsolve completed because the vector of function values is near zero as measured by the value of the function tolerance, and the problem appears regular as measured by the gradient.
Una vez más, examine la distancia de la solución calculada x2
a la solución real y el número de evaluaciones de función que fsolve
necesita para calcular la solución.
disp(norm(x2-ones(size(x2))))
0
disp(output2.funcCount)
21
fsolve
devuelve la misma solución que anteriormente, pero necesita unas 20 evaluaciones de función para hacerlo, en lugar de más de 1.000. En general, utilizar la matriz jacobiana puede reducir el número de evaluaciones de función y obtener una mayor robustez, aunque este ejemplo no muestra dicha mejora de la robustez.
Función auxiliar
Este código crea la función auxiliar multirosenbrock
.
function [F,J] = multirosenbrock(x) % Get the problem size n = length(x); if n == 0, error('Input vector, x, is empty.'); end if mod(n,2) ~= 0 error('Input vector, x ,must have an even number of components.'); end % Evaluate the vector function odds = 1:2:n; evens = 2:2:n; F = zeros(n,1); F(odds,1) = 1-x(odds); F(evens,1) = 10.*(x(evens)-x(odds).^2); % Evaluate the Jacobian matrix if nargout > 1 if nargout > 1 c = -ones(n/2,1); C = sparse(odds,odds,c,n,n); d = 10*ones(n/2,1); D = sparse(evens,evens,d,n,n); e = -20.*x(odds); E = sparse(evens,odds,e,n,n); J = C + D + E; end end