在一段时间未使用python之后,我正试图赶上使用python进行数值求解的问题。我正在努力解决一个玩具问题,即计算任意形状(参数指定)的体积。到目前为止,我有一个如下的基类:
sage -pip install pandas
...对于一个领域,我实现了以下目标:
class BaseWithRange():
def __init__(self):
self._x_range = None
@property
def x_range_min(self):
return self.x_range[0]
@property
def x_range_max(self):
return self.x_range[1]
@property
def x_range(self):
if self._x_range is None:
raise NotImplementedError("You need to set the x range value")
return self._x_range
@x_range.setter
def x_range(self, range):
self._x_range = range
def _check_in_x_range(self, x):
errString = f"'x' is out of range of ({self.x_range_min}, {self.x_range_max}) at {x}"
if hasattr(x, "__iter__") and not isinstance(x, str):
if (x < self.x_range_min).any() or (x > self.x_range_max).any():
raise ValueError(errString)
else:
if x < self.x_range_min or x > self.x_range_max:
raise ValueError(errString)
def _val(self, *args):
raise NotImplementedError()
def val(self, *args):
raise NotImplementedError()
class BaseWithTwoRanges(BaseWithRange):
def __init__(self):
super().__init__()
self._y_range = None
@property
def y_range_min(self):
return self.y_range[0]
@property
def y_range_max(self):
return self.y_range[1]
@property
def y_range(self):
if self._y_range is None:
raise NotImplementedError("You need to set the y range value")
return self._y_range
@y_range.setter
def y_range(self, range):
self._y_range = range
def _check_in_y_range(self, y):
errString = f"'y' is out of range of ({self.y_range_min}, {self.y_range_max}) at {y}"
if hasattr(y, "__iter__") and not isinstance(y, str):
if (y < self.y_range_min).any() or (y > self.y_range_max).any():
raise ValueError(errString)
else:
if y < self.y_range_min or y > self.y_range_max:
raise ValueError(errString)
class SolidBase(BaseWithTwoRanges):
def __init__(self):
super().__init__()
@property
def volume(self):
volume, error = integrate.tplquad(self._val, self.x_range_min, self.x_range_max, self.y_lower_of_x, self.y_upper_of_x, self.z_lower_of_xy, self.z_upper_of_xy)
print("Error: ", error)
return volume
def _val(self, z, y, x, *args):
try:
self._check_in_x_range(x)
self._check_in_y_range(y)
return self.val(z, y, x, *args)
except:
t, v, tb = sys.exc_info()
errorString = "Failed when called with these variables: \n y = {0}\n x = {1}\n args = {2}".format(y, x, args)
raise t("{0}\n{1}".format(v, errorString))
def val(self, z, y, x, *args):
raise NotImplementedError()
def y_lower_of_x(self, x):
raise NotImplementedError()
def y_upper_of_x(self, x):
raise NotImplementedError()
def z_lower_of_xy(self, x, y):
raise NotImplementedError()
def z_upper_of_xy(self, x, y):
raise NotImplementedError()
问题是半径为2的球体的体积结果给出的四分之一半球的结果为6.28,这是不正确的。换句话说:
class Sphere(SolidBase):
def __init__(self, radius, center = [0,0,0]):
super().__init__()
self.radius = radius
self.center = center
self.x_range = [center[0], center[0] + radius]
self.y_range = [center[1], center[1] + radius]
def val(self, z, y, x):
a = self.center[0]
b = self.center[1]
c = self.center[2]
return c + sqrt(self.radius**2 - (x - a)**2 - (y - b)**2)
def y_lower_of_x(self, x):
return 0
def y_upper_of_x(self, x):
a = self.center[0]
b = self.center[1]
return b + sqrt(self.radius**2 - (x - a)**2)
def z_lower_of_xy(self, x, y):
return 0
def z_upper_of_xy(self, x, y):
a = self.center[0]
b = self.center[1]
c = self.center[2]
return c + sqrt(self.radius**2 - (x - a)**2 - (y - b)**2)
...而不是预期的(4/3 * pi * 2 ** 3)/ 8 = 4.1887902047863905。
有人能看到我在做什么吗?
编辑:添加了更多代码,添加了缺少的单词。