[英]how to use scipy tplquad properly?
我正在嘗試使用scipy的tplquad做一些簡單的物理三重積分。 例如,我嘗試將單位球的恆定質量密度(func d)積分到單位立方體上。 這行不通。 但是,如果我將單位立方體的恆定質量密度(func f)積分到單位立方體上,則會很快得到結果。
我認為問題在於將常量積分限制提供為常量而不是函數。 我使用lambda修復了該問題,但仍然無法獲得積分。
from scipy import integrate
''' returns the mass density at a point (x,y,z)'''
def d(z, x, y):
return int(x**2 + y**2 + z**2 <= 1) # unit ball with constant density = 1 , here all orthogonal axes are principal
def f(x,y,z):
return 1
integrate.tplquad(d, -1, 1, lambda x: -1, lambda x: 1,lambda x, y: -1, lambda x, y: 1) # doesn't work / too slow
integrate.tplquad(f, -1, 1, lambda x: -1, lambda x: 1,lambda x, y: -1, lambda x, y: 1) # works fine
我希望在給定范圍內d的積分為4/3 * pi。
積分不連續函數是一個困難的數值問題。
解決方法是將集成域定義為單位球:
from scipy import integrate
import numpy as np
''' returns the mass density at a point (x,y,z)'''
def d(z, x, y):
return 1
integrate.tplquad(d, -1, 1,
lambda x: -np.sqrt(1-x**2), lambda x: np.sqrt(1-x**2),
lambda x, y: -np.sqrt(1-x**2-y**2), lambda x, y: np.sqrt(1-x**2-y**2))
# (4.188790204786397, 2.000470900043183e-09)
# 4/3*np.pi = 4.1887902047863905
另一個不理想的解決方案是人為地平滑功能。 例如,使用Logistic函數,請參閱Heaviside_step_function的解析近似值 :
''' returns the mass density at a point (x,y,z)'''
def d(z, x, y):
r2 = x**2 + y**2 + z**2
smoothing_length = 0.1 # same unit as r2
d = 1 - 1/(1 + np.exp(-2*(r2-1)/smoothing_length))
return d
integrate.tplquad(d, -1, 1, lambda x: -1, lambda x: 1,lambda x, y: -1, lambda x, y: 1)
# (4.182852937567993, 3.021537155780628e-08)
必須謹慎選擇值smoothing_length
。
蒙特卡洛積分可能是解決更復雜問題的正確方法。
大多數數值積分例程(例如tplquad
)通過使用多項式逼近積分。 如果函數平滑,則效果很好。 不幸的是,特征函數除了平滑之外還具有其他所有功能,因為它們具有不連續的邊界。 這就是tplquad
失敗的原因。
如果您想近似一個域的體積,一種合理的方法是為其創建三角形(2D)或四面體(3D)網格,然后添加單純形的體積。 網格生成器的一個示例是pygmsh和pygalmesh (屬於我的項目),但還有其他示例。
如果您確實想在球上集成一個功能,則可能應該看一下Quadpy (我的另一個項目)。 它具有針對各個領域的許多集成方案,其中包括球。 這個
import numpy
import quadpy
scheme = quadpy.ball.hammer_stroud_14_3()
val = scheme.integrate(
lambda x: numpy.ones_like(x[0]), # function to integrate
[0.0, 0.0, 0.0], # center
1.0, # radius
)
print(val) # 4.1887902047863905 == 4*pi/3
將使用度數5的方案將函數1
積分到單位球上,並返回精確的結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.