Matlab中任意离散概率密度函数生成随机样本

Matlab中任意离散概率密度函数生成随机样本,matlab,function,probability,sampling,probability-density,Matlab,Function,Probability,Sampling,Probability Density,我得到了一个任意概率密度函数,在Matlab中离散为矩阵,这意味着对于每对x,y,概率存储在矩阵中: A(x,y)=概率 这是一个100x100的矩阵,我希望能够从这个矩阵中生成二维(x,y)的随机样本,并且如果可能的话,能够计算PDF的平均值和其他矩。我想这样做是因为在重新采样之后,我想把样本拟合到一个近似的高斯混合模型 我到处都找了,但没有找到像这样具体的东西。我希望你能帮助我 谢谢。我不相信matlab具有生成任意分布的多元随机变量的内置功能。事实上,一元随机数也是如此。但是,尽管后者可以

我得到了一个任意概率密度函数,在Matlab中离散为矩阵,这意味着对于每对x,y,概率存储在矩阵中: A(x,y)=概率

这是一个100x100的矩阵,我希望能够从这个矩阵中生成二维(x,y)的随机样本,并且如果可能的话,能够计算PDF的平均值和其他矩。我想这样做是因为在重新采样之后,我想把样本拟合到一个近似的高斯混合模型

我到处都找了,但没有找到像这样具体的东西。我希望你能帮助我


谢谢。

我不相信matlab具有生成任意分布的多元随机变量的内置功能。事实上,一元随机数也是如此。但是,尽管后者可以很容易地基于累积分布函数生成,但多元分布不存在CDF,因此生成此类数字要复杂得多(主要问题是两个或更多变量具有相关性)。所以这部分问题远远超出了本网站的范围

由于半个答案比没有答案好,下面介绍如何使用matlab数值计算平均值和更高阶矩:

%generate some dummy input
xv=linspace(-50,50,101);
yv=linspace(-30,30,100);
[x y]=meshgrid(xv,yv);

%define a discretized two-hump Gaussian distribution
A=floor(15*exp(-((x-10).^2+y.^2)/100)+15*exp(-((x+25).^2+y.^2)/100));
A=A/sum(A(:)); %normalized to sum to 1

%plot it if you like
%figure;
%surf(x,y,A)

%actual half-answer starts here    

%get normalized pdf
weight=trapz(xv,trapz(yv,A));
A=A/weight; %A normalized to 1 according to trapz^2

%mean
mean_x=trapz(xv,trapz(yv,A.*x));
mean_y=trapz(xv,trapz(yv,A.*y));
因此,关键是您可以使用两个连续调用
trapz
对矩形网格执行二重积分。这允许您计算与网格形状相同的任何数量的积分,但缺点是必须独立计算矢量分量。如果您只希望计算可以用
x
y
参数化的东西(它们自然与网格大小相同),那么您就可以不用做任何额外的思考

您还可以为集成定义一个函数:

function res=trapz2(xv,yv,A,arg)

if ~isscalar(arg) && any(size(arg)~=size(A))
    error('Size of A and var must be the same!')
end

res=trapz(xv,trapz(yv,A.*arg));

end
这样你就可以计算像

weight=trapz2(xv,yv,A,1);
mean_x=trapz2(xv,yv,A,x);

注意:我在示例中使用101x100网格的原因是对
trapz
的双重调用应该以正确的顺序执行。如果您在通话中交换
xv
yv
,由于与
A
的定义不一致,您会得到错误的答案,但如果
A
是正方形,这一点就不明显了。我建议在开发阶段避免使用对称量。

如果你真的有一个由
a
定义的离散概率密度函数(与仅由
a
描述的连续概率密度函数相反),你可以通过将2D问题转化为1D问题来“作弊”

%define the possible values for the (x,y) pair
row_vals = [1:size(A,1)]'*ones(1,size(A,2));  %all x values
col_vals = ones(size(A,1),1)*[1:size(A,2)];  %all y values

%convert your 2D problem into a 1D problem
A = A(:);
row_vals = row_vals(:);
col_vals = col_vals(:);

%calculate your fake 1D CDF, assumes sum(A(:))==1
CDF = cumsum(A); %remember, first term out of of cumsum is not zero

%because of the operation we're doing below (interp1 followed by ceil)
%we need the CDF to start at zero
CDF = [0; CDF(:)];

%generate random values
N_vals = 1000;  %give me 1000 values
rand_vals = rand(N_vals,1);  %spans zero to one

%look into CDF to see which index the rand val corresponds to
out_val = interp1(CDF,[0:1/(length(CDF)-1):1],rand_vals); %spans zero to one
ind = ceil(out_val*length(A));

%using the inds, you can lookup each pair of values
xy_values = [row_vals(ind) col_vals(ind)];
我希望这有帮助


芯片

我不能给你密码。但是,如果您在文档中找不到什么,您可以自己实现它。您只需要能够从离散分布中采样。这显示了一些方法和一些非常容易实现的方法!如果速度不是那么重要:选择线性搜索。如果速度很重要:选择别名方法。我认为不应该在这里问这个问题。从任意PDF计算平均值和其他矩总是很困难的,但是如果你能得到条件概率:x | y和y | x,那么你可以使用
吉布斯抽样
来得到你想要的。你可以找到一个例子。很好的选择101x100网格而不是100x100网格。在整个代码中获得正确的尺寸和形状可能非常棘手(但非常重要)。使阵列不呈正方形是一个很好的方法来获得它的权利!