如何分配点如图A
图B的matlab代码:
N = 30; % number of points
r = 0.5; % r = radius
d = 50; % dimension
C_point = 0; % center point
figure, clf
C = ones(1, d) * C_point;
C_rep = repmat( C,N,1);
X = randn(N,d);
s2 = sum(X.^2,2) ;
radius = r * (rand(N,1).^(1/d));
X = X.*repmat(radius./sqrt(s2),1,d) + C_rep;
%% Plot 2D
t = linspace(0, 2*pi, 100);
x = r*cos(t) + C(1);
y = r*sin(t) + C(2);
plot(x,y,'b')
hold on
plot(C(1),C(2),'b.', 'MarkerSize', 10) % center point
hold on
plot(X(:,1), X(:,2),'r.','markersize',10);
axis equal;rotate3d off; rotate3d on;drawnow;shg;
hold on
ax = axis;
我应该改变成无花果。甲
答案 0 :(得分:1)
OP的代码计算在d维框内均匀分布的点,将它们投影到d维球体上,然后对半径进行采样以将它们移动到d维球内。这是完美的,除了当投射到球体上时盒子内的点不会在该球体上形成均匀分布。相反,如果您发现以高斯分布分布的随机点,则可以保证均匀的角度分布。
在d
维度中具有高斯分布的第一个计算点(我在这里完成对OP代码的最小更改):
N = 1000; % number of points
r = 0.5; % r = radius
d = 3; % dimension
C_point = 0; % center point
C = ones(1,d) * C_point;
C_rep = repmat(C,N,1);
X = randn(N,d);
请注意,我使用的是randn
,而不是rand
。 randn
创建高斯分布。
接下来,我们对矢量进行标准化,使点移动到球体:
nX = sqrt(sum(X.^2,2));
X = X./repmat(nX,1,d);
这些点是均匀分布的,您可以通过scatter3(X(:,1),X(:,2),X(:,3)); axis equal
验证并转动显示(2D渲染并不公平)。这就是我设置d=3
以及N=1000
的原因。我希望能够绘制点并看到很多点。
接下来,我们像您一样计算到原点的随机距离,并针对维度进行更正:
radius = r * (rand(N,1).^(1/d));
X = X.*repmat(radius,1,d) + C_rep;
X
现在统一分布在球中。同样,scatter3(X(:,1),X(:,2),X(:,3)); axis equal
显示了这一点。
但是,如果您设置d=50
,然后仅绘制数据的两个维度,则不会看到填充圆圈的数据。你也不会看到统一的分布。这是因为你将50-D球投射到2维,这根本不起作用。您要么必须信任数学,要么必须切片数据:
figure, hold on
t = linspace(0, 2*pi, 100);
x = r*cos(t) + C(1);
y = r*sin(t) + C(2);
plot(x,y,'b')
plot(C(1),C(2),'b.', 'MarkerSize', 10) % center point
axis equal
I = all(abs(X(:,3:d))<0.1,2);
plot(X(I,1), X(I,2),'r.','markersize',10);
I
那里的索引点在垂直于前两个维度的维度上靠近原点。同样,使用d=50
,您将获得非常少的积分,因此您需要将N
设置得非常大!要查看与上述情况相同的点密度,对于您添加的每个维度,您需要将N
乘以10.因此对于d=5
,您有N=1000*10*10=1e5
,对于d=50
,您需要N=1e50
。当然,这完全不可能计算。