Matlab中多变量自定义累积分布函数的采样

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)

考虑一个5变量(cdf),我称之为F

我想在Matlab中从这个cdf中随机抽取5x1向量。F不是已经在Matlab中实现的cdf(例如normal、t-student等)。具体而言,它被定义为

我在这个论坛和其他论坛上读到了一些关于如何在Matlab中从自定义概率分布函数中采样的问题/答案。但是,

1) 大多数是单变量cdf,例如。这个想法是应用的。我的问题有点复杂,因为我需要“反转”一个5元函数

2) 另一个选择是按照建议使用,但我不知道如何在我的例子中写出概率密度函数的解析表达式

3) 这是另一个想法,但对于二元情况来说是特定的

您能帮我了解一下如何进行吗?

给出了解决方案的提示。它解释了当你有一个PDF时的双变量情况。在这里,我们将把它扩展到任意数量的维度,适用于有CDF的情况

因此,过程是:

  • 计算r1的边际CDF
  • 使用此边际CDF随机抽取一个样本(说明如何执行此操作)
  • 计算给定r1的r2的边际CDF
  • 使用此边际CDF随机抽取样本
  • 计算给定r1和r2的r3的边际CDF
  • 等等,等等,你看这是怎么回事
  • 请注意,如果您有PDF,计算边际分布需要对剩余变量进行积分。所以r1的边际分布需要对r2..r5进行积分,给定r1的r2的边际分布需要对r3..r5进行积分,以此类推

    当你有一个CDF时,计算边际分布是很简单的,因为它已经集成了PDF:r1的边际分布是F(x,∞,∞,∞,∞). 然而,获得给定一个或多个变量的边际分布需要区分:给定r1的r2边际分布需要沿r1区分,给定r1和r2的r3边际分布需要沿r1和r2区分,等等

    可能通过解析方法获得这些导数(这将是更有效的解决方案)。这里我们使用有限差分导数近似(这使得插入任何CDF更容易)

    让我们看一些MATLAB代码:

    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是正确的