> 文章列表 > 函数向量和函数矩阵

函数向量和函数矩阵

函数向量和函数矩阵

函数f(x),x∈Rnf(\\boldsymbol{x}),\\boldsymbol{x}\\in\\text{ℝ}^nf(x),xRn梯度
∇f(x)=(∂f∂x1∂f∂x2⋮∂f∂xn)\\nabla f(\\boldsymbol{x})=\\begin{pmatrix}\\frac{\\partial f}{\\partial x_1}\\\\\\frac{\\partial f}{\\partial x_2}\\\\\\vdots\\\\\\frac{\\partial f}{\\partial x_n}\\end{pmatrix}f(x)=x1fx2fxnf
和Hesse阵
∇2f(x)=(∂2f∂x1∂x1∂2f∂x1∂x2⋯∂2f∂x1∂xn∂2f∂x2∂x1∂2f∂x2∂x2⋯∂2f∂x2∂xn⋮⋮⋱⋮∂2f∂xn∂x1∂2f∂xn∂x2⋯∂2f∂xn∂xn)\\nabla^2f(\\boldsymbol{x})=\\begin{pmatrix}\\frac{\\partial^2f}{\\partial x_1\\partial x_1}&\\frac{\\partial^2f}{\\partial x_1\\partial x_2}&\\cdots&\\frac{\\partial^2f}{\\partial x_1\\partial x_n}\\\\\\frac{\\partial^2f}{\\partial x_2\\partial x_1}&\\frac{\\partial^2f}{\\partial x_2\\partial x_2}&\\cdots&\\frac{\\partial^2f}{\\partial x_2\\partial x_n}\\\\\\vdots&\\vdots&\\ddots&\\vdots\\\\\\frac{\\partial^2f}{\\partial x_n\\partial x_1}&\\frac{\\partial^2f}{\\partial x_n\\partial x_2}&\\cdots&\\frac{\\partial^2f}{\\partial x_n\\partial x_n}\\end{pmatrix}2f(x)=x1x12fx2x12fxnx12fx1x22fx2x22fxnx22fx1xn2fx2xn2fxnxn2f
中的元素都是x\\boldsymbol{x}x的函数。以函数为元素的向量称为函数向量。相仿地,元素为函数的矩阵称为函数矩阵。以函数的意义,梯度和Hesse阵仍然是x\\boldsymbol{x}x的函数,不过前者为Rn→Rn\\text{ℝ}^n\\rightarrow\\text{ℝ}^nRnRn的函数,而后者为Rn→Rn×n\\text{ℝ}^n\\rightarrow\\text{ℝ}^{n\\times n}RnRn×n的函数。
例如,Rosenbrock函数f(x1,x2)=100(x2−x12)2+(1−x1)2f(x_1,x_2)=100(x_2-x_1^2)^2+(1-x_1)^2f(x1,x2)=100(x2x12)2+(1x1)2的梯度
∇f(x1,x2)=(−400x1(x2−x12)−2(1−x1)200(x2−x12))\\nabla f(x_1,x_2)=\\begin{pmatrix}-400x_1(x_2-x_1^2)-2(1-x_1)\\\\200(x_2-x_1^2)\\end{pmatrix}f(x1,x2)=(400x1(x2x12)2(1x1)200(x2x12))
x=(00)\\boldsymbol{x}=\\begin{pmatrix}0\\\\0\\end{pmatrix}x=(00)处的值为∇f(0,0)=(−20)\\nabla f(0,0)=\\begin{pmatrix}-2\\\\0\\end{pmatrix}f(0,0)=(20),在x=(11)\\boldsymbol{x}=\\begin{pmatrix}1\\\\1\\end{pmatrix}x=(11)处的值为∇f(1,1)=(00)\\nabla f(1,1)=\\begin{pmatrix}0\\\\0\\end{pmatrix}f(1,1)=(00)。Rosenbrock函数的Hesse阵
∇2f(x1,x2)=(−400(x2−x12)+800x12+2−400x1−400x1200)\\nabla^2f(x_1,x_2)=\\begin{pmatrix}-400(x_2-x_1^2)+800x_1^2+2&-400x_1\\\\-400x_1&200\\end{pmatrix}2f(x1,x2)=(400(x2x12)+800x12+2400x1400x1200)
其在x=(00)\\boldsymbol{x}=\\begin{pmatrix}0\\\\0\\end{pmatrix}x=(00)处的值为∇2f(0,0)=(200200)\\nabla^2f(0,0)=\\begin{pmatrix}2&0\\\\0&200\\end{pmatrix}2f(0,0)=(200200),而在x=(11)\\boldsymbol{x}=\\begin{pmatrix}1\\\\1\\end{pmatrix}x=(11)处的值为∇2f(1,1)=(802−400−400200)\\nabla^2f(1,1)=\\begin{pmatrix}802&-400\\\\-400&200\\end{pmatrix}2f(1,1)=(802400400200)
Python用于科学计算的工具包sicpy的optimization模块提供了计算Rosenbrock函数值、梯度值及Hesse阵值的函数rosen、rosen_der和rosen_hess。
例1 调用rosen_der和rosen_hess验算上述计算结果。
:下列代码完成本例计算。

import numpy as np                                  #导入numpy
from scipy.optimize import rosen_der,rosen_hess     #导入rosen_der,rosen_hess
x=np.array([0,0])                                   #设置向量x
print(rosen_der(x))                                 #计算梯度
print(rosen_hess(x))                                #计算Hesse阵
x=np.array([1,1])                                   #重设向量x
print(rosen_der(x))                                 #重算梯度
print(rosen_hess(x))                                #重算Hesse阵

程序的第1~2行分别导入numpy包和scipy包中optimization模块的rosen_der函数和rosen_hess函数。第3行创建numpy提供的array类数组对象x,并将其初始化为[0,0],第4、5行调用rosen_der和rosen_hess函数,分别计算Rosenbrock函数在[0,0]处的梯度和Hesse阵并输出。第6行将x重置为[1,1],第7、8行将打印算得的梯度和Hesse阵。运行程序,输出

[-2  0]
[[  2   0]
[  0 200]]
[0 0]
[[ 802 -400]
[-400  200]]

其中第1行输出的是∇f(0,0)=(−20)\\nabla f(0,0)=\\begin{pmatrix}-2\\\\0\\end{pmatrix}f(0,0)=(20),第2~3函数输出的是∇2f(0,0)=(200200)\\nabla^2f(0,0)=\\begin{pmatrix}2&0\\\\0&200\\end{pmatrix}2f(0,0)=(200200)。第4行输出∇f(1,1)=(00)\\nabla f(1,1)=\\begin{pmatrix}0\\\\0\\end{pmatrix}f(1,1)=(00),第5~6行输出∇2f(1,1)=(802−400−400200)\\nabla^2f(1,1)=\\begin{pmatrix}802&-400\\\\-400&200\\end{pmatrix}2f(1,1)=(802400400200)
Rosenbrock函数是Python作为基准问题唯一提供梯度和Hesse阵计算函数的对象。一般情况下,我们需要自行为函数f(x),x∈Rnf(\\boldsymbol{x}),\\boldsymbol{x}\\in\\text{ℝ}^nf(x),xRn设置计算梯度和Hesse阵的函数。
Python中有一个lambda运算符,可以用来定义简单函数,其语法格式为
lambda x: expression
其中,x表示函数的自变量,分号后的expression表示计算函数返回值的表达式,一般含有自变量x。
例2lambda运算符,设计Rosenbrock函数的梯度函数和Hesse阵函数。
:下列代码完成本例计算。

import numpy as np                                                      #导入numpy
f1=lambda x:np.array([-400*x[0]*(x[1]-x[0]**2)-2*(1-x[0]),              #设置梯度函数200*(x[1]-x[0]**2)])
f2=lambda x:np.array([[-400*(x[1]-x[0]**2)+800*x[0]**2+2,-400*x[0]],    #设置Hesse阵函数[-400*x[0],200]])
x=np.array([0,0])                                                       #设置向量x
print(f1(x))                                                            #计算梯度
print(f2(x))                                                            #计算Hesse阵
x=np.array([1,1])                                                       #重置向量x
print(f1(x))                                                            #重算梯度
print(f2(x))                                                            #重算Hesse阵

程序的第2~3行用lambda运算符定义Rosenbrock函数的梯度函数
∇f(x1,x2)=(−400x1(x2−x12)−2(1−x1)200(x2−x12))\\nabla f(x_1,x_2)=\\\\\\begin{pmatrix}-400x_1(x_2-x_1^2)-2(1-x_1)\\\\200(x_2-x_1^2)\\end{pmatrix}f(x1,x2)=(400x1(x2x12)2(1x1)200(x2x12))
为f1。注意,Python数组的下标是从0开始编码的。第4~5行定义Hesse阵函数
∇2f(x1,x2)=(−400(x2−x12)+800x12+2−400x1−400x1200)\\nabla^2f(x_1,x_2)=\\begin{pmatrix}-400(x_2-x_1^2)+800x_1^2+2&-400x_1\\\\-400x_1&200\\end{pmatrix}2f(x1,x2)=(400(x2x12)+800x12+2400x1400x1200)
为f2。注意, Python使用二维数组(等长数组的数组)表示矩阵。第6~8行和9~11行分别计算x=(00)\\boldsymbol{x}=\\begin{pmatrix}0\\\\0\\end{pmatrix}x=(00)x=(11)\\boldsymbol{x}=\\begin{pmatrix}1\\\\1\\end{pmatrix}x=(11)处Rosenbrock函数的梯度和Hesse阵并输出。程序运行结果为

[-2  0]
[[  2   0]
[  0 200]]
[0 0]
[[ 802 -400]
[-400  200]]

与例1的输出一致。