0

ここでの 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 ではないことがわかっていますが、これは問題ではありません。

4

3 に答える 3

2
class Distribution:
    ...
    def pdf(self, x):
        return self.pdf(x)

pdf()自分自身を呼び出し、それが自分自身を呼び出し、それが自分自身を呼び出します... 無限に。

と同じcdf()

于 2021-12-27T01:08:46.727 に答える
0

@John と @Tom と @bbbbbb の助けに感謝します...問題は、新しいディストリビューションを作成する代わりに自分自身を返そうとしていました。mulの定義を

def __mul__(self, other):
        if isinstance(other, float) or isinstance(other, int):
            def newpdf(x):
                return self.pdf(x) * other
            def newcdf(x):
                return self.cdf(x) * other
            return Distribution(newpdf, newcdf)
        else:
            return NotImplemented

次に、これはこの問題を解決します

于 2021-12-27T01:15:01.590 に答える