clear all;

%% mex-C compilation
mex CgetMAX1.c;
mex CgetMAX1_DoG.c;
mex sparseFeatureExtraction.c;
mex MatchingPursuit.c;
mex grad_U_sparse.c;
mex sparseFRAME_SUM2_logZ.c;
mex CgetMAX1_trace.c;
mex filterTiling.c;
mex mexc_ComputeMAX2MP.cpp
mex mexc_TemplateAffineTransform.cpp
mex mexc_CropInstance_FRAME.cpp



%% constants
domainTriples = cell(3,3);
domainTriples{1,1} = 'dslr';
domainTriples{1,2} = 'amazon';
domainTriples{1,3} = 'webcam';

domainTriples{2,1} = 'amazon';
domainTriples{2,2} = 'webcam';
domainTriples{2,3} = 'dslr';

domainTriples{3,1} = 'webcam';
domainTriples{3,2} = 'dslr';
domainTriples{3,3} = 'amazon';

para=parametersList()

for iRun=1:3

clearvars -except iRun domainTriples para


if (exist('./output','dir'))%experimental results
    delete('./output/*.*'); 
else
    mkdir('output');
end


    % four domain names are 'dslr' 'amazon' 'caltech' 'webcam'
        
%     srcDomain = domainPairs{iRun,1}
%     tgtDomain = domainPairs{iRun,2}
    
    seed = 1;
    disp(['Source domain ' domainTriples{iRun,1} ' and ' domainTriples{iRun,2} ', target domain ' domainTriples{iRun,3}]);
    rng(seed); % set the seed so that experiments are reproducible

    imgPath = '../dataset/';
    sy = 300;
   % [trainImgs, testImgs, trainLabels,testLabels]=splitData(imgPath,srcDomain,tgtDomain,sy);
    [trainImgs,testImgs,trainLabels,testLabels]=mulSourceSplitData(imgPath,domainTriples(iRun,1:2),domainTriples{iRun,3},sy);
    numClass = length(unique(trainLabels));
    
    codeBook = [];
    for iClass = 1:numClass
        idx = find(trainLabels==iClass);
        
        savingFolder=['./Class' num2str(iClass) '/'];
        if exist(savingFolder)
            rmdir(savingFolder,'s'); 
            mkdir(savingFolder);
        else
            mkdir(savingFolder);
        end
            
        codeWords =LearnDictionary(trainImgs(idx), savingFolder, para);
        
        save(sprintf('./output/codeWork%d.mat',iClass),'codeWords');
        
        codeBook = [codeBook;codeWords];

    end

    save(sprintf('./output/AllcodeBook.mat'),'codeBook');
    % extract features for training and testing images
    trainFeatures = BatchExtractFeatures(trainImgs,codeBook, para);
    testFeatures = BatchExtractFeatures(testImgs,codeBook, para);

    % train the model using muli-class svm
    addpath('./liblinear/matlab');
    %{ 
    Details of liblinar options
    -s type : set type of solver (default 1)
      for multi-class classification
             0 -- L2-regularized logistic regression (primal)
             1 -- L2-regularized L2-loss support vector classification (dual)
             2 -- L2-regularized L2-loss support vector classification (primal)
             3 -- L2-regularized L1-loss support vector classification (dual)
             4 -- support vector classification by Crammer and Singer
             5 -- L1-regularized L2-loss support vector classification
             6 -- L1-regularized logistic regression
             7 -- L2-regularized logistic regression (dual)
      for regression
            11 -- L2-regularized L2-loss support vector regression (primal)
            12 -- L2-regularized L2-loss support vector regression (dual)
            13 -- L2-regularized L1-loss support vector regression (dual)
    -c cost : set the parameter C (default 1)
    -p epsilon : set the epsilon in loss function of epsilon-SVR (default 0.1)
    -e epsilon : set tolerance of termination criterion
            -s 0 and 2
                    |f'(w)|_2 <= eps*min(pos,neg)/l*|f'(w0)|_2,
                    where f is the primal function and pos/neg are # of
                    positive/negative data (default 0.01)
            -s 11
                    |f'(w)|_2 <= eps*|f'(w0)|_2 (default 0.001) 
            -s 1, 3, 4 and 7
                    Dual maximal violation <= eps; similar to libsvm (default 0.1)
            -s 5 and 6
                    |f'(w)|_inf <= eps*min(pos,neg)/l*|f'(w0)|_inf,
                    where f is the primal function (default 0.01)
            -s 12 and 13\n"
                    |f'(alpha)|_1 <= eps |f'(alpha0)|,
                    where f is the dual function (default 0.1)
    -B bias : if bias >= 0, instance x becomes [x; bias]; if < 0, no bias term added (default -1)
    -wi weight: weights adjust the parameter C of different classes (see README for details)
    -v n: n-fold cross validation mode
    -q : quiet mode (no outputs)
    %}
    libLinearOptions = ['-s 4 -c 10 -B 0 -q'];
    model = train(trainLabels,sparse(trainFeatures),libLinearOptions);

    % test the model, and get confusion matrix
    [testLabelsHat, acc]= predict(testLabels,sparse(testFeatures),model);
    
    srcDomain=[domainTriples{iRun,1} ' and ' domainTriples{iRun,2}];
    tgtDomain=domainTriples{iRun,3};
    
    save(sprintf('accuracy%d.mat',iRun),'acc','srcDomain','tgtDomain');
    T = zeros(max(testLabels),length(testLabels));
    Y = T;
    for iSample = 1:length(testLabels)
        T(testLabels(iSample),iSample)=1;
        Y(testLabelsHat(iSample),iSample)=1;
    end
    [~,confMat,~,~] =confusion(T,Y);
    datestr(clock)
    
%end
end