Generate random (biased) points lying on two circumferences

Hi, I need to generate an artificial data set as a test set for a machine learning program.
This dataset must consist in two circumferences, with the smaller one completely contained inside the larger one. Thus I need a way to randomly generate points lying in one of these two circumferences, also adding some noise on both X and Y coordinates to make things more realistic.
So I tried to code a very simple algorithm exploiting the circumference equation to get the Y coordinate after fixing the radius and generating a random X. I tried out many slightly different versions and the best I could came out gives me this result (with 1000 points):
It's easy to see that the distribution is far from being uniform, and this is due to the fact that I ignore the imaginary part for those points whose X is greater than the radius, which leads to those strange "bubbles" on the far left and right extremities of the circumferences. Does anyone have an algorithm that gives a better distribution?
I'm pretty sure there's something that can be done with a Gaussian, but I didn't figure it out correctly yet.
By the way this is my code:
function [ dataSet ] = innerCircleDataSet( n )
% Perturbation on the inner circumference
p = 0.125;
% Radius of the inner circumference
radius = 0.5;
half = ceil(n/2);
if (half == n/2)
half = half + 1;
end
dataSet = zeros(n,3);
% Random generation of point Xs.
dataSet(1:n/2,1) = -radius - p/2 + rand(floor(n/2),1) * (2*radius + p);
dataSet(half:n1) = -2*radius - p + rand(n-half+1,1) * (4*radius + 2*p);
% Random perturbation on the Ys.
r = - p/2 + rand(n,1) * p;
% Exploits circumference equation (x^2 + y^2 = r^2) to compute Y.
y(1:n/2,2) = real(sqrt((radius)^2 - dataSet(1:n/2,1).^2)) + r(1: n/2);
y(half:n,2)=real(sqrt((2*radius)^2-dataSet(half:n,1).^2))+2*r(half:n);
y = y(:,2);
% Array of 0s and 1s, multiplied by -2 and added 1 to get all -1 and 1.
sign = -2 * round(rand(n,1)) + 1;
% Randomly chooses between the positive and the negative real solution.
dataSet(:, 2) = sign .* y;
end
Thanks in advance for your help!

 採用された回答

David Young
David Young 2012 年 1 月 20 日

0 投票

How about something based on this:
n = 500;
angles = 2*pi*rand(1,n);
r1 = 0.5 + 0.01 * randn(1,n/2);
r2 = 1 + 0.02 * randn(1, n/2);
[x y] = pol2cart(angles, [r1 r2]);
plot(x,y,'b+');

1 件のコメント

Alessandro
Alessandro 2012 年 1 月 20 日
Exactly what I was looking for.
I didn't think about randomizing polar coordinates, thanks!

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

ヘルプ センター および File ExchangeRandom Number Generation についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by