Python Numerical Integration for Volume of Region

2024/10/12 17:18:19

For a program, I need an algorithm to very quickly compute the volume of a solid. This shape is specified by a function that, given a point P(x,y,z), returns 1 if P is a point of the solid and 0 if P is not a point of the solid.

I have tried using numpy using the following test:

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

but it fails giving me the following errors:

Warning (from warnings module):File "C:\Python27\lib\site-packages\scipy\integrate\quadpack.py", line 321warnings.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 321warnings.warn(msg, IntegrationWarning)IntegrationWarning: The algorithm does not converge. Roundoff error is detectedin the extrapolation table. It is assumed that the requested tolerancecannot 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 321warnings.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 321warnings.warn(msg, IntegrationWarning)IntegrationWarning: The integral is probably divergent, or slowly convergent.

So, naturally, I looked for "special-purpose integrators", but could not find any that would do what I needed.

Then, I tried writing my own integration using the Monte Carlo method and tested it with the same shape:

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 ferr=0.percent=0while err>prec or points<init_sample:p=(rand(xr),rand(yr),rand(zr))rpoint=f(p)vol+=rpointpoints+=1s+=(rpoint-vol/points)**2if 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:',errprint 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.))

but this works too slowly. For this program I will be using this numerical integration about 100 times or so, and I will also be doing it on larger shapes, which will take minutes if not an hour or two at the rate it goes now, not to mention that I want a better precision than 2 decimal places.

I have tried implementing a MISER Monte Carlo method, but was having some difficulties and I'm still unsure how much faster it would be.

So, I am asking if there are any libraries that can do what I am asking, or if there are any better algorithms which work several times faster (for the same accuracy). Any suggestions are welcome, as I've been working on this for quite a while now.

EDIT:

If I cannot get this working in Python, I am open to switching to any other language that is both compilable and has relatively easy GUI functionality. Any suggestions are welcome.

Answer

As the others have already noted, finding the volume of domain that's given by a Boolean function is hard. You could used pygalmesh (a small project of mine) which sits on top of CGAL and gives you back a tetrahedral mesh. This

import numpy
import pygalmesh
import meshplexclass Custom(pygalmesh.DomainBase):def __init__(self):super(Custom, self).__init__()returndef eval(self, x):return (x[0]**2 + x[1]**2 + x[2]**2) - 1.0def get_bounding_sphere_squared_radius(self):return 2.0mesh = pygalmesh.generate_mesh(Custom(), cell_size=1.0e-1)

gives you

enter image description here

From there on out, you can use a variety of packages for extracting the volume. One possibility: meshplex (another one out of my zoo):

import meshplex
mp = meshplex.MeshTetra(mesh.points, mesh.cells["tetra"])
print(numpy.sum(mp.cell_volumes))

gives

4.161777

which is close enough to the true value 4/3 pi = 4.18879020478.... If want more precision, decrease the cell_size in the mesh generation above.

https://en.xdnf.cn/q/69627.html

Related Q&A

invalid literal for int() with base 10: on Python-Django

i am learning django from official django tutorial. and i am getting this error when vote something from form. this caused from - probably - vote function under views.py here is my views.py / vote func…

How to use HTTP method DELETE on Google App Engine?

I can use this verb in the Python Windows SDK. But not in production. Why? What am I doing wrong?The error message includes (only seen via firebug or fiddler)Malformed requestor something like thatMy…

Python heapq : How do I sort the heap using nth element of the list of lists?

So I have lists of lists getting added to the heap; eg:n = [[1, 5, 93],[2, 6, 44],[4, 7, 45],[6, 3, 12]]heapq.heapify(n)print(n)This compares and sorts according to the lists first element.My question …

How strings are stored in python memory model

I am from c background and a beginner in python. I want to know how strings are actually stored in memory in case of python.I did something likes="foo"id(s)=140542718184424id(s[0])= 140542719…

The _imaging C module is not installed (on windows)

Im trying to generate some pdf with django/PIL/Imaging and everything is good until I attempt to put some images into the pdf:Exception Type: ImportError Exception Value: The _imaging C module is n…

HOW TO use fabric use with dtach,screen,is there some example

i have googled a lot,and in fabric faq also said use screen dtach with it ,but didnt find how to implement it? bellow is my wrong code,the sh will not execute as excepted it is a nohup taskdef dispatc…

Developing for the HDMI port on Linux

How would it be possible to exclusively drive the HDMI output from an application, without allowing the OS to automatically configure it for display output?For example, using the standard DVI/VGA as t…

Hive client for Python 3.x

is it possible to connect to hadoop and run hive queries using Python 3.x? I am using Python 3.4.1.I found out that it can be done as written here: https://cwiki.apache.org/confluence/display/Hive/Hiv…

How to add a function call to a list?

I have a Python code that uses the following functions:def func1(arguments a, b, c):def func2(arguments d, e, f):def func3(arguments g, h, i):Each of the above functions configures a CLI command on a p…

How to do fuzzy string search without a heavy database?

I have a mapping of catalog numbers to product names:35 cozy comforter 35 warm blanket 67 pillowand need a search that would find misspelled, mixed names like "warm cmfrter".We have code u…