Generate random (biased) points lying on two circumferences
9 views (last 30 days)
Show older comments
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!
0 Comments
Accepted Answer
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+');
More Answers (0)
See Also
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!