Esta página aún no se ha traducido para esta versión. Puede ver la versión más reciente de esta página en inglés.

Uso de matemáticas simbólicas con Optimization Toolbox™ Solvers

En este ejemplo se muestra cómo utilizar las funciones de la caja de herramientas matemática simbólica™ y proporcionar derivados analíticos a los solucionadores de optimización.jacobianmatlabFunction Optimization Toolbox™ los solucionadores suelen ser más precisos y eficientes cuando se suministran gradientes y hessianos de las funciones objetivo y restricción.

Hay varias consideraciones en el uso de cálculos simbólicos con funciones de optimización:

  1. El objetivo de optimización y las funciones de restricción deben definirse en términos de un vector, digamos.x Sin embargo, las variables simbólicas son escalares o de valor complejo, no con valores vectoriales. Esto requiere que traduzcas entre vectores y escalares.

  2. Se supone que los degradados de optimización, y a veces los hessianos, se calculan dentro del cuerpo de las funciones objetivas o de restricción. Esto significa que un degradado simbólico o hessian debe colocarse en el lugar apropiado en el archivo de función objetivo o restricción o el manejador de función.

  3. Calcular gradientes y hessianos simbólicamente puede llevar mucho tiempo. Por lo tanto, debe realizar este cálculo solo una vez y generar código, a través de, para llamar durante la ejecución del solucionador.matlabFunction

  4. La evaluación de expresiones simbólicas con la función consume mucho tiempo.subs Es mucho más eficiente de usar.matlabFunction

  5. genera código que depende de la orientación de los vectores de entrada.matlabFunction Puesto que llama a la función objetiva con vectores de columna, debe tener cuidado de llamar con vectores de columna de variables simbólicas.fminconmatlabFunction

Primer ejemplo: minimización sin restricciones con hessian

La función objetivo a minimizar es:

<math display="block">
<mrow>
<mi>f</mi>
<mo stretchy="false">(</mo>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
<mo>,</mo>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msub>
<mo stretchy="false">)</mo>
<mo>=</mo>
<mi mathvariant="normal">log</mi>
<mrow>
<mo>(</mo>
<mn>1</mn>
<mo>+</mo>
<mn>3</mn>
<msup>
<mrow>
<mo>(</mo>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msub>
<mo>-</mo>
<mo stretchy="false">(</mo>
<msubsup>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
<mrow>
<mn>3</mn>
</mrow>
</msubsup>
<mo>-</mo>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
<mo stretchy="false">)</mo>
<mo>)</mo>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo>+</mo>
<mo stretchy="false">(</mo>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
<mo>-</mo>
<mn>4</mn>
<mo>/</mo>
<mn>3</mn>
<msup>
<mrow>
<mo stretchy="false">)</mo>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo>)</mo>
</mrow>
<mo>.</mo>
</mrow>
</math>

Esta función es positiva, con un valor mínimo único de cero alcanzado en = 4/3, = (4/3) ^ 3-4/3 = 1,0370...x1x2

Escribimos las variables independientes como y porque en esta forma se pueden utilizar como variables simbólicas.x1x2 Como componentes de un vector se escribirían y.xx(1)x(2) La función tiene un valle sinuoso como se muestra en la siguiente parcela.

syms x1 x2 real x = [x1;x2]; % column vector of symbolic variables f = log(1 + 3*(x2 - (x1^3 - x1))^2 + (x1 - 4/3)^2)
f = 
<math display="block">
<mrow>
<mi>log</mi>
<mrow>
<mrow>
<mo>(</mo>
<mrow>
<mrow>
<mrow>
<msup>
<mrow>
<mfenced close=")" open="(">
<mrow>
<mrow>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mo>-</mo>
<mrow>
<mfrac>
<mrow>
<mn>4</mn>
</mrow>
<mrow>
<mn>3</mn>
</mrow>
</mfrac>
</mrow>
</mrow>
</mrow>
</mfenced>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
</mrow>
<mo>+</mo>
<mrow>
<mn>3</mn>
<mo></mo>
<mrow>
<msup>
<mrow>
<mfenced close=")" open="(">
<mrow>
<mrow>
<mo>-</mo>
<mrow>
<msup>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mrow>
<mn>3</mn>
</mrow>
</msup>
</mrow>
<mo>+</mo>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mo>+</mo>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msub>
</mrow>
</mrow>
</mrow>
</mfenced>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
</mrow>
</mrow>
<mo>+</mo>
<mn>1</mn>
</mrow>
</mrow>
<mo>)</mo>
</mrow>
</mrow>
</mrow>
</math>
 fsurf(f,[-2 2],'ShowContours','on') view(127,38)

Calcular el gradiente y hessian de f:

gradf = jacobian(f,x).' % column gradf
gradf = 
<math display="block">
<mrow>
<mtable columnalign="left">
<mtr>
<mtd>
<mrow>
<mrow>
<mo>(</mo>
<mtable>
<mtr>
<mtd>
<mrow>
<mo>-</mo>
<mrow>
<mfrac>
<mrow>
<mrow>
<mn>6</mn>
<mo></mo>
<mfenced close=")" open="(">
<mrow>
<mrow>
<mrow>
<mn>3</mn>
<mo></mo>
<mrow>
<msup>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
</mrow>
</mrow>
<mo>-</mo>
<mn>1</mn>
</mrow>
</mrow>
</mfenced>
<mo></mo>
<mfenced close=")" open="(">
<mrow>
<mrow>
<mo>-</mo>
<mrow>
<msup>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mrow>
<mn>3</mn>
</mrow>
</msup>
</mrow>
<mo>+</mo>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mo>+</mo>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msub>
</mrow>
</mrow>
</mrow>
</mfenced>
</mrow>
<mo>-</mo>
<mrow>
<mn>2</mn>
<mo></mo>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
</mrow>
<mo>+</mo>
<mrow>
<mfrac>
<mrow>
<mn>8</mn>
</mrow>
<mrow>
<mn>3</mn>
</mrow>
</mfrac>
</mrow>
</mrow>
<mrow>
<msub>
<mrow>
<mi>σ</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
</mfrac>
</mrow>
</mrow>
</mtd>
</mtr>
<mtr>
<mtd>
<mrow>
<mfrac>
<mrow>
<mo>-</mo>
<mrow>
<mn>6</mn>
<mo></mo>
<mrow>
<msup>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mrow>
<mn>3</mn>
</mrow>
</msup>
</mrow>
</mrow>
<mo>+</mo>
<mrow>
<mn>6</mn>
<mo></mo>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
</mrow>
<mo>+</mo>
<mrow>
<mn>6</mn>
<mo></mo>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msub>
</mrow>
</mrow>
</mrow>
<mrow>
<msub>
<mrow>
<mi>σ</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
</mfrac>
</mrow>
</mtd>
</mtr>
</mtable>
<mo>)</mo>
</mrow>
</mrow>
</mtd>
</mtr>
<mtr>
<mtd>
<mrow>
<mi></mi>
</mrow>
</mtd>
</mtr>
<mtr>
<mtd>
<mrow>
<mi mathvariant="normal">where</mi>
</mrow>
</mtd>
</mtr>
<mtr>
<mtd>
<mrow>
<mi></mi>
</mrow>
</mtd>
</mtr>
<mtr>
<mtd>
<mrow>
<mi mathvariant="normal">  </mi>
<mrow></mrow>
<mrow>
<mrow>
<msub>
<mrow>
<mi>σ</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mo>=</mo>
<mrow>
<mrow>
<msup>
<mrow>
<mfenced close=")" open="(">
<mrow>
<mrow>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mo>-</mo>
<mrow>
<mfrac>
<mrow>
<mn>4</mn>
</mrow>
<mrow>
<mn>3</mn>
</mrow>
</mfrac>
</mrow>
</mrow>
</mrow>
</mfenced>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
</mrow>
<mo>+</mo>
<mrow>
<mn>3</mn>
<mo></mo>
<mrow>
<msup>
<mrow>
<mfenced close=")" open="(">
<mrow>
<mrow>
<mo>-</mo>
<mrow>
<msup>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mrow>
<mn>3</mn>
</mrow>
</msup>
</mrow>
<mo>+</mo>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mo>+</mo>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msub>
</mrow>
</mrow>
</mrow>
</mfenced>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
</mrow>
</mrow>
<mo>+</mo>
<mn>1</mn>
</mrow>
</mrow>
</mrow>
</mtd>
</mtr>
</mtable>
</mrow>
</math>
hessf = jacobian(gradf,x)
hessf = 
<math display="block">
<mrow>
<mtable columnalign="left">
<mtr>
<mtd>
<mrow>
<mrow>
<mo>(</mo>
<mtable>
<mtr>
<mtd>
<mrow>
<mrow>
<mfrac>
<mrow>
<mrow>
<mn>6</mn>
<mo></mo>
<mrow>
<msup>
<mrow>
<mfenced close=")" open="(">
<mrow>
<mrow>
<mrow>
<mn>3</mn>
<mo></mo>
<mrow>
<msup>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
</mrow>
</mrow>
<mo>-</mo>
<mn>1</mn>
</mrow>
</mrow>
</mfenced>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
</mrow>
</mrow>
<mo>-</mo>
<mrow>
<mn>36</mn>
<mo></mo>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mo></mo>
<mfenced close=")" open="(">
<mrow>
<mrow>
<mo>-</mo>
<mrow>
<msup>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mrow>
<mn>3</mn>
</mrow>
</msup>
</mrow>
<mo>+</mo>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mo>+</mo>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msub>
</mrow>
</mrow>
</mrow>
</mfenced>
</mrow>
<mo>+</mo>
<mn>2</mn>
</mrow>
<mrow>
<msub>
<mrow>
<mi>σ</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msub>
</mrow>
</mfrac>
</mrow>
<mo>-</mo>
<mrow>
<mfrac>
<mrow>
<msup>
<mrow>
<msub>
<mrow>
<mi>σ</mi>
</mrow>
<mrow>
<mn>3</mn>
</mrow>
</msub>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
</mrow>
<mrow>
<msup>
<mrow>
<msub>
<mrow>
<mi>σ</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msub>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
</mrow>
</mfrac>
</mrow>
</mrow>
</mtd>
<mtd>
<mrow>
<msub>
<mrow>
<mi>σ</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
</mtd>
</mtr>
<mtr>
<mtd>
<mrow>
<msub>
<mrow>
<mi>σ</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
</mtd>
<mtd>
<mrow>
<mrow>
<mfrac>
<mrow>
<mn>6</mn>
</mrow>
<mrow>
<msub>
<mrow>
<mi>σ</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msub>
</mrow>
</mfrac>
</mrow>
<mo>-</mo>
<mrow>
<mfrac>
<mrow>
<msup>
<mrow>
<mfenced close=")" open="(">
<mrow>
<mrow>
<mo>-</mo>
<mrow>
<mn>6</mn>
<mo></mo>
<mrow>
<msup>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mrow>
<mn>3</mn>
</mrow>
</msup>
</mrow>
</mrow>
<mo>+</mo>
<mrow>
<mn>6</mn>
<mo></mo>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
</mrow>
<mo>+</mo>
<mrow>
<mn>6</mn>
<mo></mo>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msub>
</mrow>
</mrow>
</mrow>
</mrow>
</mfenced>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
</mrow>
<mrow>
<msup>
<mrow>
<msub>
<mrow>
<mi>σ</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msub>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
</mrow>
</mfrac>
</mrow>
</mrow>
</mtd>
</mtr>
</mtable>
<mo>)</mo>
</mrow>
</mrow>
</mtd>
</mtr>
<mtr>
<mtd>
<mrow>
<mi></mi>
</mrow>
</mtd>
</mtr>
<mtr>
<mtd>
<mrow>
<mi mathvariant="normal">where</mi>
</mrow>
</mtd>
</mtr>
<mtr>
<mtd>
<mrow>
<mi></mi>
</mrow>
</mtd>
</mtr>
<mtr>
<mtd>
<mrow>
<mi mathvariant="normal">  </mi>
<mrow></mrow>
<mrow>
<mrow>
<msub>
<mrow>
<mi>σ</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mo>=</mo>
<mrow>
<mrow>
<mfrac>
<mrow>
<mfenced close=")" open="(">
<mrow>
<mrow>
<mo>-</mo>
<mrow>
<mn>6</mn>
<mo></mo>
<mrow>
<msup>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mrow>
<mn>3</mn>
</mrow>
</msup>
</mrow>
</mrow>
<mo>+</mo>
<mrow>
<mn>6</mn>
<mo></mo>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
</mrow>
<mo>+</mo>
<mrow>
<mn>6</mn>
<mo></mo>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msub>
</mrow>
</mrow>
</mrow>
</mrow>
</mfenced>
<mo></mo>
<mrow>
<msub>
<mrow>
<mi>σ</mi>
</mrow>
<mrow>
<mn>3</mn>
</mrow>
</msub>
</mrow>
</mrow>
<mrow>
<msup>
<mrow>
<msub>
<mrow>
<mi>σ</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msub>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
</mrow>
</mfrac>
</mrow>
<mo>-</mo>
<mrow>
<mfrac>
<mrow>
<mrow>
<mn>18</mn>
<mo></mo>
<mrow>
<msup>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
</mrow>
</mrow>
<mo>-</mo>
<mn>6</mn>
</mrow>
<mrow>
<msub>
<mrow>
<mi>σ</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msub>
</mrow>
</mfrac>
</mrow>
</mrow>
</mrow>
</mrow>
</mtd>
</mtr>
<mtr>
<mtd>
<mrow>
<mi></mi>
</mrow>
</mtd>
</mtr>
<mtr>
<mtd>
<mrow>
<mi mathvariant="normal">  </mi>
<mrow></mrow>
<mrow>
<mrow>
<msub>
<mrow>
<mi>σ</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msub>
</mrow>
<mo>=</mo>
<mrow>
<mrow>
<msup>
<mrow>
<mfenced close=")" open="(">
<mrow>
<mrow>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mo>-</mo>
<mrow>
<mfrac>
<mrow>
<mn>4</mn>
</mrow>
<mrow>
<mn>3</mn>
</mrow>
</mfrac>
</mrow>
</mrow>
</mrow>
</mfenced>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
</mrow>
<mo>+</mo>
<mrow>
<mn>3</mn>
<mo></mo>
<mrow>
<msup>
<mrow>
<mfenced close=")" open="(">
<mrow>
<mrow>
<mo>-</mo>
<mrow>
<msup>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mrow>
<mn>3</mn>
</mrow>
</msup>
</mrow>
<mo>+</mo>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mo>+</mo>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msub>
</mrow>
</mrow>
</mrow>
</mfenced>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
</mrow>
</mrow>
<mo>+</mo>
<mn>1</mn>
</mrow>
</mrow>
</mrow>
</mtd>
</mtr>
<mtr>
<mtd>
<mrow>
<mi></mi>
</mrow>
</mtd>
</mtr>
<mtr>
<mtd>
<mrow>
<mi mathvariant="normal">  </mi>
<mrow></mrow>
<mrow>
<mrow>
<msub>
<mrow>
<mi>σ</mi>
</mrow>
<mrow>
<mn>3</mn>
</mrow>
</msub>
</mrow>
<mo>=</mo>
<mrow>
<mrow>
<mn>6</mn>
<mo></mo>
<mfenced close=")" open="(">
<mrow>
<mrow>
<mrow>
<mn>3</mn>
<mo></mo>
<mrow>
<msup>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
</mrow>
</mrow>
<mo>-</mo>
<mn>1</mn>
</mrow>
</mrow>
</mfenced>
<mo></mo>
<mfenced close=")" open="(">
<mrow>
<mrow>
<mo>-</mo>
<mrow>
<msup>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mrow>
<mn>3</mn>
</mrow>
</msup>
</mrow>
<mo>+</mo>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
<mo>+</mo>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msub>
</mrow>
</mrow>
</mrow>
</mfenced>
</mrow>
<mo>-</mo>
<mrow>
<mn>2</mn>
<mo></mo>
<mrow>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
</mrow>
</mrow>
<mo>+</mo>
<mrow>
<mfrac>
<mrow>
<mn>8</mn>
</mrow>
<mrow>
<mn>3</mn>
</mrow>
</mfrac>
</mrow>
</mrow>
</mrow>
</mrow>
</mtd>
</mtr>
</mtable>
</mrow>
</math>

El solucionador espera pasar un vector x y, con la opción establecida en y la opción establecida en, espera una lista de tres salidas:.fminuncSpecifyObjectiveGradienttrueHessianFcn'objective'[f(x),gradf(x),hessf(x)]

genera exactamente esta lista de tres salidas de una lista de tres entradas.matlabFunction Además, utilizando la opción, acepta entradas vectoriales.varsmatlabFunction

fh = matlabFunction(f,gradf,hessf,'vars',{x});

Ahora resuelva el problema de minimización comenzando en el punto [-1, 2]:

options = optimoptions('fminunc', ...     'SpecifyObjectiveGradient', true, ...     'HessianFcn', 'objective', ...     'Algorithm','trust-region', ...     'Display','final'); [xfinal,fval,exitflag,output] = fminunc(fh,[-1;2],options)
Local minimum possible.  fminunc stopped because the final change in function value relative to  its initial value is less than the value of the function tolerance. 
xfinal = 2×1

    1.3333
    1.0370

fval = 7.6623e-12 
exitflag = 3 
output = struct with fields:
         iterations: 14
          funcCount: 15
           stepsize: 0.0027
       cgiterations: 11
      firstorderopt: 3.4391e-05
          algorithm: 'trust-region'
            message: '...'
    constrviolation: []

Compare esto con el número de iteraciones que no utilizan ningún degradado o información de hessian. Esto requiere el algoritmo.'quasi-newton'

options = optimoptions('fminunc','Display','final','Algorithm','quasi-newton'); fh2 = matlabFunction(f,'vars',{x});  % fh2 = objective with no gradient or Hessian [xfinal,fval,exitflag,output2] = fminunc(fh2,[-1;2],options)
Local minimum possible.  fminunc stopped because it cannot decrease the objective function along the current search direction. 
xfinal = 2×1

    1.3333
    1.0370

fval = 7.9714e-14 
exitflag = 5 
output2 = struct with fields:
       iterations: 20
        funcCount: 99
         stepsize: 3.2455e-05
     lssteplength: 1
    firstorderopt: 4.0233e-06
        algorithm: 'quasi-newton'
          message: '...'

El número de iteraciones es menor cuando se utilizan gradientes y hessianos, y hay dramáticamente menos evaluaciones de funciones:

sprintf(['There were %d iterations using gradient' ...     ' and Hessian, but %d without them.'], ...     output.iterations,output2.iterations)
ans =  'There were 14 iterations using gradient and Hessian, but 20 without them.' 
sprintf(['There were %d function evaluations using gradient' ...     ' and Hessian, but %d without them.'], ...     output.funcCount,output2.funcCount)
ans =  'There were 15 function evaluations using gradient and Hessian, but 99 without them.' 

Segundo ejemplo: minimización restringida mediante el algoritmo de punto interior de fmincon

Consideramos la misma función objetiva y punto de partida, pero ahora tenemos dos restricciones no lineales:

<math display="block">
<mrow>
<mn>5</mn>
<mi mathvariant="normal">sinh</mi>
<mo stretchy="false">(</mo>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msub>
<mo>/</mo>
<mn>5</mn>
<mo stretchy="false">)</mo>
<mo></mo>
<msubsup>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
<mrow>
<mn>4</mn>
</mrow>
</msubsup>
</mrow>
</math>

<math display="block">
<mrow>
<mn>5</mn>
<mi mathvariant="normal">tanh</mi>
<mo stretchy="false">(</mo>
<msub>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>1</mn>
</mrow>
</msub>
<mo>/</mo>
<mn>5</mn>
<mo stretchy="false">)</mo>
<mo></mo>
<msubsup>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msubsup>
<mo>-</mo>
<mn>1</mn>
<mo>.</mo>
</mrow>
</math>

Las restricciones mantienen la optimización alejada del punto mínimo global [1.333, 1.037]. Visualice las dos restricciones:

[X,Y] = meshgrid(-2:.01:3); Z = (5*sinh(Y./5) >= X.^4);  % Z=1 where the first constraint is satisfied, Z=0 otherwise Z = Z+ 2*(5*tanh(X./5) >= Y.^2 - 1);  % Z=2 where the second is satisfied, Z=3 where both are surf(X,Y,Z,'LineStyle','none'); fig = gcf; fig.Color = 'w'; % white background view(0,90) hold on plot3(.4396, .0373, 4,'o','MarkerEdgeColor','r','MarkerSize',8);  % best point xlabel('x') ylabel('y') hold off

Trazamos un pequeño círculo rojo alrededor del punto óptimo.

Aquí hay una trama de la función objetiva sobre la región factible, la región que satisface ambas restricciones, en la foto de arriba en rojo oscuro, junto con un pequeño círculo rojo alrededor del punto óptimo:

W = log(1 + 3*(Y - (X.^3 - X)).^2 + (X - 4/3).^2);  % W = the objective function W(Z < 3) = nan; % plot only where the constraints are satisfied surf(X,Y,W,'LineStyle','none'); view(68,20) hold on plot3(.4396, .0373, .8152,'o','MarkerEdgeColor','r', ...     'MarkerSize',8); % best point xlabel('x') ylabel('y') zlabel('z') hold off

Las restricciones no lineales deben escribirse en el formulario.c(x) <= 0 Calculamos todas las restricciones simbólicas y sus derivados, y las colocamos en un manejador de funciones utilizando.matlabFunction

Los degradados de las restricciones deben ser vectores de columna; se deben colocar en la función objetivo como una matriz, con cada columna de la matriz que representa el degradado de una función de restricción. Esta es la transposición de la forma generada por, por lo que tomamos la transposición a continuación.jacobian

Colocamos las restricciones no lineales en un identificador de función. espera que las restricciones no lineales y los degradados se emiten en el orden.fmincon[c ceq gradc gradceq] Dado que no hay ninguna restricción de igualdad no lineal, se emite para y.[]ceqgradceq

c1 = x1^4 - 5*sinh(x2/5); c2 = x2^2 - 5*tanh(x1/5) - 1; c = [c1 c2]; gradc = jacobian(c,x).'; % transpose to put in correct form constraint = matlabFunction(c,[],gradc,[],'vars',{x});

El algoritmo de punto interior requiere que su función hessian se escribe como una función separada, en lugar de ser parte de la función objetiva. Esto se debe a que una función restringida no linealmente debe incluir esas restricciones en su hessian. Su hessian es el Hessiano de los Lagrangios; Consulte la guía del usuario para obtener más información.

La función hessian toma dos argumentos de entrada: el vector de posición y el lambda de la estructura de multiplicador de Lagrange.x Las partes de la estructura lambda que se utilizan para las restricciones no lineales son y.lambda.ineqnonlinlambda.eqnonlin Para la restricción actual, no hay ecualidades lineales, por lo que usamos los dos multiplicadores y.lambda.ineqnonlin(1)lambda.ineqnonlin(2)

En el primer ejemplo calculamos el Hessiano de la función objetiva. Ahora calculamos los hessianos de las dos funciones de restricción, y hacemos las versiones del manejador de la función con.matlabFunction

hessc1 = jacobian(gradc(:,1),x); % constraint = first c column hessc2 = jacobian(gradc(:,2),x);  hessfh = matlabFunction(hessf,'vars',{x}); hessc1h = matlabFunction(hessc1,'vars',{x}); hessc2h = matlabFunction(hessc2,'vars',{x});

Para hacer el hessian final, ponemos los tres hessianos juntos, añadiendo los multiplicadores de Lagrange apropiados a las funciones de restricción.

myhess = @(x,lambda)(hessfh(x) + ...     lambda.ineqnonlin(1)*hessc1h(x) + ...     lambda.ineqnonlin(2)*hessc2h(x));

Establezca las opciones para utilizar el algoritmo de punto interior, el degradado y el hessian, que la función objetiva devuelva tanto el objetivo como el degradado, y ejecute el solucionador:

options = optimoptions('fmincon', ...     'Algorithm','interior-point', ...     'SpecifyObjectiveGradient',true, ...     'SpecifyConstraintGradient',true, ...     'HessianFcn',myhess, ...     'Display','final'); % fh2 = objective without Hessian fh2 = matlabFunction(f,gradf,'vars',{x}); [xfinal,fval,exitflag,output] = fmincon(fh2,[-1;2],...     [],[],[],[],[],[],constraint,options)
Local minimum found that satisfies the constraints.  Optimization completed because the objective function is non-decreasing in  feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance. 
xfinal = 2×1

    0.4396
    0.0373

fval = 0.8152 
exitflag = 1 
output = struct with fields:
         iterations: 10
          funcCount: 13
    constrviolation: 0
           stepsize: 1.9160e-06
          algorithm: 'interior-point'
      firstorderopt: 1.9217e-08
       cgiterations: 0
            message: '...'

Una vez más, el solucionador realiza muchas menos iteraciones y evaluaciones de funciones con gradiente y hessian suministrado que cuando no son:

options = optimoptions('fmincon','Algorithm','interior-point',...     'Display','final'); % fh3 = objective without gradient or Hessian fh3 = matlabFunction(f,'vars',{x}); % constraint without gradient: constraint = matlabFunction(c,[],'vars',{x}); [xfinal,fval,exitflag,output2] = fmincon(fh3,[-1;2],...     [],[],[],[],[],[],constraint,options)
Local minimum found that satisfies the constraints.  Optimization completed because the objective function is non-decreasing in  feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance. 
xfinal = 2×1

    0.4396
    0.0373

fval = 0.8152 
exitflag = 1 
output2 = struct with fields:
         iterations: 16
          funcCount: 51
    constrviolation: 0
           stepsize: 1.1819e-07
          algorithm: 'interior-point'
      firstorderopt: 7.3186e-07
       cgiterations: 0
            message: '...'

 sprintf(['There were %d iterations using gradient' ...     ' and Hessian, but %d without them.'],...     output.iterations,output2.iterations)
ans =  'There were 10 iterations using gradient and Hessian, but 16 without them.' 
sprintf(['There were %d function evaluations using gradient' ...     ' and Hessian, but %d without them.'], ...     output.funcCount,output2.funcCount)
ans =  'There were 13 function evaluations using gradient and Hessian, but 51 without them.' 

Limpieza de variables simbólicas

Se suponía que las variables simbólicas utilizadas en este ejemplo eran reales. Para borrar esta suposición del espacio de trabajo del motor simbólico, no es suficiente eliminar las variables. Debe borrar los supuestos de las variables utilizando la sintaxis

assume([x1,x2],'clear')

Todas las suposiciones se borran cuando la salida del siguiente comando está vacía

assumptions([x1,x2])
  ans =   Empty sym: 1-by-0   

Temas relacionados