C 超平面上的一致采样

C 超平面上的一致采样,c,algorithm,sampling,random-sample,C,Algorithm,Sampling,Random Sample,给定向量大小N,我想生成一个向量,它s1+s2+…+sn=S 已知0虽然代码相当复杂,但它似乎能做到这一点 我可能会选择一种更简单的基于拒绝的算法,即:从超平面的法向量开始,在n维空间中选择一个正交基。将每个点(S,0,0,0..0),(0,S,0,0..0)转换为该基,并沿每个基向量存储最小值和最大值。在新基中对每个分量进行均匀采样,但第一个分量(法向量)除外,该分量始终为S,然后变换回原始空间并检查约束是否满足。如果不是,请再次取样 另外,我认为这更像是一个数学问题,实际上,在或上提问可能是

给定向量大小N,我想生成一个向量
,它
s1+s2+…+sn=S

已知
0虽然代码相当复杂,但它似乎能做到这一点

我可能会选择一种更简单的基于拒绝的算法,即:从超平面的法向量开始,在
n
维空间中选择一个正交基。将每个点(S,0,0,0..0),(0,S,0,0..0)转换为该基,并沿每个基向量存储最小值和最大值。在新基中对每个分量进行均匀采样,但第一个分量(法向量)除外,该分量始终为S,然后变换回原始空间并检查约束是否满足。如果不是,请再次取样

另外,我认为这更像是一个数学问题,实际上,在或上提问可能是一个好主意。[为了简单起见,我将跳过“hyper-”前缀]

一个可能的想法是:在某个封闭体中生成许多均匀分布的点,并将它们投影到平面的目标部分

为了获得均匀分布,体积的形状必须类似于平面的一部分,但沿平面法线增加了边距

要在这样的体积中均匀地生成点,我们可以将其封装在立方体中,并拒绝体积之外的所有内容

  • 选择margin,为了简单起见,我们取margin=s(一旦margin为正值,它只会影响性能)
  • 在立方体中生成点[-M,S+M]x[-M,S+M]x[-M,S+M]
  • 如果到平面的距离大于M,则拒绝该点并转到#2
  • 在平面上投影点
  • 检查投影是否属于[0,S]x[0,S]x[0,S],如果不是-拒绝并转到#2
  • 将此点添加到结果集中,然后转到#2,因为您需要更多点

  • 这个问题可以映射到线性多面体上的采样问题,对于线性多面体,常用的方法有蒙特卡罗方法、随机游动和点击-运行方法(参见示例中的简短比较)。它与线性规划有关,可以推广到流形。 成分数据分析中还有多面体分析,例如,它提供了平面和多面体之间的可逆转换,可用于采样

    如果您正在处理低维问题,还可以使用拒绝采样。这意味着您首先在包含多面体(由不等式定义)的平面上采样。后一种方法很容易实现(当然也是浪费),下面的GNUOctave(我让问题的作者用C重新实现)代码就是一个例子

    第一个要求是得到与超平面正交的向量。对于N个变量的总和,这是N=(1,…,1)。第二个要求是平面上的点。例如,可以是p=(S,…,S)/N

    现在平面上的任意点满足n^T*(x-p)=0

    我们还假设x_i>=0

    使用这些函数,计算平面上的正交基(向量n的零度),然后在该基上创建随机组合。最后,映射回原始空间,并对生成的样本应用约束

    #3D中的示例
    dim=3;
    S=1;
    n=一(尺寸,1);#垂直向量
    p=S*尺寸(尺寸,1)/尺寸;
    #垂直向量的零空间(转置,即行向量)
    #这将在平面中生成一个基
    V=零(n.);
    #这些步骤只是为了减少被拒绝的样本数量
    #我们构建一个紧密的边界框
    bb=S*眼睛(昏暗)#每列都是受约束区域的一个角
    #在空空间上投影
    w_bb=V\(bb-repmat(p,1,dim));
    wmin=min(w_-bb(:);
    wmax=max(w_bb(:);
    #随机组合和映射回
    nsamples=1e3;
    w=wmin+(wmax-wmin)*兰德(dim-1,nsamples);
    x=V*w+p;
    #遮罩多边形内的点
    msk=真(1,n样本);
    对于i=1:dim
    msk&=(x(i,:)>=0);
    外循环
    x_in=x(:,msk);#多面体内部(您的样本)
    x_out=x(:,!msk);#多面体之外
    #绘制结果
    散射体3(x(1,:),x(2,:),x(3,:),8,双(msk),‘填充’;
    等等
    图3(bb(1,:)、bb(2,:)、bb(3,:)、‘xr’)
    轴图像
    

    一个简单的解决方案是迭代生成范围
    (0,S-sum)
    中的数字,其中
    sum
    是迄今为止生成的所有数字的总和,然后洗牌列表。不过,我认为它不够统一|一个问题:元素s1、s2、…sn是否来自输入向量?如果是这样的话,这个问题等价于子集和问题,我们就无法有效地知道给定向量中是否有一组数字和S求和,更不用说找到一个大小为n的随机样本了。n个数字达到实分布的S的正和的概率是0。对于浮点,它在2^-50的附近。虽然这个想法可能适用于整数,但对于实数来说却失败得很惨。看起来不错,但从第一眼看,它似乎不是“拒绝采样”。你能不能再简单描述一下这个方法是如何实现的?那里的“摘要”没有足够的信息来理解如何实现它。我不确定我是否遵循。你能解释一下为什么修改后的拒绝概率不等于0以匹配总和(在每次迭代中)<代码>s1+s2+s3+…+sn
    是正态分布的(对于足够大的n),正态分布数成为某个任意数的概率为0。我不建议匹配总和,而是只对
    n-1
    维度进行采样。这样,在变换之后,任何结果点都将位于超平面上,但我们仍然必须检查它是否在边界内。例如,对于3d,我们将从超平面上的某个正方形区域采样,然后拒绝不属于三角形的样本。它的大o是什么?效率越高越好。