Escribir funciones objetivo escalares
Archivos de función
Un archivo de función objetivo escalar acepta una entrada, por ejemplo x
, y devuelve una salida escalar real, por ejemplo f
. La entrada x
puede ser un escalar, vector o matriz. Un archivo de función puede devolver más salidas (consulte Incluir gradientes y matrices hessianas).
Por ejemplo, suponga que su objetivo es una función de tres variables, x, y y z:
f(x) = 3*(x – y)4 + 4*(x + z)2 / (1 + x2 + y2 + z2) + cosh(x – 1) + tanh(y + z).
Escriba esta función como un archivo que acepta el vector
xin
= [x;y;z] y devuelve f:function f = myObjective(xin) f = 3*(xin(1)-xin(2))^4 + 4*(xin(1)+xin(3))^2/(1+norm(xin)^2) ... + cosh(xin(1)-1) + tanh(xin(2)+xin(3));
Guárdelo como un archivo llamado
myObjective.m
en una carpeta de la ruta de MATLAB®.Compruebe que la función realice la evaluación correctamente:
myObjective([1;2;3]) ans = 9.2666
Para obtener más información sobre cómo incluir parámetros adicionales, consulte Pasar parámetros adicionales. Para ver más ejemplos complejos de archivos de función, consulte Minimization with Gradient and Hessian Sparsity Pattern o Minimization with Bound Constraints and Banded Preconditioner.
Funciones locales y funciones anidadas
Las funciones pueden existir dentro de otros archivos como funciones locales o funciones anidadas. Con las funciones locales o funciones anidadas se puede reducir el número de archivos diferentes que se guardan. Con las funciones anidadas también podrá acceder a parámetros adicionales, como se muestra en Funciones anidadas.
Por ejemplo, suponga que desea minimizar la función objetivo myObjective.m
, descrita en Archivos de función, sujeta a la restricción ellipseparabola.m
, descrita en Restricciones no lineales. En lugar de escribir dos archivos, myObjective.m
y ellipseparabola.m
, escriba un archivo que contenga ambas funciones como funciones locales:
function [x fval] = callObjConstr(x0,options) % Using a local function for just one file if nargin < 2 options = optimoptions('fmincon','Algorithm','interior-point'); end [x fval] = fmincon(@myObjective,x0,[],[],[],[],[],[], ... @ellipseparabola,options); function f = myObjective(xin) f = 3*(xin(1)-xin(2))^4 + 4*(xin(1)+xin(3))^2/(1+sum(xin.^2)) ... + cosh(xin(1)-1) + tanh(xin(2)+xin(3)); function [c,ceq] = ellipseparabola(x) c(1) = (x(1)^2)/9 + (x(2)^2)/4 - 1; c(2) = x(1)^2 - x(2) - 1; ceq = [];
Resuelva la minimización restringida comenzando por el punto [1;1;1]
:
[x fval] = callObjConstr(ones(3,1)) Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the default value of the function tolerance, and constraints are satisfied to within the default value of the constraint tolerance. x = 1.1835 0.8345 -1.6439 fval = 0.5383
Objetivos de función anónima
Utilice funciones anónimas para escribir funciones objetivo simples. Para obtener más información sobre funciones anónimas, consulte ¿Qué son las funciones anónimas?. La función de Rosenbrock es lo suficientemente simple como para escribirla como una función anónima:
anonrosen = @(x)(100*(x(2) - x(1)^2)^2 + (1-x(1))^2);
anonrosen
realice la evaluación correctamente en [-1 2]
:anonrosen([-1 2]) ans = 104
anonrosen
con fminunc
, se obtienen los siguientes resultados:options = optimoptions(@fminunc,'Algorithm','quasi-newton'); [x fval] = fminunc(anonrosen,[-1;2],options) Local minimum found. Optimization completed because the size of the gradient is less than the default value of the function tolerance. x = 1.0000 1.0000 fval = 1.2266e-10
Incluir gradientes y matrices hessianas
Proporcionar derivadas para solvers
Para fmincon
y fminunc
, puede incluir gradientes en la función objetivo. Por lo general, los solvers son más robustos y pueden ser ligeramente más rápidos cuando se incluyen gradientes. Consulte Beneficios de incluir derivadas. Para incluir también segundas derivadas (matrices hessianas), consulte Incluir matrices hessianas.
La siguiente tabla muestra qué algoritmos pueden utilizar gradientes y matrices hessianas.
Solver | Algoritmo | Gradiente | Matriz hessiana |
---|---|---|---|
fmincon | active-set | Opcional | No |
interior-point | Opcional | Opcional (consulte Matriz hessiana para el algoritmo fmincon interior-point) | |
sqp | Opcional | No | |
trust-region-reflective | Necesario | Opcional (consulte Matriz hessiana para los algoritmos fminunc trust-region o fmincon trust-region-reflective) | |
fminunc | quasi-newton | Opcional | No |
trust-region | Necesario | Opcional (consulte Matriz hessiana para los algoritmos fminunc trust-region o fmincon trust-region-reflective) |
Cómo incluir gradientes
Escriba código que devuelva:
La función objetivo (escalar) como primera salida
El gradiente (vector) como segunda salida
Establezca la opción
SpecifyObjectiveGradient
entrue
medianteoptimoptions
. Si fuera apropiado, establezca también la opciónSpecifyConstraintGradient
entrue
.Opcionalmente, compruebe que la función de gradiente coincida con una aproximación de diferencias finitas. Consulte Checking Validity of Gradients or Jacobians.
Sugerencia
Para una mayor flexibilidad, escriba código condicionalizado. Condicionalizado significa que el número de salidas de función puede variar, como se muestra en el siguiente ejemplo. El código condicionalizado no provoca un error en función del valor de la opción SpecifyObjectiveGradient
. El código no condicionalizado requiere que establezca las opciones correctamente.
Por ejemplo, considere la función de Rosenbrock
que se describe y representa en Problema no lineal restringido utilizando la tarea Optimize de Live Editor o el solver. El gradiente de f(x) es
rosentwo
es una función condicionalizada que devuelve lo que el solver necesite:
function [f,g] = rosentwo(x) % Calculate objective f f = 100*(x(2) - x(1)^2)^2 + (1-x(1))^2; if nargout > 1 % gradient required g = [-400*(x(2)-x(1)^2)*x(1)-2*(1-x(1)); 200*(x(2)-x(1)^2)]; end
nargout
comprueba el número de argumentos que especifica una función que realiza la llamada. Consulte Buscar el número de argumentos de funciones.
El solver fminunc
, diseñado para optimización no restringida, permite minimizar la función de Rosenbrock. Indique a fminunc
que utilice el gradiente y la matriz hessiana estableciendo options
:
options = optimoptions(@fminunc,'Algorithm','trust-region',... 'SpecifyObjectiveGradient',true);
Ejecute fminunc
comenzando en [-1;2]
:
[x fval] = fminunc(@rosentwo,[-1;2],options) Local minimum found. Optimization completed because the size of the gradient is less than the default value of the function tolerance. x = 1.0000 1.0000 fval = 1.9886e-17
Si tiene una licencia de Symbolic Math Toolbox™, puede calcular gradientes y matrices hessianas de forma automática, tal y como se describe en Calculate Gradients and Hessians Using Symbolic Math Toolbox.
Incluir matrices hessianas
Puede incluir segundas derivadas con los algoritmos fmincon
'trust-region-reflective'
e 'interior-point'
, y con el algoritmo fminunc
'trust-region'
. Hay varias formas de incluir información de matrices hessianas, en función del tipo de información y del algoritmo.
También debe incluir gradientes (establezca SpecifyObjectiveGradient
en true
y, si procede, SpecifyConstraintGradient
en true
) para incluir matrices hessianas.
Matriz hessiana para los algoritmos fminunc
trust-region o fmincon
trust-region-reflective. Estos algoritmos o bien no tienen restricciones, o bien tienen únicamente límites de restricciones o restricciones de igualdad lineales. De este modo, la matriz hessiana es la matriz de segundas derivadas de la función objetivo.
Incluya la matriz hessiana como tercera salida de la función objetivo. Por ejemplo, la matriz hessiana H(x) de la función de Rosenbrock es (consulte Cómo incluir gradientes)
Incluya esta matriz hessiana en el objetivo:
function [f, g, H] = rosenboth(x) % Calculate objective f f = 100*(x(2) - x(1)^2)^2 + (1-x(1))^2; if nargout > 1 % gradient required g = [-400*(x(2)-x(1)^2)*x(1)-2*(1-x(1)); 200*(x(2)-x(1)^2)]; if nargout > 2 % Hessian required H = [1200*x(1)^2-400*x(2)+2, -400*x(1); -400*x(1), 200]; end end
Establezca HessianFcn
en 'objective'
. Por ejemplo:
options = optimoptions('fminunc','Algorithm','trust-region',... 'SpecifyObjectiveGradient',true,'HessianFcn','objective');
Matriz hessiana para el algoritmo fmincon
interior-point. La matriz hessiana es la matriz hessiana del lagrangiano, donde el lagrangiano L(x,λ) es
g y h son funciones vectoriales que representan todas las restricciones de desigualdad e igualdad respectivamente (es decir, límites de restricciones y restricciones lineales y no lineales), por lo que el problema de minimización es
Para obtener más detalles, consulte Teoría de optimalidad restringida. La matriz hessiana del lagrangiano es
(1) |
Para incluir una matriz hessiana, escriba una función con la sintaxis
hessian = hessianfcn(x,lambda)
hessian
es una matriz de n por n, dispersa o densa, donde n es el número de variables. Si hessian
es grande y tiene relativamente pocas entradas distintas de cero, ahorre tiempo de ejecución y memoria representando hessian
como una matriz dispersa. lambda
es una estructura con los vectores de multiplicadores de Lagrange asociados a las restricciones no lineales:
lambda.ineqnonlin lambda.eqnonlin
fmincon
calcula la estructura lambda
y la pasa a su función de matriz hessiana. hessianfcn
debe calcular las sumas en Ecuación 1. Indique que va a proporcionar una matriz hessiana estableciendo estas opciones:
options = optimoptions('fmincon','Algorithm','interior-point',... 'SpecifyObjectiveGradient',true,'SpecifyConstraintGradient',true,... 'HessianFcn',@hessianfcn);
Por ejemplo, para incluir una matriz hessiana para la función de Rosenbrock restringida al disco unidad , observe que la función de restricción tiene gradiente y matriz de segunda derivada
Escriba la función de matriz hessiana como
function Hout = hessianfcn(x,lambda) % Hessian of objective H = [1200*x(1)^2-400*x(2)+2, -400*x(1); -400*x(1), 200]; % Hessian of nonlinear inequality constraint Hg = 2*eye(2); Hout = H + lambda.ineqnonlin*Hg;
Guarde hessianfcn
en la ruta de MATLAB. Para completar el ejemplo, la función de restricción incluyendo gradientes es
function [c,ceq,gc,gceq] = unitdisk2(x) c = x(1)^2 + x(2)^2 - 1; ceq = [ ]; if nargout > 2 gc = [2*x(1);2*x(2)]; gceq = []; end
Resuelva el problema incluyendo gradientes y una matriz hessiana.
fun = @rosenboth; nonlcon = @unitdisk2; x0 = [-1;2]; options = optimoptions('fmincon','Algorithm','interior-point',... 'SpecifyObjectiveGradient',true,'SpecifyConstraintGradient',true,... 'HessianFcn',@hessianfcn); [x,fval,exitflag,output] = fmincon(fun,x0,[],[],[],[],[],[],@unitdisk2,options);
Para ver otros ejemplos utilizando una matriz hessiana interior-point, consulte Algoritmo interior-point de fmincon con matriz hessiana analítica y Calculate Gradients and Hessians Using Symbolic Math Toolbox.
Función de multiplicación de matriz hessiana. En lugar de una función de matriz hessiana completa, los algoritmos fmincon
interior-point
y trust-region-reflective
permiten proporcionar una función de multiplicación de matriz hessiana. Esta función da el resultado de un producto del vector por la matriz hessiana sin calcular la matriz hessiana directamente. Esto puede ahorrar memoria. La opción SubproblemAlgorithm
debe ser 'cg'
para que una función de multiplicación de matriz hessiana funcione; este es el trust-region-reflective
predeterminado.
Las sintaxis para los dos algoritmos difieren.
Para el algoritmo
interior-point
, la sintaxis esW = HessMultFcn(x,lambda,v);
El resultado
W
debería ser el producto deH*v
, dondeH
es la matriz hessiana del lagrangiano enx
(consulte Ecuación 1),lambda
es el multiplicador de Lagrange (calculado porfmincon
) yv
es un vector de tamaño n por 1. Establezca las opciones de la siguiente manera:options = optimoptions('fmincon','Algorithm','interior-point','SpecifyObjectiveGradient',true,... 'SpecifyConstraintGradient',true,'SubproblemAlgorithm','cg','HessianMultiplyFcn',@HessMultFcn);
Proporcione la función
HessMultFcn
, que devuelve un vector de n por 1, donde n es el número de dimensiones de x. La opciónHessianMultiplyFcn
permite pasar el resultado de multiplicar la matriz hessiana por un vector sin calcular dicha matriz hessiana.El algoritmo
trust-region-reflective
no incluye alambda
:W = HessMultFcn(H,v);
El resultado
W = H*v
.fmincon
pasaH
como el valor devuelto en la tercera salida de la función objetivo (consulte Matriz hessiana para los algoritmos fminunc trust-region o fmincon trust-region-reflective).fmincon
también pasav
, un vector o matriz con n filas. El número de columnas dev
puede variar, así que escribaHessMultFcn
para aceptar un número arbitrario de columnas.H
no tiene por qué ser la matriz hessiana; es más, puede ser cualquier elemento que permita calcularW = H*v
.Establezca las opciones de la siguiente manera:
options = optimoptions('fmincon','Algorithm','trust-region-reflective',... 'SpecifyObjectiveGradient',true,'HessianMultiplyFcn',@HessMultFcn);
Para ver un ejemplo que utilice una función de multiplicación de matriz hessiana con el algoritmo
trust-region-reflective
, consulte Minimization with Dense Structured Hessian, Linear Equalities.
Beneficios de incluir derivadas
Si no proporciona gradientes, los solvers estiman gradientes mediante diferencias finitas. Si proporciona gradientes, el solver no necesita realizar esta estimación de diferencias finitas, por lo que puede ahorrar tiempo y obtener más precisión, aunque una estimación de diferencias finitas puede ser más rápida para derivadas complicadas. Además, los solvers utilizan una matriz hessiana aproximada, que puede diferir bastante de la matriz hessiana real. Proporcionando una matriz hessiana, se puede obtener una solución en menos iteraciones. Por ejemplo, consulte el final de Calculate Gradients and Hessians Using Symbolic Math Toolbox.
Para problemas restringidos, proporcionar un gradiente ofrece otra ventaja. Un solver puede alcanzar un punto x
de forma que x
sea factible, pero, para este punto x
, las diferencias finitas alrededor de x
siempre conducen a un punto no factible. Suponga, además, que la función objetivo en un punto no factible devuelve una salida compleja, Inf
, NaN
o un error. En este caso, un solver puede fallar o detenerse prematuramente. Proporcionar un gradiente permite al solver continuar. Para aprovechar esta ventaja, es posible que también necesite incluir el gradiente de una función de restricción no lineal y establecer la opción SpecifyConstraintGradient
en true
. Consulte Restricciones no lineales.
Escoger una aproximación de matriz hessiana de entrada para fmincon
interior-point
El algoritmo fmincon
interior-point
cuenta con muchas opciones para seleccionar una aproximación de matriz hessiana de entrada. Para obtener más detalles de la sintaxis, consulte Matriz hessiana como entrada. Aquí están las opciones, junto con las estimaciones de sus características relativas.
Matriz hessiana | Uso relativo de memoria | Eficiencia relativa |
---|---|---|
'bfgs' (valor predeterminado) | Alto (para problemas grandes) | Alta |
'lbfgs' | Bajo a moderado | Moderada |
'fin-diff-grads' | Bajo | Moderada |
'HessianMultiplyFcn' | Bajo (puede depender del código) | Moderada |
'HessianFcn' | ? (depende del código) | Alta (depende del código) |
Utilice la matriz hessiana 'bfgs'
predeterminada a menos que
Se quede sin memoria: inténtelo con
'lbfgs'
en lugar de'bfgs'
. Si puede proporcionar sus propios gradientes, inténtelo con'fin-diff-grads'
y establezca las opcionesSpecifyObjectiveGradient
ySpecifyConstraintGradient
entrue
.Desea más eficiencia: proporcione sus propios gradientes y matriz hessiana. Consulte Incluir matrices hessianas, Algoritmo interior-point de fmincon con matriz hessiana analítica y Calculate Gradients and Hessians Using Symbolic Math Toolbox.
La razón por la que 'lbfgs'
tiene solo eficiencia moderada es doble. Tiene actualizaciones Sherman-Morrison relativamente costosas. Y el paso de iteración resultante puede ser en cierto modo inexacto a consecuencia de la memoria limitada de 'lbfgs'
.
La razón por la que 'fin-diff-grads'
y HessianMultiplyFcn
tienen solo eficiencia moderada es que utilizan un enfoque de gradiente conjugado. Estiman de forma precisa la matriz hessiana de la función objetivo, pero no generan el paso de iteración más preciso. Para obtener más información, consulte fmincon Interior Point Algorithm y su debate sobre el enfoque LDL y el enfoque de gradiente conjugado que se desea resolver Ecuación 38.