Ich habe zwei Zufallsvariablen X und Y, die auf dem Simplex gleichmäßig verteilt sind: Schätzung der Wahrscheinlichkeitsdichte der Summe einheitlicher Zufallsvariablen in Python
Ich möchte die Dichte ihrer Summe bewerten:
nach der obigen Integral Auswertung mein Endziel ist es, das folgende Integral zu berechnen:
th zu berechnen Als erstes Integral erzeuge ich gleichmäßig verteilte Punkte in Simplex und überprüfe dann, ob sie zu der gewünschten Region im obigen Integral gehören und nehme den Bruchteil von Punkten, um die obige Dichte zu bewerten.
Sobald ich die obige Dichte berechnet habe, befolge ich ein ähnliches Verfahren, um das obige Logarithmusintegral zu berechnen, um seinen Wert zu berechnen. Dies war jedoch extrem ineffizient und dauerte so 3-4 Stunden. Kann mir jemand einen effizienten Weg vorschlagen, dies in Python zu lösen? Ich benutze Numpy-Paket. Hier
ist der Code
import numpy as np
import math
import random
import numpy.random as nprnd
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
#This function checks if the point x lies the simplex and the negative simplex shifted by z
def InreqSumSimplex(x,z):
dim=len(x)
testShiftSimpl= all(z[i]-1 <= x[i] <= z[i] for i in range(0,dim)) and (sum(x) >= sum(z)-1)
return int(testShiftSimpl)
def InreqDiffSimplex(x,z):
dim=len(x)
testShiftSimpl= all(z[i] <= x[i] <= z[i]+1 for i in range(0,dim)) and (sum(x) <= sum(z)+1)
return int(testShiftSimpl)
#This is for the density X+Y
def DensityEvalSum(z,UniformCube):
dim=len(z)
Sum=0
for gen in UniformCube:
Exponential=[-math.log(i) for i in gen] #This is exponentially distributed
x=[i/sum(Exponential) for i in Exponential[0:dim]] #x is now uniformly distributed on simplex
Sum+=InreqSumSimplex(x,z)
Sum=Sum/numsample
FunVal=(math.factorial(dim))*Sum;
if FunVal<0.00001:
return 0.0
else:
return -math.log(FunVal)
#This is for the density X-Y
def DensityEvalDiff(z,UniformCube):
dim=len(z)
Sum=0
for gen in UniformCube:
Exponential=[-math.log(i) for i in gen]
x=[i/sum(Exponential) for i in Exponential[0:dim]]
Sum+=InreqDiffSimplex(x,z)
Sum=Sum/numsample
FunVal=(math.factorial(dim))*Sum;
if FunVal<0.00001:
return 0.0
else:
return -math.log(FunVal)
def EntropyRatio(dim):
UniformCube1=np.random.random((numsample,dim+1));
UniformCube2=np.random.random((numsample,dim+1))
IntegralSum=0; IntegralDiff=0
for gen1,gen2 in zip(UniformCube1,UniformCube2):
Expo1=[-math.log(i) for i in gen1]; Expo2=[-math.log(i) for i in gen2]
Sumz=[ (i/sum(Expo1)) + j/sum(Expo2) for i,j in zip(Expo1[0:dim],Expo2[0:dim])] #Sumz is now disbtributed as X+Y
Diffz=[ (i/sum(Expo1)) - j/sum(Expo2) for i,j in zip(Expo1[0:dim],Expo2[0:dim])] #Diffz is now distributed as X-Y
UniformCube=np.random.random((numsample,dim+1))
IntegralSum+=DensityEvalSum(Sumz,UniformCube) ; IntegralDiff+=DensityEvalDiff(Diffz,UniformCube)
IntegralSum= IntegralSum/numsample; IntegralDiff=IntegralDiff/numsample
return ((IntegralDiff +math.log(math.factorial(dim)))/ ((IntegralSum +math.log(math.factorial(dim)))))
Maxdim=11
dimlist=range(2,Maxdim)
Ratio=len(dimlist)*[0]
numsample=10000
for i in range(len(dimlist)):
Ratio[i]=EntropyRatio(dimlist[i])
Können Sie den aktuellen Code anzeigen? – MaxNoe
Für welche Werte von "n" interessieren Sie sich? –
@MarkDickinson: Ich interessiere mich für höhere Werte von n, wie bis zu 100.200 etc. Aber ich muss alle Werte von n = 2 bis 200 graphisch darstellen. Deshalb möchte ich es effizient machen. – pikachuchameleon