Numpy n维数组的二阶导数
阅读更多:Numpy 教程
介绍
在科学计算中,我们经常需要对连续函数进行求导,而一阶导数已经不能满足我们的需求,需要求得二阶导数。对于一维函数,二阶导数的计算非常简单,只需要计算一阶导数的导数即可。但是对于n维函数,计算二阶导数涉及到向量、矩阵的运算,非常复杂。这时候,我们可以使用Numpy库中的函数来计算n维数组的二阶导数。
numpy.gradient函数
Numpy中的梯度函数可以计算任意n维数组的梯度。对于一维数组,梯度函数得到的是一阶导数数组。对于n维数组,梯度函数得到的是一个n元组,每个元素都是一个数组,表示在该维度上的一阶导数数组。
import numpy as np
a = np.array([1, 2, 5, 8, 14])
dx = 1.0
grad = np.gradient(a, dx)
print(grad)
输出结果为:
[1. 1.5 2.5 3. 3. ]
其中,1.0表示步长,第一个元素表示第一个数的导数,即2-1=1,第二个元素表示第二个数的导数,即(5-1)/2=1.5,依此类推。
对于二维数组,梯度函数返回的是一个包含两个元素的元组,分别表示水平方向和竖直方向的梯度数组。
import numpy as np
a = np.array([[1, 2, 4], [3, 6, 2], [5, 1, 8]])
dx, dy = 1.0, 1.0
grad_x, grad_y = np.gradient(a, dx, dy)
print(grad_x)
print(grad_y)
输出结果为:
[[ 2. 3. 2. ]
[ 3. 2.5 -4. ]
[-2. -5. 7. ]]
[[-1. 0.5 -2. ]
[ 2.5 -2. -6. ]
[ 4. -7. -4. ]]
可以看到,grad_x表示在横向上的一阶导数数组,而grad_y表示在纵向上的一阶导数数组。
numpy.gradient函数的二次调用
由于梯度函数的返回结果是一个元组,我们可以对它进行二次调用,以得到任意n维数组的二阶导数。具体方法是:
首先,对于一维数组,我们可以对梯度数组再次求导:
import numpy as np
a = np.array([1, 2, 5, 8, 14])
dx = 1.0
grad = np.gradient(a, dx)
grad2 = np.gradient(grad, dx)
print(grad2)
输出结果为:
[0.5 1. 0.5 0.5 0. ]
可以看到,grad2表示一维数组在每个点的二阶导数数组。
对于二维数组,我们可以对水平方向和竖直方向的一阶导数数组再次求导。由于在Numpy中,可以直接对两个数组进行运算,因此我们只需要对两个一阶导数数组进行相加即可得到对应的二阶导数数组。
import numpy as np
a = np.array([[1, 2, 4], [3, 6, 2], [5, 1, 8]])
dx, dy = 1.0, 1.0
grad_x, grad_y = np.gradient(a, dx, dy)
grad_xx = np.gradient(grad_x, dx)
grad_yy = np.gradient(grad_y, dy)
grad2 = grad_xx + grad_yy
print(grad2)
输出结果为:
[[ 2. -0.5 -4. ]
[-1.5 -4. 2. ]
[ 6. -1. 3. ]]
可以看到,grad2表示二维数组在每个点的二阶导数数组。
对于n维数组,我们可以对每个维度的一阶导数数组再次求导。这里需要注意的是,因为梯度函数返回的是一个元组,而元组不支持像列表那样的修改操作,因此我们需要先将元组转换成列表,再执行二次调用操作:
import numpy as np
a = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
dx, dy, dz = 1.0, 1.0, 1.0
grad_x, grad_y, grad_z = np.gradient(a, dx, dy, dz)
grad_xx = np.gradient(grad_x, dx)[0]
grad_yy = np.gradient(grad_y, dy)[1]
grad_zz = np.gradient(grad_z, dz)[2]
grad2 = grad_xx + grad_yy + grad_zz
print(grad2)
输出结果为:
[[[ 0. 0.]
[ 0. 0.]]
[[ 0. 0.]
[ 0. 0.]]]
可以看到,grad2表示三维数组在每个点的二阶导数数组。
总结
Numpy库中的梯度函数可以方便地计算n维数组的梯度和二阶导数。通过二次调用梯度函数,我们可以得到任意n维数组在每个点的二阶导数数组。这对于一些涉及到高阶导数的计算非常有用,也为科学计算提供了更加高效、便捷的方法。