function [Pts,Partition,b]=cfp_gencore_tube(d,tubeAng,unbalancedFlag)
%
% A random generator of tube type colorful feasibility problem core cases.
%
% **********
% * Syntax *
% **********
% [Pts,Partition,b]=cfp_gencore_tube(d)
% [Pts,Partition,b]=cfp_gencore_tube(d,tubeAng)
% [Pts,Partition,b]=cfp_gencore_tube(d,tubeAng,unbalancedFlag)
%
% ***************
% * Description *
% ***************
% [Pts,Partition,b]=cfp_gencore_tube(d) randomly generates a tube type
% colorful feasibility problem core case, whose colorful points cluster in
% two opposite caps of a hypersphere.
%
% ******************
% * Input Argument *
% ******************
% The input argument d is the dimension for Euclidean space.
%   The optional argument tubeAng is the maximum angle between a point and
% the axis through the centers of the caps. 0<tubeAng<pi/2 must be
% satisfied. The default is tubeAng=pi/6.
%   If unbalancedFlag=true, then the generator produces one point of each
% color on a cap, and the rest on the opposite cap. The default is
% unbalancedFlag=false.
%
% ********************
% * 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. 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. This
% function only assigns (d+1) points to each color, since in practice a
% subset of size (d+1) containing b in the convex hull can always be found
% when there are more than (d+1) points. Partition is an output
% argument for future potential update.
%
% *************
% * Algorithm *
% *************
% For each color, d points are selected randomly on a cap of the unit 
% hypersphere, then the (d+1)th point is generated as a random convex
% combination of the antipodes of the first d points. The method of 
% generating a random point on the cap is:
%   (i)   let c be the center of the cap.
%   (ii)  obtain a point t perpendicular to c. t distributes uniformly on
%         an equator of the unit hypersphere. The method is from reference
%         [1].
%   (iii) obtain a random angle 0<theta<tubeAng.
%   (iv)  c*cos(theta)+t*sin(theta) is a random on the cap.
% There is one note to the generated random points: they trends to cluster
% around the center of the caps, instead of uniformly distribute on the
% cap. The reason refers to [2].
%
% **************
% * References *
% **************
% [1] Muller, M. E. "A Note on a Method for Generating Points Uniformly on
%     N-Dimensional Spheres" Comm. Assoc. Comput. Mach. 2, 19-20, 1959.
% [2] Eric W. Weisstein. "Sphere Point Picking." From MathWorld--A Wolfram
%     Web Resource. http://mathworld.wolfram.com/SpherePointPicking.html
%

%%%%%%%%%%%%%%%%%%%%%%%%% Internal Comments %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Written by Sui Huang, Advanced Optimization Lab, McMaster University,
% Hamilton, Ontario, Canada.
% 
% ************************
% * Modification History *
% ************************
% May    2005: First version.
% August 2005: Added comments.
% May    2006: Added CoreViolate parameter.
% April  2007: Removed CoreViolated parameter.
%              Renamed to cfp_gencore_tube().
%

%% Apply the default input arguments.
if ((nargin<3)||isempty(unbalancedFlag))
    unbalancedFlag = false;
end
if ((nargin<2)||isempty(tubeAng))
    tubeAng = pi/6;
end

%% Allocate memory for Pts.
Pts = zeros(d, (d+1)*(d+1));

%% Generate the points of each color.
for base = 0:(d+1):(d*d+d)
    % Generate a random place to place a special point in the set.
    i = rand_int(1,1,[1 (d+1)]);
    % Generate d points on a cap.
    L = [((base+1):(base+i-1))  ((base+i+1):(base+d+1))];
    Pts(1:(d-1), L) = randn(d-1,d);
    if unbalancedFlag
        c = 1;
    else
        c = (-1)^rand_int(1,1,[0 1]);
    end
    for j = L
        theta = rand_real(1,1,[0 tubeAng]);
        
        Pts(1:(d-1),j) = Pts(1:(d-1),j)*sin(theta)/norm(Pts(1:(d-1),j),2);
        Pts(d,j) = c * cos(theta);
    end
    % Generate the last point of this color as a convex combination of the
    % antipodes of the first d points.
    Pts(:, (base+i)) = - Pts(:, L)* rand_real(d,1,[0 1]);
    Pts(:, (base+i)) = Pts(:, (base+i)) / norm(Pts(:, (base+i)),2);
end

 
%% Generate b as the origin.
b = zeros(d,1);

%% Partition tells that each color has (d+1) points.
Partition = (d+1)*ones(1,(d+1));

return