陳鍾誠

Version 1.0

向量微積分

梯度

\nabla_{\boldsymbol{x}} f(\boldsymbol{x})\overset{\underset{\mathrm{def}}{}}{=} \left[ \frac{\partial f(\boldsymbol{x})}{\partial x_1}, \frac{\partial f(\boldsymbol{x})}{\partial x_2},\cdots,\frac{\partial f(\boldsymbol{x})}{\partial x_n} \right]^T=\frac{\partial f(\boldsymbol{x})}{\partial \boldsymbol{x}}

grad 是最斜的方向

grad(f,p) 就是函數 f 在 p 點上最斜的方向。

散度

{\displaystyle \operatorname {div} \mathbf {A} =\nabla \cdot \mathbf {A} ={\frac {\partial A_{x}}{\partial x}}+{\frac {\partial A_{y}}{\partial y}}+{\frac {\partial A_{z}}{\partial z}}}

以散度 divA 就是單位體積向量場 A 之通量 (flux)

散度 ⇐⇒ 通量(曲面積分) ⇐⇒ Gauss 散度定理

旋度

{\displaystyle \mathbf {curl\,} \ \mathbf {A} ={\boldsymbol {\nabla }}\times \mathbf {A} =\left({\frac {\partial A_{z}}{\partial y}}-{\frac {\partial A_{y}}{\partial z}}\right)\mathbf {i} +\left({\frac {\partial A_{x}}{\partial z}}-{\frac {\partial A_{z}}{\partial x}}\right)\mathbf {j} +\left({\frac {\partial A_{y}}{\partial x}}-{\frac {\partial A_{x}}{\partial y}}\right)\mathbf {k} }

旋度的行列式表示法

{\displaystyle \mathbf {curl\,} \mathbf {A} ={\begin{vmatrix}\mathbf {i} &\mathbf {j} &\mathbf {k} \\{\frac {\partial }{\partial x}}&{\frac {\partial }{\partial y}}&{\frac {\partial }{\partial z}}\\A_{x}&A_{y}&A_{z}\end{vmatrix}}}

因為 |curl A · n| ≤ |curl A|, 所以旋度 curl A 可以詮釋為單位面積向量場 A 之最大環流。

因為線積分與座標無關, 所以旋度與所選取之座標無關,

旋度 ⇐⇒ 環流(線積分) ⇐⇒ Stokes定理

Laplace 算子

{\displaystyle \Delta f=\nabla ^{2}f=\nabla \cdot \nabla f}

線積分

\int_C F(r) dr = \int_a^b F(r(t)) dr/dt dt

完整程式

import numpy as np

pi = np.pi
step = 0.001

# 函數 f 對變數 p[k] 的偏微分: df / dp[k]
def df(f, p, k):
    p1 = p.copy()
    p1[k] = p[k]+step
    return (f(p1) - f(p)) / step

# 單變數微分
def df1(f, x):
    return df(f, np.array([x]), 0)

# 梯度:函數 f 在點 p 上的梯度
def grad(f, p):
    gp = p.copy()
    for k in range(len(p)):
        gp[k] = df(f, p, k)
    return gp

# 散度:函數 f 在點 p 上的散度
# 限制:f 為 n 維向量函數 f(Rn)->Rn
def div(f, p):
    r = 0
    for i in range(p.size):
        r += df(f, p, i)[i]
    return r

# 旋度:函數 f 在點 p 上的旋度
# 限制:f 為 3 維向量函數 f(R3)->R3
def curl(f, p):
    rx = df(f, p, 1)[2]-df(f, p, 2)[1]
    ry = df(f, p, 2)[0]-df(f, p, 0)[2]
    rz = df(f, p, 0)[1]-df(f, p, 1)[0]
    return np.array([rx, ry, rz])

# 拉普拉斯算子 ∆ = div∇
def laplace(f, p):
    return div(lambda p:grad(f, p), p)

def lintegrate(F, r, a, b, dt=step):
    area = 0.
    t = a
    while (t < b):
        p = r(t)
        dr = df1(r, t)
        # print('t={} p={} F(p)={}'.format(t, p, F(p)))
        area += np.dot(F(p), dr)*dt
        t += dt
    return area

測試程式

梯度

from vfield import *
# 我們想找函數 f 的最低點
def f(p):
    [x,y] = p
    print('x,y=', x, y)
    return x*x + y*y

p = np.array([1.0,3])
print('df(f, p, 0) = ', df(f, p, 0))
print('df(f, p, 1) = ', df(f, p, 1))
print('grad(f)=', grad(f, p))

執行結果

$ python3 grad1.py
x,y= 1.001 3.0
x,y= 1.0 3.0
df(f, p, 0) =  2.0009999999999195
x,y= 1.0 3.001
x,y= 1.0 3.0
df(f, p, 1) =  6.000999999999479
x,y= 1.001 3.0
x,y= 1.0 3.0
x,y= 1.0 3.001
x,y= 1.0 3.0
grad(f)= [2.001 6.001]

散度

from vfield import *

# f = (3xz, 2xy, -yzz)
# div(f) = (3z+2x-2yz)
def f(p):
    x,y,z = p
    return np.array([3*x*z, 2*x*y, -y*z*z])

p = np.array([1.0, 0, 3])
print('div(f,p)=', div(f,p)) # 3z+2x+0 = 3*3+2*1+0 = 11

執行結果

$ python3 div1.py
div(f,p)= 10.999999999998565

f = (3xz, 2xy, -yz^2)

div f = 3z+2x-2yz

在 (x,y,z)=(1,0,3) 時,答案應為 (33+21+0)=11, 非常接近!

旋度

from vfield import *

# f = (yz, 3zx, z)
# curl(f) = (-3x, y, 2x)
def f(p):
    x,y,z = p
    return np.array([y*z, 3*z*x, z])

p = np.array([1.0, 0, 3])
print('f=(yz, 3zx, z) p=', p)
print('curl(f,p)=', curl(f,p)) # [-3,0,6]

執行結果

$ python3 curl1.py
f=(yz, 3zx, z) p= [1. 0. 3.]
curl(f,p)= [-3.  0.  6.]

f = (yz, 3zx, z)

curl f = (-3x, y, 2z)

在 (1,0,3) 的旋度應為 (-3, 0, 6)

拉普拉斯算子

from vfield import *
from numpy import linalg as LA

def f(p):
    return 1.0/LA.norm(p)

p = np.array([1.,2.,3.])
print(laplace(f, p))

執行結果

$ python3 laplace1.py
2.1029733510147253e-05

引力場的拉普拉斯算子為零,程式結果 0.000021 非常接近零。

線積分

from vfield import *
from math import *

def F(p):
    x,y=p
    return np.array([-y, -x*y])

def r(t):
    return np.array([cos(t), sin(t)])

print("lintegrate(0,pi/2)=", lintegrate(F, r, 0., pi/2))

本範例參考 紙本 kreyszig 工程數學精華本(歐亞書局) 8ed (424 頁),答案為 pi/4-1/3 = 0.4521。

$ python3 lintegrate1.py
lintegrate(0,pi/2)= 0.4521851778637378

參考文獻