python 数值积分_区域体积的Python数值积分

对于程序,我需要一种算法来快速计算实体的体积.该形状由一个函数指定,给定点P(x,y,z),如果P是实体的点,则返回1,如果P不是实体的点,则返回0.

我尝试使用numpy使用以下测试:

import numpy

from scipy.integrate import *

def integrand(x,y,z):

if x**2. + y**2. + z**2. <=1.:

return 1.

else:

return 0.

g=lambda x: -2.

f=lambda x: 2.

q=lambda x,y: -2.

r=lambda x,y: 2.

I=tplquad(integrand,-2.,2.,g,f,q,r)

print I

但它没有给我以下错误:

Warning (from warnings module):

File “C:\Python27\lib\site-packages\scipy\integrate\quadpack.py”, line 321

warnings.warn(msg, IntegrationWarning)

IntegrationWarning: The maximum number of subdivisions (50) has been achieved.

If increasing the limit yields no improvement it is advised to analyze

the integrand in order to determine the difficulties. If the position of a

local difficulty can be determined (singularity, discontinuity) one will

probably gain from splitting up the interval and calling the integrator

on the subranges. Perhaps a special-purpose integrator should be used.

Warning (from warnings module):

File “C:\Python27\lib\site-packages\scipy\integrate\quadpack.py”, line 321

warnings.warn(msg, IntegrationWarning)

IntegrationWarning: The algorithm does not converge. Roundoff error is detected

in the extrapolation table. It is assumed that the requested tolerance

cannot be achieved, and that the returned result (if full_output = 1) is

the best which can be obtained.

Warning (from warnings module):

File “C:\Python27\lib\site-packages\scipy\integrate\quadpack.py”, line 321

warnings.warn(msg, IntegrationWarning)

IntegrationWarning: The occurrence of roundoff error is detected, which prevents

the requested tolerance from being achieved. The error may be

underestimated.

Warning (from warnings module):

File “C:\Python27\lib\site-packages\scipy\integrate\quadpack.py”, line 321

warnings.warn(msg, IntegrationWarning)

IntegrationWarning: The integral is probably divergent, or slowly convergent.

所以,当然,我寻找“专用集成商”,但找不到任何可以做我需要的东西.

然后,我尝试使用蒙特卡罗方法编写自己的集成,并使用相同的形状对其进行测试:

import random

# Monte Carlo Method

def get_volume(f,(x0,x1),(y0,y1),(z0,z1),prec=0.001,init_sample=5000):

xr=(x0,x1)

yr=(y0,y1)

zr=(z0,z1)

vdomain=(x1-x0)*(y1-y0)*(z1-z0)

def rand((p0,p1)):

return p0+random.random()*(p1-p0)

vol=0.

points=0.

s=0. # sum part of variance of f

err=0.

percent=0

while err>prec or points

p=(rand(xr),rand(yr),rand(zr))

rpoint=f(p)

vol+=rpoint

points+=1

s+=(rpoint-vol/points)**2

if points>1:

err=vdomain*(((1./(points-1.))*s)**0.5)/(points**0.5)

if err>0:

if int(100.*prec/err)>=percent+1:

percent=int(100.*prec/err)

print percent,'% complete\n error:',err

print int(points),'points used.'

return vdomain*vol/points

f=lambda (x,y,z): ((x**2)+(y**2)<=4.) and ((z**2)<=9.) and ((x**2)+(y**2)>=0.25)

print get_volume(f,(-2.,2.),(-2.,2.),(-2.,2.))

但这工作太慢了.对于这个程序,我将使用这个数值积分大约100次左右,我也将在更大的形状上进行,如果不是一两个小时,它将花费几分钟,现在的速度,更不用说我想要的精度高于2位小数.

我尝试过实施MISER蒙特卡罗方法,但遇到了一些困难,我仍然不确定它会有多快.

所以,我问是否有任何库可以做我要求的,或者是否有更好的算法可以更快地工作几次(相同的精度).欢迎任何建议,因为我已经在这方面工作了很长一段时间.

编辑:

如果我不能在Python中使用它,我可以切换到任何其他可编译且具有相对简单的GUI功能的语言.欢迎任何建议.

你可能感兴趣的:(python,数值积分)