function [s2Eigvector,s2Mean,s2Dictionary] = learn_s2_dictionary(c1Database,param)
% This function is to train mid-level dictionary with sparse coding.
% Firstly, we use PCA to reduce the dimensions of mid-level features.
% Input:  c1Database   -- the database of mid-level features
%         param        -- see the default settings below
% Output: s2Eigvector  -- the matrix of PCA eigen vectors, each column
%                         represents an eigvector
%         s2Mean       -- the mean of mid-level features, column vector
%         s2Dictionary -- the learned mid-level dictionary, each column
%                         represents a basis
% Written by Jimei Yang
% Oct. 28, 2009
if ~isfield(param,'nSmpForS2Dict')
    param.nSmpForS2Dict = 200000;
end
if ~isfield(param,'pca')
    param.pca = 96;
end

% sample image patches from training database from dictionary learning
fprintf('-- sample features from the c1 layer...\n');
% X = rand_sampling(c1Database, param.nSmpForS2Dict);
num_img = length(c1Database.label); % num of images
num_per_img = round(param.nSmpForS2Dict/num_img);
num_smp = num_per_img*num_img;

load(c1Database.path{1});
dimFea = size(c1Fea.feaData, 1);

X = zeros(dimFea, num_smp);
cnt = 0;

for ii = 1:num_img
    fpath = c1Database.path{ii};
    load(fpath);
    num_fea = size(c1Fea.feaData, 2);
    rndidx = randperm(num_fea);
    X(:, cnt+1:cnt+num_per_img) = c1Fea.feaData(:, rndidx(1:num_per_img));
    cnt = cnt+num_per_img;
end
X(:,sum(X.^2)==0) = [];

if param.pca > 0
    options.PCARatio = param.pca;
    [s2Eigvector,s2Eigvalue,s2Mean] = PCA(X,options);
    Y = s2Eigvector'*(X-repmat(s2Mean,1,size(X,2)));
else
    s2Eigvector = [];
    s2Mean = [];
end

if ~isfield(param,'nBasesS2')
    param.nBasesS2 = 2048;
end
if ~isfield(param,'maxIter')
    param.maxIter = 20;
end

fprintf('-- train sparse coding...');
[s2Dictionary] = reg_sparse_coding(Y, param.nBasesS2, eye(param.nBasesS2), param.beta, param.gamma, param.maxIter);

