ここでの add および mul の定義は、self を返すことに依存しているため無意味であり、無限ループが発生します。以下の私自身の回答のように、ラムダを使用して新しいディストリビューションを作成すると、正常に機能します。
クラスをいじって、小さな統計ツールを構築しようとしてオーバーライドしています。__mul__
ただし、このコードを実行すると、呼び出しで実行されている呼び出し内の再帰ループに陥り、そのn1.pdf
理由がわかりません。__mul__
私が所有しているpdfの古い関数呼び出しへの新しいポインターを作成するという、私が「望んでいた」こと(CSの言語で言いましょう)を行う代わりに、Pythonが遅延して実行することに関係があると思います新しいポインターを 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)
ps 0.5 を掛けた後は pdf ではないことがわかっていますが、これは問題ではありません。