2017-11-06 10 views
0

私は対数正規PDFとガウスPDFをコンボリューションしようとしています。 Iそのためには、次のように関数を定義した:scipy convolveはxに依存します

first array domain

赤い線が対数正規PDF、グリーンラインガウスです:

def PDF_log(x,sig,mu): # log normal PDF 
    mu = np.log(mu) 
    return((1/x)*(1/(sig*np.sqrt(2*np.pi))) * np.exp(-(np.log(x)-mu)**2/(2*sig**2))) 

def gauss(x,sig,mu): # a noraml PDF 
    return(1/(np.sqrt(2*np.pi*sig**2)) * np.exp(-(x-mu)**2/(2.*sig**2))) 

def gauss_log(x, sig, mu, sig0, mu0): 
    a = signal.convolve(PDF_log(x,sig,mu),gauss(x,sig0,mu0),mode='same')/np.sum(gauss(x,sig0,mu0)) 


def test(): 
    mu = 0.6 
    sig = 0.2 
    sig0 = 0.05 
    mu0 = mu 
    x = np.linspace(0.5, 0.6, 10000) 
    plt.plot(x, gauss_log(x, sig, mu, sig0, mu0), '--', label='gauss_X_log', zorder=10) 
    plt.plot(x, gauss(x,sig0,mu0), label='gauss') 
    plt.plot(x, PDF_log(x,sig,mu), label='log') 
    plt.legend() 
    plt.show() 

これは私に次のような結果になります。 「畳み込み」は青い破線です。明らかにここで何かが間違っている

for different domain

:私は、xドメインx = np.linspace(0.5, 0.8, 10000)を変更すると は、私は非常に異なる結果が得られます。私の畳み込み積分F(x) = int (g(t)*f(x-t))dtの結果は "x"の範囲に依存すべきではありません。 私は、私にこのナンセンスを与える大規模なドメイン、すなわちx = np.linspace(0.00001, 100, 10000)、作られた:

large array domain

どちらかが私のスクリプトでは、単純なバグがあるか、私は離散畳み込みをmissunderstandを。

+0

あなたの対数正規を比較することができます。これは私が正しいと思われるものん

(上からPDFを持ちます) 'scipy.stats.lognorm'で – percusse

+0

ログ正常なPDFは大丈夫だと思います。少なくとも、 'scipy.stats.lognorm.pdf'を使用すると、私はそれにマッチすることができます。私は単にWikipediaの公式をコピーしました。私は私の問題が、「scipy.signal.convolve」が何をするか(私の理解の中にあると思う)(プロット内の青い破線)。 – Sebastiano1991

+1

@ Sebastiano1991 "期待された結果"を回復するには、信号をドメイン全体(無限大から無限大まで)で畳み込む必要があります。正規分布の場合、積分を「平均 - 標準偏差の数倍」〜「平均+標準偏差の数倍」に合理的な精度で制限できますが、ここではドメインが小さすぎます。 –

答えて

1

私は私のミスがあったところ、私は考え出し:

ではなく、適切なカーネル関数gauss(x0,sig0,mu)を持ちます。私はガウスのために同じxを使用しました。

def gauss_log(x, x0, sig, mu, sig0, mu0): 
    a = signal.convolve(gauss(x0,sig0,mu0),PDF_log(x,sig,mu),mode='same')/np.sum(gauss(x0,sig0,mu0)) 
    return(a) 

def test(lightcurve,noisecurve): 
    mu = 0.1 #can now put arbitrary small values of mu 
    sig = 0.1 
    sig0 = 0.05 
    mu0 = 0 
    x = np.linspace(0.00001, 5, 1000) 
    x0 = np.linspace(-5,5,1000) #note that arrays need to be equal length! 
    g_log = gauss_log(x, x0, sig, mu, sig0, mu0) 
    plt.plot(x, g_log, '--', label='gauss_X_log', zorder=10) 
    plt.plot(x0, gauss(x0,sig0,mu0), label='gauss') 
    plt.plot(x, PDF_log(x,sig,mu), label='log') 
    plt.legend() 
    plt.show() 

    ###testing normalization! 
    print(np.trapz(gauss(x0,sig0,mu0),x0)) 
    print(np.trapz(g_log,x)) 
    print(np.trapz(PDF_log(x,sig,mu),x)) 

1.0

0.999938903253

1.0

enter image description here

+0

サイトメモ: 'scipy.signal.convolve'は2つの配列の離散畳み込みです。アレイポイントの数が多い場合、これは完全にうまく動作します。私の実際のケースでは、私は11の配列エントリしか持たないが、これは問題を引き起こす。これを回避するために、私は 'scipy.integrate.quad'を使って畳み込み積分を数値的に評価することにしました。これは計算時間のコストで結果を大幅に改善します。あるいは、最も制約の厳しいPDFの値を選択することができます。中央値付近。 – Sebastiano1991

関連する問題