Matlab中多变量自定义累积分布函数的采样
考虑一个5变量(cdf),我称之为F 我想在Matlab中从这个cdf中随机抽取5x1向量。F不是已经在Matlab中实现的cdf(例如normal、t-student等)。具体而言,它被定义为 我在这个论坛和其他论坛上读到了一些关于如何在Matlab中从自定义概率分布函数中采样的问题/答案。但是, 1) 大多数是单变量cdf,例如。这个想法是应用的。我的问题有点复杂,因为我需要“反转”一个5元函数 2) 另一个选择是按照建议使用,但我不知道如何在我的例子中写出概率密度函数的解析表达式 3) 这是另一个想法,但对于二元情况来说是特定的 您能帮我了解一下如何进行吗?给出了解决方案的提示。它解释了当你有一个PDF时的双变量情况。在这里,我们将把它扩展到任意数量的维度,适用于有CDF的情况 因此,过程是:Matlab中多变量自定义累积分布函数的采样,matlab,random,probability,sampling,cdf,Matlab,Random,Probability,Sampling,Cdf,考虑一个5变量(cdf),我称之为F 我想在Matlab中从这个cdf中随机抽取5x1向量。F不是已经在Matlab中实现的cdf(例如normal、t-student等)。具体而言,它被定义为 我在这个论坛和其他论坛上读到了一些关于如何在Matlab中从自定义概率分布函数中采样的问题/答案。但是, 1) 大多数是单变量cdf,例如。这个想法是应用的。我的问题有点复杂,因为我需要“反转”一个5元函数 2) 另一个选择是按照建议使用,但我不知道如何在我的例子中写出概率密度函数的解析表达式 3)
sigma_a = 0.5;
sigma_b = 0.3;
F = @(r1,r2,r3,r4,r5)exp(-exp(-r1) - (exp(-r2/sigma_a)+exp(-r3/sigma_a)).^sigma_a ...
- (exp(-r4/sigma_b)+exp(-r5/sigma_b)).^sigma_b);
lims = [-5,10]; % This is the area along all dimensions containing 99.99% of the PDF
N = 1000;
values = zeros(N,5);
for n=1:N
values(n,:) = sample_random(F,5,lims);
end
在这里,我为sigma\u a
和sigma\u b
挑选了一些随机值,并用它们定义了一个由5个变量组成的函数F
。r5
。我发现PDF的域在所有维度上都是相同的,我发现了一个比实际需要的稍大的区域(lims
)接下来,我通过调用sample\u random
,从分布F
中获得1000个随机样本:
function r = sample_random(F,N,lims)
delta = diff(lims)/10000;
x = linspace(lims(1),lims(2),300);
r = inf(1,N);
for ii = 1:N
marginal = get_marginal(F,r,ii,x,delta);
p = rand * marginal(end);
[~,I] = unique(marginal); % interp1 cannot handle duplicated points, let's remove them
r(ii) = interp1(marginal(I),x(I),p);
end
delta
是我们将用于对导数进行有限差分近似的距离。x
表示沿F
任意一维的采样点
我们首先将r
定义为向量[inf,inf,inf,inf,inf,inf]
,我们将使用它作为示例位置,在函数末尾,它将包含从分布中提取的随机值
接下来,我们在5个维度上循环,在每次迭代中,我们对维度ii
的边际分布进行采样,给定先前维度的值(已经选取)。函数get_marginal
如下。我们选取一个介于0和该边际CDF最大值之间的随机值(注意,当我们为每个维度选取r
值时,最大值减小,当ii==1
最大值为1时),我们使用此随机值插值到反向采样的边际CDF中(反向简单地表示交换x和y).我需要从marginal
中删除重复值,因为它成为interp1
中的x
,并且此函数要求x
值是唯一的
最后,函数get_marginal
:
function marginal = get_marginal(F,r,ii,x,delta)
N = length(r);
marginal = zeros(size(x));
for jj=0:2^(ii-1)-1
rr = flip(dec2bin(jj,N)-'0');
sign = mod(sum(rr,2),2);
if sign == 0
sign = 1;
else
sign = -1;
end
args = num2cell(r - delta * rr);
args{ii} = x;
marginal = marginal + sign * F(args{:});
end
这包含了相当多的复杂性。它沿着给定的维度ii
,在点x
,给定固定值r(1:ii-1)
,对CDF进行采样
计算偏导数带来了复杂性。如果我们要计算任意一维的边际分布,而没有选择任何固定的值,我们只需这样做
marginal = F(inf,x,inf,inf,inf);
选择了一个值后,我们会这样做
marginal = F(r1,x,inf,inf,inf) - F(r1-delta,x,inf,inf,inf);
(这是沿第一维偏导数的近似值)
get\u marginal
中的代码对ii-1
固定值执行此操作。这需要对每个固定值以及每个delta
移位组合进行两次F
采样,总共采样次数为n^2
次(对于n
固定值)dec2bin
位用于获取所有这些组合。符号
确定是否从运行总数中添加或减去给定样本。args
是一个单元格数组,函数有5个参数F
,元素1:ii-1
为固定值,元素ii
设置为x
,元素ii+1:N
是inf
最后,我绘制了数据集
值的边际分布(其中包含从CDF中随机抽取的1000个元素),并与CDF的边际分布进行叠加,以验证所有值是否正确:
lims = [-2,5];
x = linspace(lims(1),lims(2),300);
figure
for ii=1:5
subplot(5,1,ii)
histogram(values(:,ii),'normalization','cdf','BinLimits',lims)
hold on
args = num2cell(inf(1,5));
args{ii} = x;
plot(x,F(args{:}))
text(5.2,0.5,['r_',num2str(ii)])
end
我不确定我是否理解你的问题,你说你有一个CDF,它是F(r,sigma\u a,sigma\u b),那么你想从这个函数中随机采样!那么你的问题是如何生成一个随机的5x1向量r并将其提交给F?或者你的问题是如何将这个CDF转换为一个合适的PDF,以用于自定义值r?@user3285148:我发布的代码只对独立的proba是正确的