Tôi có hai biến ngẫu nhiên X và Y được phân bố đều trên simplex: Ước tính mật độ xác suất của tổng của các biến ngẫu nhiên thống nhất trong python
tôi muốn đánh giá mật độ tổng của chúng:
sau khi đánh giá tích ở trên, mục tiêu cuối cùng của tôi là để tính tích phân sau:
để tính thứ e tích phân đầu tiên, tôi tạo ra các điểm phân bố đồng nhất trong simplex và sau đó kiểm tra nếu chúng thuộc về vùng mong muốn trong tích phân trên và lấy phần điểm để đánh giá mật độ trên.
Khi tôi tính toán mật độ trên, tôi đang làm theo một quy trình tương tự để tính tích phân lôgarit ở trên để tính toán giá trị của nó. Tuy nhiên, điều này đã vô cùng không hiệu quả và mất rất nhiều thời gian 3-4 giờ. Bất cứ ai có thể cho tôi một cách hiệu quả để giải quyết điều này trong Python? Tôi đang sử dụng gói Numpy.
Đây là mã
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])
Bạn có thể hiển thị mã hiện tại không? – MaxNoe
Bạn thích loại giá trị nào của 'n'? –
@MarkDickinson: Tôi thực sự quan tâm đến giá trị cao hơn của n, như tối đa 100.200 vv Nhưng tôi cần phải vẽ đồ thị tất cả các giá trị bắt đầu từ n = 2 cho đến 200. Đó là lý do tại sao tôi muốn làm cho nó hiệu quả. – pikachuchameleon