function [Pts,Partition,b]=cfp_gen_random(d,ColorPartition,options)
%
% A random generator for colorful feasibility problem.
%
% **********
% * Syntax *
% **********
% [Pts,Partition,b]=cfp_gen_random(d)
% [Pts,Partition,b]=cfp_gen_random(d,ColorPartition)
% [Pts,Partition,b]=cfp_gen_random(d,ColorPartition,options)
%
% ***************
% * Description *
% ***************
% [Pts,Partition,b]=cfp_gen_random(d,ColorPartition,options) randomly
% generates a colorful feasibility problem.
%
% ******************
% * Input Argument *
% ******************
% The input argument d is the dimension for Euclidean space.
%     The input ColorPartition a vector of length d+1 indicating the number
% of points each color should have. For example, if ColorPartition=[2 4 4],
% then the generated colorful feasibility problem should have two points
% for the first color, four points for the second, and four points for the
% last color.
%     The input options tells other properties the generated problem should
% have. options.feasible=1 indicates that the generated problem must be
% feasible, options.feasible=0 indicates that the generated problem may or
% may not be feasible.
%
% ********************
% * Output Arguments *
% ********************
% Pts is a matrix storing the coordinates of points. Each column of Pts
% stores the coordinate of one point. The number of rows is d, which is
% the number of dimensions of the Euclidean space. The points in each color
% of Pts must contain b in their convex hulls. All the colorful points are
% unit vectors. Scaling the colorful points does not affect whether a
% convex hull generated by them contain the origin, and b is the origin.
% Hence, all the colorful points can be scaled to unit vectors.
%   b is a column vector representing a point, and it is always generated
% as the origin. This output argument is for future potential update.
%   Partition is a row vector of length (d+1). Each element is an  integer
% no less than (d+1), specifying the number of points in a color. For
% example [3 4 3] tells that the first 3 points in Pts are in the first
% color, the following 4 points are in the second color, and so on.
%

%%%%%%%%%%%%%%%%%%%%%%%%% Internal Comments %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Written by Sui Huang, Advanced Optimization Lab, McMaster University,
% Hamilton, Ontario, Canada.
% 
% ************************
% * Modification History *
% ************************
% April  2007  The first version.
%

%% apply the default input arguments
if ((nargin<3)||isempty(options.feasible))
    options.feasible = 1;
end
if ((nargin<2)||isempty(ColorPartition))
    ColorPartition = rand_int(1, d+1, [1 d+1]);
end

%% assign some control variables
NumColor = length(ColorPartition);
NumPts = sum(ColorPartition);

%% construct alternative data structure
% ColorMap is an alternative data structure to present which point is in
% which color to ease the programming.
ColorMap(NumColor).list = [];
base = 0;
for cnt=1:NumColor
    ColorMap(cnt).list = (base+1) : (base+ColorPartition(cnt));
    base = base + ColorPartition(cnt);
end
% Keep: ColorMap

%% generate random points
Pts = randn(d, NumPts);
for i = 1:NumPts
    Pts(:,i) = Pts(:,i)/norm(Pts(:,i),2);
end

%% handle forced feasibility
if (options.feasible==1)
    iA = rand_int(1, 1, [1 NumPts]);
    L  = zeros(1, NumColor-1);
    j = 0;
    for i = 1:NumColor
        if (~ismember(iA, ColorMap(i).list))
            j = j+1;
            L(j) = ...
                 ColorMap(i).list(rand_int(1, 1, [1 ColorPartition(i)]));
        end
    end
    Pts(:, iA) = - (Pts(:, L) * rand_real(NumColor-1, 1, [0 1]));
    Pts(:, iA) = Pts(:, iA)/norm(Pts(:, iA));
end

%% assign b to zero vector
b = zeros(d,1);

%% assign output for Partion
Partition = ColorPartition;

return