Main Content

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 J(x) de un sistema de ecuaciones F(x) es Jij(x)=Fi(x)xj. Proporcione esta derivada como segunda salida para su función objetivo.

Por ejemplo, la función multirosenbrock es una generalización n-dimensional de la función de Rosenbrock (consulte Resolver un problema no lineal restringido, basado problemas) para cualquier valor positivo par de n:

F(1)=1-x1F(2)=10(x2-x12)F(3)=1-x3F(4)=10(x4-x32)F(n-1)=1-xn-1F(n)=10(xn-xn-12).

La solución del sistema de ecuación F(x)=0 es el punto xi=1, i=1n.

Para esta función objetivo, todos los términos jacobianos Jij(x) son cero excepto los términos donde i y j difieren en al menos uno. Para valores impares de i<n, los términos distintos de cero son

Jii(x)=-1J(i+1)i=-20xiJ(i+1)(i+1)=10.

La función auxiliar multirosenbrock al final de este ejemplo crea la función objetivo F(x) y su matriz jacobiana J(x).

Resuelva el sistema de ecuaciones comenzando en el punto xi=-1.9 para valores impares de i<n y xi=2 para valores pares de i. Especifique n=64.

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

Consulte también

Temas relacionados