
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Learning local representative and metric
clear all; 
close all
mex Clearn.c;   % compile C code

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp(['get constants']);
scale = .7;  % scale of Gabors, length = 17 pixels
norient = 15;  % number of orientations
Upperbound = 16.; % saturation value
epsilon = .1;  % allowed correlation between selected Gabors
sub = 1;    % subsampling rate for Gabor
Lrange = 2; % allowed shifting in location (times sub pixels)
Orange = 1; % allowed shifting in orientation
Totalsketch = 40;  % allowed number of selected Gabors   
K = 5; % K nearest neighbors to be used for local learning 
SHUTUP = 1.; % SHUTUP is to neglect the positions with low average responses          
binnum = 50; % number of bins 
numIt = 3; % number of iterations for obtaining each of the representatives
fraca = 3.; % the weight of this image is K/fraca

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp(['get images']);
Folder = 'multi';
sx = 100; sy = 100; 
Iname = dir([Folder '\*.jpg']);
nimage = size(Iname, 1);
Isize = zeros(nimage, 2); 
for (i = 1 : nimage)
    I{i} = imresize(imread([Folder '\' Iname(i).name]),[sx sy], 'nearest');
    if size(I{i},3)==3
        I{i} = double(rgb2gray(I{i})); 
    else
        I{i} = double(I{i}); 
    end
end
Sx = zeros(1, nimage) + sx; 
Sy = zeros(1, nimage) + sy; 
disp(['number of image = ' num2str(nimage)]);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp(['get S1 maps']);
tic
[allfilter, allsymbol] = makefilter(scale, norient);  % generate Gabor filters 
h = (size(allfilter{1}, 1)-1)/2;  % half size of Gabor
C = corr(allfilter, epsilon);    % generate the inhibition maps
allfiltered = applyfilterfftsame(I, allfilter);  % filter training images
allfilteredback = mcopy(allfiltered, nimage, norient); 
%disp(['filtering time: ' num2str(toc) ' seconds']);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp(['get variables']);
Mi = zeros(1, Totalsketch);  % orientation of selected Gabor
Mx = zeros(1, Totalsketch);  % position of selected Gabor
My = zeros(1, Totalsketch); 
Mm = zeros(1, Totalsketch);  % lambda
Mm1 = zeros(1, Totalsketch);  % logZ
sym = zeros(sx, sy);  % symbolic plot of selected Gabor
symAll = cell(1, nimage); 
Asym = cell(1, nimage);   % symbolic plot for each image with active Gabor
for (i = 1 : nimage)
    Asym{i} = zeros(sx, sy);  
end
tss = zeros(nimage, 1);  % template matching scores for testing images
dataWeight = zeros(nimage, 1);
dataWeightAll0 = zeros(nimage, nimage); 
tssmean = zeros(nimage, 1); % local average of tss
inde = zeros(nimage, K); % K nearest neighbors 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% start local learning from every training image 
for (this = 1:nimage)
disp(['get example ' num2str(this)]);
for (i = 1:nimage)
    dataWeight(i) = 0; 
end
dataWeight(this) = 1;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%disp(['get local template']);
for (it = 1 : numIt)
%disp(['    estimate the local template in iteration ' num2str(it)]);
tic
if (it==1)
    Upperbound0 = 1e10;
    Lrange0 = 0; Orange0 = 0; 
else
    Upperbound0 = Upperbound; 
    Lrange0 = Lrange; Orange0 = Orange; 
end
Clearn(nimage, norient, allfiltered, allfilteredback, C, h, sx, sy, Mi, Mx, My, Mm, allsymbol(1, :), sym, Asym, Lrange0, Orange0, sub, Totalsketch, Upperbound, tss, SHUTUP, binnum, dataWeight);
if (it==1)
    for (sk = 1 : Totalsketch)
        Mm(sk) = min(Mm(sk), sqrt(Upperbound)); 
    end
end
%disp(['    mex-C learning takes ' num2str(toc) ' seconds']);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%disp(['    select K nearest neighbors in iteration ' num2str(it)]);
[tsssort ind] = sort(tss, 'descend'); 
for (i = 1 : nimage)
    dataWeight(i) = 0; 
end
for (k = 1 : K)
    dataWeight(ind(k)) = 1.; 
end
dataWeight(this) = K/fraca; 

if (it==numIt)
    tssmean(this, 1) = mean(tsssort(1:K)); 
    inde(this, :) = ind(1:K); 
    symAll{this} = sym+0.; 
    outthis; 
    for (k=1:K)
        dataWeightAll0(this, ind(k)) = 1.; 
    end
end
clear tsssort; 
clear ind; 
end
end

outalltemplate; 
outtemplatetrim; 
ABlearn1; 