Generate random (biased) points lying on two circumferences

5 views (last 30 days)
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!

Accepted Answer

David Young
David Young on 20 Jan 2012
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 Comment
Alessandro
Alessandro on 20 Jan 2012
Exactly what I was looking for.
I didn't think about randomizing polar coordinates, thanks!

Sign in to comment.

More Answers (0)

Categories

Find more on Descriptive Statistics in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!