function X = example_petals
% An example of data points arranged along four rotated and translated ellipses.

% Copyright 2012 Levente Hunyadi

X = ...
[ example_data_ellipse(200, 0, 2, 1, 2, pi) ...
, example_data_ellipse(150, -2, 0, 2, 1, pi) ...
, example_data_ellipse(100, 0, -2, 1, 2, pi) ...
, example_data_ellipse(150, 2, 0, 2, 1, pi) ...
];
X(:,X(1,:).^2 + X(2,:).^2 < 1) = [];

% rotate points about origin
phi = 0.2*pi;
X = [cos(phi) sin(phi) ; -sin(phi) cos(phi)] * X;

if 0
    plot(X(1,:), X(2,:), '.');
    return;
end

% contaminate point with noise
sigma = [0.125 0.125];
X = example_data_contaminate(X, sigma);

if 0
    plot(X(1,:), X(2,:), '.');
    return;
end

function X = example_data_ellipse(n, x_c, y_c, a, b, phi)
% Data points arranged in an ellipse.

validateattributes(n, {'numeric'}, {'positive','integer','scalar'});
validateattributes(a, {'numeric'}, {'positive','real','scalar'});
validateattributes(b, {'numeric'}, {'positive','real','scalar'});

t = linspace(0, 2*pi, n);
x = x_c + a.*cos(t).*cos(phi) - b.*sin(t).*sin(phi);
y = y_c + a.*cos(t).*sin(phi) + b.*sin(t).*cos(phi);
X = [x;y];

function X = example_data_contaminate(X0, sigma)
% Contaminates each component of the observations with Gaussian noise.

validateattributes(sigma, {'numeric'}, {'nonnegative','nonempty','vector'});
sigma = sigma(:);
m = numel(sigma);
n = size(X0,2);
validateattributes(X0, {'numeric'}, {'real','2d','size',[m,n]});

X = X0 + bsxfun(@times, sigma, randn(numel(sigma),n));
