在超平面上均匀采样

时间:2012-09-27 07:28:19

标签: c algorithm sampling random-sample

给定矢量大小N,我想生成<s1,s2, ..., sn>的矢量s1+s2+...+sn = S

已知0<S<1si < S。生成的这些向量也应该是均匀分布的。

C中任何有助于解释的代码都会很棒!

3 个答案:

答案 0 :(得分:1)

代码here似乎可以解决问题,但它相当复杂。

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

P.S。我认为这更像是一个数学问题,实际上,在http://maths.stackexchange.comhttp://stats.stackexchange.com

询问是个好主意

答案 1 :(得分:0)

[为了简单,我会跳过“超 - ”前缀]

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

为了获得均匀分布,体积必须像平面部分一样,但沿平面法线增加边距。

要在此类卷中均匀生成点,我们可以将其包含在多维数据集中并拒绝卷外的所有内容。

  1. 选择保证金,让我们采用保证金= S以简化(一旦保证金为正,它只影响业绩)
  2. 在立方体中生成一个点[-M,S + M] x [-M,S + M] x [-M,S + M]
  3. 如果到飞机的距离大于M,则拒绝该点并转到#2
  4. 在飞机上投射点
  5. 检查投影是否为[0,S] x [0,S] x [0,S],如果不是 - 拒绝并转到#2
  6. 将此点添加到结果集中,然后转到#2,您需要更多积分

答案 2 :(得分:0)

该问题可以映射到在线性多面体上进行采样的问题,常见的方法是蒙特卡洛方法,随机游走法和即动即走方法(有关简短比较,请参见https://www.jmlr.org/papers/volume19/18-158/18-158.pdf)。它与线性编程有关,可以扩展为流形。 在成分数据分析中还存在多位点的分析,例如https://link.springer.com/content/pdf/10.1023/A:1023818214614.pdf,可在平面和可用于采样的多面体之间提供可逆转换。

如果您要处理的尺寸较小,也可以使用剔除采样。这意味着您首先在包含多面体(由您的不等式定义)的平面上采样。此后一种方法易于实现(当然很浪费),下面的GNU Octave(我让问题的作者重新用C语言实现)代码就是一个示例。

第一个要求是获取与超平面正交的向量。对于N个变量的总和,这是n =(1,...,1)。第二个要求是飞机上的一点。对于您的示例,可能是p =(S,...,S)/ N。

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

我们还假设x_i> = 0

有了这些,您就可以在平面上计算正交基准(向量n的零值),然后在该基准上创建随机组合。最后,您映射回原始空间,并将约束应用于生成的样本。

# Example in 3D
dim = 3;
S   = 1;
n   = ones(dim, 1); # perpendicular vector
p   = S * ones(dim, 1) / dim;
 
# null-space of the perpendicular vector (transposed, i.e. row vector)
# this generates a basis in the plane
V = null (n.');

# These steps are just to reduce the amount of samples that are rejected
# we build a tight bounding box
bb = S * eye(dim); # each column is a corner of the constrained region
# project on the null-space
w_bb = V \ (bb - repmat(p, 1, dim));
wmin = min (w_bb(:));
wmax = max (w_bb(:));

# random combinations and map back
nsamples = 1e3;
w        = wmin + (wmax - wmin) * rand(dim - 1, nsamples);
x        = V * w + p;

# mask the points inside the polytope
msk = true(1, nsamples);
for i = 1:dim
  msk &= (x(i,:) >= 0);
endfor

x_in = x(:, msk); # inside the polytope (your samples)
x_out = x(:, !msk); # outside the polytope

# plot the results
scatter3 (x(1,:), x(2,:), x(3,:), 8, double(msk), 'filled');
hold on
plot3(bb(1,:), bb(2,:), bb(3,:), 'xr')
axis image

enter image description here