Revisión de Cálculo para Optimización

Mariano Rivera

%matplotlib inline

from sympy import *
init_printing()

x = Symbol('x')
y = Symbol('y')
z = Symbol('z')

Gradiente, Jacobiano y Hessiano

Derivada parcial

Calcular la derivada parcial de una función que depende de varias variables c.r.a (con respecto a) una variable, corresponde a calcular la derivada de la función respecto a esa variable asuminedo las demás constante. Esto es:
f(x1,x2,,xi,,xn)xi=deflimh0f(x1,x2,,xi+h,,xn)f(x1,x2,,xi,,xn)h. \frac{\partial f(x_1, x_2, \ldots, x_i,\ldots, x_n)}{\partial x_i} \overset{def}{=} \lim_{h \rightarrow 0}\frac{ f(x_1, x_2, \ldots, x_i+h,\ldots, x_n) - f(x_1, x_2, \ldots, x_i,\ldots, x_n) }{h}.

O mas compacto
f(x)xi=deflimh0f(x+hei)f(x)h \boxed{ \frac{\partial f(x)}{\partial x_i} \overset{def}{=} \lim_{h \rightarrow 0}\frac{ f(x+h \,e_i)-f(x)}{h} }
donde
x=[x1x2x3xn] x = \begin{bmatrix} x_1 \\ x_2 \\ x_3 \\ \vdots \\ x_n \\ \end{bmatrix}

f = x**2 + 2*y**2 + 3*z**2 - 6*x**2*z + 4*y*x + 5*y*z**2 - 3*x*y*z
f

6x2z+x23xyz+4xy+2y2+5yz2+3z2- 6 x^{2} z + x^{2} - 3 x y z + 4 x y + 2 y^{2} + 5 y z^{2} + 3 z^{2}

diff(f,x)

12xz+2x3yz+4y- 12 x z + 2 x - 3 y z + 4 y

diff(f,z)

6x23xy+10yz+6z- 6 x^{2} - 3 x y + 10 y z + 6 z

f = x**2 + 2*y**2 + 3*z**2
f

x2+2y2+3z2x^{2} + 2 y^{2} + 3 z^{2}

El operador Gradiente \nabla:
f(x)=def[f(x)x1f(x)x2f(x)x3f(x)xn] \nabla f(x) \overset{def}{=} \begin{bmatrix} \frac{\partial f(x) }{ \partial x_1} \\ \frac{\partial f(x) }{ \partial x_2} \\ \frac{\partial f(x) }{ \partial x_3} \\ \vdots \\ \frac{\partial f(x) }{ \partial x_n} \\ \end{bmatrix}

Podemos ver al gradiente, intuitivamente, que al operar sobre una función y la “expande” en un vector columna que contienen sus derivadas parciales.

Matriz Jacobiana o Jacobiano de la función ff:

Jf=def[f(x)x1,f(x)x2,f(x)x3,,f(x)xn] J_f \overset{def}{=} \begin{bmatrix} \frac{\partial f(x) }{ \partial x_1}, & \frac{\partial f(x) }{ \partial x_2}, & \frac{\partial f(x) }{ \partial x_3}, & \ldots, & \frac{\partial f(x) }{ \partial x_n} \\ \end{bmatrix} \\
=[f1(x)x1,f1(x)x2,f1(x)x3,,f1(x)xnf2(x)x1,f2(x)x2,f2(x)x3,,f2(x)xnf3(x)x1,f3(x)x2,f3(x)x3,,f3(x)xn,fm(x)x1,fm(x)x2,fm(x)x3,,fm(x)xn] \;\;\;\;\;\;\;\;\;= \begin{bmatrix} \frac{\partial f_1(x) }{ \partial x_1} &, \frac{\partial f_1(x) }{ \partial x_2}, & \frac{\partial f_1(x) }{ \partial x_3}, &\ldots, &\frac{\partial f_1(x) }{ \partial x_n} \\ \frac{\partial f_2(x) }{ \partial x_1}, &\frac{\partial f_2(x) }{ \partial x_2}, & \frac{\partial f_2(x) }{ \partial x_3},& \ldots, &\frac{\partial f_2(x) }{ \partial x_n} \\ \frac{\partial f_3(x) }{ \partial x_1}, &\frac{\partial f_3(x) }{ \partial x_2}, & \frac{\partial f_3(x) }{ \partial x_3}, &\ldots, & \frac{\partial f_3(x) }{ \partial x_n} \\ \vdots, & \vdots& \vdots & \ddots & \vdots \\ \frac{\partial f_m(x) }{ \partial x_1}, &\frac{\partial f_m(x) }{ \partial x_2}, & \frac{\partial f_m(x) }{ \partial x_3}, &\ldots, & \frac{\partial f_m(x) }{ \partial x_n} \end{bmatrix}

Podemos ver intuitivamente el Jacobiano como un operador que “expande” cada renglón de la función vectorial ff en sus derivadas parciales.

Luego si ff1f \equiv f_1:
f=Jf \nabla f = J_f^\top

sbl = Matrix([x,y,z])
sbl

[xyz]\left[\begin{matrix}x\\y\\z\end{matrix}\right]

f = Matrix([f])
f

[x2+2y2+3z2]\left[\begin{matrix}x^{2} + 2 y^{2} + 3 z^{2}\end{matrix}\right]

G=f.jacobian(sbl).T
G

[2x4y6z]\left[\begin{matrix}2 x\\4 y\\6 z\end{matrix}\right]

Recordando la definición de Gradiente de ff
f(x)=[f(x)x1f(x)x2f(x)x3f(x)xn] \nabla f(x) = \begin{bmatrix} \frac{\partial f(x) }{ \partial x_1} \\ \frac{\partial f(x) }{ \partial x_2} \\ \frac{\partial f(x) }{ \partial x_3} \\ \vdots \\ \frac{\partial f(x) }{ \partial x_n} \\ \end{bmatrix}

Matrix Hessiana o Hessiano de ff:

Note que el Hessiano, se puede ver como aplicar el operador Jacobiano al Gradiente:
Hf=defJ{f}=J{Jf} \boxed{ H_f \overset{def}{=} J \{ \nabla f\} = J\{ J_f^\top\} }

Sobre la Notación:

J{}J\{ \cdot \} se refiere al operador

JfJ_f se refiere a la Matrix

H = G.jacobian(sbl)
H

[200040006]\left[\begin{matrix}2 & 0 & 0\\0 & 4 & 0\\0 & 0 & 6\end{matrix}\right]

det(H)

4848

Probablemente, nos sintamos mas cómodos calculando el gradiente con un operador especifico de Gradiente que con el de Jacobiano. Para tal caso, definimos lo siguiente

def Grad(f, variables):
    return Matrix([f]).jacobian(Matrix(symbols(variables))).T

La divergencia se define como
f=def1f \nabla \cdot f \overset{def}{=} \mathbf{1}^\top \nabla f

def Div(f, variables):
     return sum(Grad(f,variables))

Hessiano se define como:
2f=deff \nabla^2 f \overset{def}{=} \nabla^\top \nabla f
Como en python no podemos indicarle al operador matrix.jacobian como haga la expansion. Nuestro Grad, siempre calculará derivadas por columnas asi que jugamos un poco con el orden de los operadores para implementrar el Hessiano.

Si ff es dos veces continua y diferenciable, entonces tenemos
2f=(2f)=(f)=f \nabla^2 f = ( \nabla^2 f)^\top = (\nabla^\top \nabla f)^\top = \nabla \nabla f^\top

def Hessian(f, variables):
    g = Grad(f,variables)
    return Grad(g.T, variables)

Probemos nuestras implementaciones

from sympy import *
init_printing()

x1 = Symbol('x1')
x2 = Symbol('x2')

f = (x1 - x2)**2+ x1**3
f

x13+(x1x2)2x_{1}^{3} + \left(x_{1} - x_{2}\right)^{2}

Grad(f,'x1, x2')

[3x12+2x12x22x1+2x2]\left[\begin{matrix}3 x_{1}^{2} + 2 x_{1} - 2 x_{2}\\- 2 x_{1} + 2 x_{2}\end{matrix}\right]

Div(f,'x1 x2')

3x123 x_{1}^{2}

Hessian(f, 'x1 x2')

[6x1+2222]\left[\begin{matrix}6 x_{1} + 2 & -2\\-2 & 2\end{matrix}\right]

Revisando propiedades de las derivadas que involucran Algebra Lineal

xyx \nabla_x y^\top x

from sympy import *
init_printing()
from sympy import Matrix, latex, symbols

A = Matrix(symbols('a_1:4\,1:4')).reshape(3,3)
x = Matrix(symbols('x_1:4')).reshape(3,1)
y = Matrix(symbols('y_1:4')).reshape(3,1)

(y.T*x).jacobian(x).T

[y1y2y3]\left[\begin{matrix}y_{1}\\y_{2}\\y_{3}\end{matrix}\right]

(A*x).jacobian(x).T

[a1,1a2,1a3,1a1,2a2,2a3,2a1,3a2,3a3,3]\left[\begin{matrix}a_{1,1} & a_{2,1} & a_{3,1}\\a_{1,2} & a_{2,2} & a_{3,2}\\a_{1,3} & a_{2,3} & a_{3,3}\end{matrix}\right]

(x.T*A*x).jacobian(x).T

[2a1,1x1+a1,2x2+a1,3x3+a2,1x2+a3,1x3a1,2x1+a2,1x1+2a2,2x2+a2,3x3+a3,2x3a1,3x1+a2,3x2+a3,1x1+a3,2x2+2a3,3x3]\left[\begin{matrix}2 a_{1,1} x_{1} + a_{1,2} x_{2} + a_{1,3} x_{3} + a_{2,1} x_{2} + a_{3,1} x_{3}\\a_{1,2} x_{1} + a_{2,1} x_{1} + 2 a_{2,2} x_{2} + a_{2,3} x_{3} + a_{3,2} x_{3}\\a_{1,3} x_{1} + a_{2,3} x_{2} + a_{3,1} x_{1} + a_{3,2} x_{2} + 2 a_{3,3} x_{3}\end{matrix}\right]

A*x+A.T*x

[2a1,1x1+a1,2x2+a1,3x3+a2,1x2+a3,1x3a1,2x1+a2,1x1+2a2,2x2+a2,3x3+a3,2x3a1,3x1+a2,3x2+a3,1x1+a3,2x2+2a3,3x3]\left[\begin{matrix}2 a_{1,1} x_{1} + a_{1,2} x_{2} + a_{1,3} x_{3} + a_{2,1} x_{2} + a_{3,1} x_{3}\\a_{1,2} x_{1} + a_{2,1} x_{1} + 2 a_{2,2} x_{2} + a_{2,3} x_{3} + a_{3,2} x_{3}\\a_{1,3} x_{1} + a_{2,3} x_{2} + a_{3,1} x_{1} + a_{3,2} x_{2} + 2 a_{3,3} x_{3}\end{matrix}\right]

(x.T*A*x).jacobian(x).T- A*x-A.T*x

[000]\left[\begin{matrix}0\\0\\0\end{matrix}\right]

J= (x.T*A*x).jacobian(x)
J.jacobian(x)

[2a1,1a1,2+a2,1a1,3+a3,1a1,2+a2,12a2,2a2,3+a3,2a1,3+a3,1a2,3+a3,22a3,3]\left[\begin{matrix}2 a_{1,1} & a_{1,2} + a_{2,1} & a_{1,3} + a_{3,1}\\a_{1,2} + a_{2,1} & 2 a_{2,2} & a_{2,3} + a_{3,2}\\a_{1,3} + a_{3,1} & a_{2,3} + a_{3,2} & 2 a_{3,3}\end{matrix}\right]

A+A.T

[2a1,1a1,2+a2,1a1,3+a3,1a1,2+a2,12a2,2a2,3+a3,2a1,3+a3,1a2,3+a3,22a3,3]\left[\begin{matrix}2 a_{1,1} & a_{1,2} + a_{2,1} & a_{1,3} + a_{3,1}\\a_{1,2} + a_{2,1} & 2 a_{2,2} & a_{2,3} + a_{3,2}\\a_{1,3} + a_{3,1} & a_{2,3} + a_{3,2} & 2 a_{3,3}\end{matrix}\right]

Optimización Convexa

Conjunto Convexo

Definiciones

Conjunto Convexo. ΩRn\Omega \subseteq \mathbb{R}^n es un conjunto convexo si
αx+(1α)yΩ,x,yΩyα[0,1] \alpha x + (1-\alpha) y \in \Omega, \;\;\; \forall x, y \in \Omega \;\; y\;\; \forall \alpha \in [0,1]

Función Convexa. f:ΩRf:\Omega \rightarrow \mathbb{R} es una función convexa si
αf(x)+(1α)f(y)f(αx+(1α)y),,x,yΩ \alpha f(x) + (1-\alpha) f(y) \ge f ( \alpha x + (1-\alpha) y ), , \;\;\; \forall x, y \in \Omega
y el dominio Ω\Omega es un conjunto convexo

f(x)=x f(x) = |x|

Función Estrictamente Convexa. f:ΩRf:\Omega \rightarrow \mathbb{R} es una función convexa si
αf(x)+(1α)f(y)>f(αx+(1α)y),,x,yΩ \alpha f(x) + (1-\alpha) f(y) > f ( \alpha x + (1-\alpha) y ), , \;\;\; \forall x, y \in \Omega
y el dominio Ω\Omega es un conjunto convexo

f(x)=x2 f(x) = x^2

Función que es una aproximación diferenciable al valor absoluto. Esta función aproxima al valor absoluto para x>>βx >> \beta
f(x)=x2+β2 f(x) = \sqrt{x^2+\beta^2}

Optimalidad

Sea el problema de optimización
minxf(x) \boxed{ \min_{x} \; f(x) }

con xRnx\in \mathbb{R}^n y fC2f \in \mathcal{C}^2.

Óptimo Global Estricto. xRnx^\ast \in \mathbb{R}^n es el óptimo global estricto si f(x)<f(y),yRnf(x^\ast) < f(y), \;\; \forall y \in \mathbb{R}^n.

Óptimo Global. xRnx^\ast \in \mathbb{R}^n es el óptimo global si f(x)f(y),yRnf(x^\ast) \le f(y), \;\; \forall y \in \mathbb{R}^n.

Óptimo Local Estricto. xRnx^\ast \in \mathbb{R}^n es el óptimo local estricto si f(x)<f(y),yNxf(x^\ast) < f(y), \;\; \forall y \in \mathcal{N}_{x^\ast}; donde Nx\mathcal{N}_{x^\ast} es una vecindad abierta que contine a xx^\ast.

Óptimo Local o mínimo local (m.l). xRnx^\ast \in \mathbb{R}^n es el óptimo local si f(x)f(y),yNxf(x^\ast) \le f(y), \;\; \forall y \in \mathcal{N}_{x^\ast}; donde Nx\mathcal{N}_{x^\ast} es una vecindad abierta que contine a xx^\ast.

Cuando implementamos algoritmos de optimización generalmente nos conformamos con encontrar un óptimo local como solución .

Dirección de Descenso

Dirección de descenso. dd es una dirección de descenso en el punto xx' para el problema propuestonde optimización si partiendo de x’ en la dirección d podemos mejorar el valor de la función objetivo, esto es:
f(x+ϵd)<f(x) f(x'+\epsilon d) < f(x')
para una ϵ\epsilon suficientemente pequeña (sfmp).

Para encontrar que condición cumple dd, usamos expansión en serie de Taylor:
f(x)>f(x+ϵd)=f(x)+ϵf(x)d+ϵ2d2fd+f(x)+ϵf(x)d. f(x') > f(x'+\epsilon d) = f(x') + \epsilon \nabla f(x') ^\top d + \epsilon^2 d^\top \nabla^2 f \, d + \ldots \\ \;\;\;\;\;\; \approx f(x') + \epsilon \nabla f(x') ^\top d.
Dado que ϵ\epsilon es pequeño: ϵ<ϵn| \epsilon |< | \epsilon^n | para n>1n>1.
Luego restamos a ambos lados f(x)f(x') y tenemos que:

La dirección de descenso dd debe cumplir con
f(x)d<0 \boxed{ \nabla f(x')^ \top d < 0 }

La línea punteada es tangente a la curva de nivel correspondiente a ff en xx'

El gradiente f(x)\nabla f(x') es normal a la curva de nivel y apunta en la dirección en que la función ff crece.

Gráficamente, dd debe estar en semiespacio opuesto a f\nabla f que es delimitado por la tangente a la curva de nivel de ff en xx'.

Condición de Optimalidad de Primer Orden

Asumimos el problema de optimización sin restricciones de una función suave.

Una solución (m.l.) xx^\ast al problema de optimización es un punto en el cual no existe una dirección de descenso. Esto es:
d:f(x)d<0 \nexists d : \nabla f(x^\ast)^ \top d < 0
Esto solo ocurre si:
f(x)=0 \nabla f(x^\ast) = 0

Condicion de optimalidad de primer orden. Si xx^\ast es un m.l. entonces f(x)=0\nabla f(x^\ast) = 0.

Si la función ff es convexa, entonces el m.l. es mínimo global y el punto xx^* que satisfaga f(x)=0\nabla f(x^\ast) = 0 es solución global al problema de optimización

En los máximos también el gradiente se hace cero

Pensemos que queremos encontrar una dirección de ascenso bb a partir del punto actual xx'. Entonces bb debe cumplit con:
f(x+ϵb)>f(x) f(x'+\epsilon b) > f(x')
para una ϵ\epsilon suficientemente pequeña (sfmp).

Usamos expanción en serie de Taylor de 1er orden:
f(x)<f(x+ϵd)f(x)+ϵf(x)d. f(x') < f(x'+\epsilon d) \approx f(x') + \epsilon \nabla f(x') ^\top d.
Como antes, restamos a ambos lados f(x)f(x') y tenemos que una dirección de ascenso bb debe cumplir con
f(x)b>0 \boxed{ \nabla f(x')^ \top b > 0 }

Si x’ es un maximo local, entonces si existe una dirección de ascenso posible. La única forma de no entrar en contradicción con condición anterior, es que f(x)=0\nabla f(x')=0.

Condiciones de Optimalidad de Segundo Orden

En general (funciones no-convexas), la condición de optimalidad 1er orden es necesaria, pero no es suficiente para encontrar una solución.

Es decir, en un m.l. el gradiente se desvanece; pero también el gradiente se desvanece en otros puntos (máximos) que no son m.l.'s.

Para distinguir estos casos necesitamos la condiciones de segundo orden.

Condiciones de segundo orden sin restricciones

Sea el problema de optimización SIN restricciones

minxf(x) \min_x \;\; f(x)

La solución xx^* satisface la condición de optimalidad primer orden
xf(x)=0 \nabla_x f(x^*) = {\bf 0}

Esto evita que un método de descenso actualice el punto óptimo:
xxαxf(x) x^\ast \leftarrow x^\ast - \alpha \nabla_x f(x^*)

Sin embargo, usiando la approximación de series de Taylor de segundo orden notamos que para ϵ\epsilon suficientemente pequeña (sfmp):
f(x+ϵp)=f(x)+ϵpf(x)+12ϵ2p2f(x)p=f(x)+12ϵ2p2f(x)p f(x^*+ \epsilon p) = f(x^*) + \epsilon p^\top \nabla f(x^*) +\frac{1}{2} \epsilon^2\,p^\top \nabla^2 f(x^*) \, p \\ = f(x^*) +\frac{1}{2} \epsilon^2\,p^\top \nabla^2 f(x^*) \, p
luego, dado que xx^* es óptimo:
p2f(x)p=2ϵ2[f(x+ϵp)f(x)]0,p. p^\top \nabla^2 f(x^*) \, p = \frac{2}{\epsilon^2} \left[ f(x^*+ \epsilon p) - f(x^*) \right] \ge 0, \;\; \forall p.

Condición necesaria de segundo orden

TMA.
Si xx^* es solución del problema
minxf(x) \min_x \;\; f(x)
Entonces, f(x)=0\nabla f(x^*)=0 y el Hessiano 2f(x)\nabla^2 f(x^*) en dicho óptimo es semidefinido positivo.

Proof.
De lo anteriormente visto tenemos p2f(x)p0,pp^\top \nabla^2 f(x^*) \, p \ge 0, \;\; \forall p.

Condición suficiente de segundo orden

TMA. Sea el problema
minxf(x) \min_x \;\; f(x)
con f suave (dos veces continuamente diferenciable)y xx' un punto en el cual

entonces, xx' es un m.l. del problema de optimización.

Proof. Sea el punto xx' tal que f(x)=0\nabla f(x') =0 y p2f(x)p>0\, p^\top \nabla^2 f(x') p >0. Luego elegimos una bola abierta de radio rr al rededor de xx'
D={z:xz<r}, D = \{z \,:\, \|x'-z \|< r \},
tal que 2f(x)\nabla^2 f(x') se mantenga definido positivo. Tomado un vector cualquier vector pp tal que
x+ϵpD x'+ \epsilon p \in D

Luego, para ϵ\epsilon sfmp:
f(x+ϵp)=f(x)+ϵpf(x)+ϵ22p2f(x)p f(x'+ \epsilon\,p) = f(x') + \epsilon\, p^\top \nabla f(x') + \frac{\epsilon^2}{2} p^\top \nabla^2 f(x') p
Entonces, dado que:

tenemos que
f(x+ϵp)>f(x), f(x'+\epsilon p) > f(x'),
por lo que xx' es un m.l.

import numpy as np
import matplotlib.pyplot as plt

N=10
x= (np.arange(0,N)/N)**2
z= np.zeros(int(N/2))
f1 = np.concatenate([ x[::-1],z,x])
f2 = np.concatenate([-x[::-1],z,x])
f3 = np.concatenate([x[::-1],x])

fig =plt.figure(figsize=(15,5))

ax = fig.add_subplot(1,3,1)
ax.plot(f3,'b' )
ax.annotate(r'$\nabla f=0, \;\; \nabla^2f \succ 0$',
            xy=(9.5,0), xytext=(6.4,.2),
            arrowprops=dict(facecolor='red', shrink=1),
            )
ax = fig.add_subplot(1,3,2)
ax.plot(f1,'b' )
ax.annotate(r'$\nabla f=0, \;\; \nabla^2f = 0$', 
            xy=(12,0), xytext=(8,.15),
            arrowprops=dict(facecolor='red', shrink=1),
            )
ax = fig.add_subplot(1,3,3)
ax.plot(f2,'b' )
ax.annotate(r'$\nabla f=0, \;\; \nabla^2f = 0$',
            xy=(12,0), xytext=(8,.3),
            arrowprops=dict(facecolor='red', shrink=1),
            )

De los tres casos mostrados en la figura anterior, los dos promeros (de la izquierda) corresponden a mínimos locales (soluciones) y el tercero a un punto de mesa (no-solución).

La tercera gráfica (a la derecha) ilustra el porqué para evitar esta caso, en la condición suficiente de segundo orden tuvimos que asumir de inicio que el Hessiano era definido positivo en xx'.

Lo que concluimos que: