【发布时间】:2022-01-26 03:32:01
【问题描述】:
这里的 add 和 mul 定义是无意义的,因为它们依赖于返回 self,导致无限循环。如果他们使用 lambdas 创建一个新的发行版,那么它可以正常工作,如下面我自己的回答。
我只是在玩类,并试图构建一个小型统计工具。但是,当我运行此代码时,我陷入了__mul__ 调用中的递归循环,该调用正在n1.pdf 调用中运行,我无法弄清楚原因。我认为这与 Python 懒惰地执行 __mul__ 而不是做我“想要”的事情(让我们用 CS 语言说)创建一个新指针,该指针指向 pdf 的旧函数调用,即由指向 pdf 的新指针所拥有,然后将旧指针(主 .pdf 指针)设置为新函数。
我认为这措辞很糟糕,所以如果您理解我的要求,非常欢迎编辑。
import math
import random
class Distribution:
def __init__(self, pdf, cdf):
self.pdf = pdf
self.cdf = cdf
def pdf(self, x):
return self.pdf(x)
def cdf(self, x):
return self.cdf(x)
def __mul__(self, other):
if isinstance(other, float) or isinstance(other, int):
newpdf = lambda x : self.pdf(x) * other
self.pdf = newpdf
newcdf = lambda x : self.cdf(x) * other
self.cdf = newcdf
return self
else:
return NotImplemented
def __add__(self, other):
self.pdf = lambda x : self.pdf(x) + other.pdf(x)
self.cdf = lambda x : self.cdf(x) + other.cdf(x)
return Distribution(self.pdf, self.cdf)
class Normal(Distribution):
def __init__(self, mean, stdev):
self.mean = mean
self.stdev = stdev
def pdf(self, x):
return (1.0 / math.sqrt(2 * math.pi * self.stdev ** 2)) * math.exp(-0.5 * (x - self.mean) ** 2 / self.stdev ** 2)
def cdf(self, x):
return (1 + math.erf((x - self.mean) / math.sqrt(2) / self.stdev)) / 2
def sample(self):
return self.mean + self.stdev * math.sqrt(2) * math.cos(2 * math.pi * random.random())
if __name__ == "__main__":
n1 = Normal(1,2)
n1half = n1 * 0.5
x = n1.pdf(1)
print(x)
附言我知道乘以0.5后不再是pdf,这不是问题。
【问题讨论】:
-
旁注:函数
__mul__不会在每个流路径中返回值。 -
旁注 2:通过返回
self,函数__mul__的行为不像二进制函数(例如,与函数__add__相比)。 -
据我了解,这些函数都不应该改变
self,而只是返回一个新对象。 -
欢迎回到 Stack Overflow。作为复习,请阅读How to Ask 并注意这不是论坛。请do not tag questions as "solved"; instead, accept an answer.
-
@TomKarzes 的目标是通过指定在给定点评估 PDF 和 CDF 所需的规则,将两个
Distributions相乘创建一个代表产品的Distribution。被建模的概念是probability distribution,它非常有意义 - 只是代码没有正确表达这个想法。
标签: python recursion infinite-recursion