function [template,currSample, LogZ]=sparseFRAMElearn(template, nIteration,filters,rHat,sx,sy,halfFilterSize,locationShiftLimit, nTileRow,nTileCol,epsilon,L,lambdaLearningRate,numSample,isSaved,savingFolder)



nValidFeature= sum((sx-2*halfFilterSize-2*locationShiftLimit).*(sy-2*halfFilterSize-2*locationShiftLimit));
SSD=zeros(nIteration,1);
%initialLogZ =log((2*pi))*(nValidFeature/2);
initialLogZ = 0;
logZRatioSeries = zeros(nIteration,1);


% the field of enlargeTemplate stores a big tiled template for multiple chains HMC sampling 
template.enlargedTemplate = enlargingTemplate(nTileRow, nTileCol, sx, sy, template);
prevSample = single(randn(sx*nTileRow,sy*nTileCol));  

rHat_selected = zeros(1,template.numSelected);
for i=1:template.numSelected
   rHat_selected(i)=rHat{template.selectedFilter(i)}(template.selectedRow(i),template.selectedCol(i));
end

gradientF_selected=zeros(1,template.numSelected);
for iter = 1:nIteration
    disp( [ 'iteration: ' num2str(iter)]);
    tic  
  
     [rModel_selected, currSample]=multiChainHMC_sparse(template, filters, prevSample, epsilon, L, numSample, nTileRow, nTileCol);  
    
     % compute z ratio
     logZRatio = computeLogZRatio_sparse(prevSample,currSample,template,filters,gradientF_selected,lambdaLearningRate, nTileRow, nTileCol);
     logZRatioSeries(iter)=logZRatio;
     %
     
     disp(['one iteration learning time: ' num2str(toc) ' seconds']);

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5   
    % compute gradient and do graidnet ascent
       
    gradientF_selected = rHat_selected-rModel_selected;
    
      
    SSD(iter)=mean(abs(gradientF_selected));
            
    template.selectedLambdas = template.selectedLambdas + lambdaLearningRate * gradientF_selected;
    
    prevSample=currSample;
           
    if isSaved
       % save synthesied image
       gLow = min(currSample(:));
       gHigh = max(currSample(:));
       disp([ 'min: ' num2str(gLow) ' max: ' num2str(gHigh)]);
       disp([ 'SSD: ' num2str(SSD(iter))]);
       img = (currSample-gLow)/(gHigh-gLow);
       imwrite(img, [savingFolder num2str(iter,'%04d') '.png']);
    end
    
end

% re-estimate logz
LogZ = initialLogZ + sum(logZRatioSeries);
disp([' Final LogZ: ' num2str(LogZ)]);

if isSaved
  h = figure; 
  plot(1:nIteration,SSD);
  title('Convergence');
  xlabel('Iterations');
  ylabel('SSD');
  saveas(h,[savingFolder 'plot.png'],'png');

  disp([' Final LogZ: ' num2str(LogZ)]);
  bar(1:nIteration,logZRatioSeries);
  title(['Initial Log Z: ' num2str(initialLogZ,'%e') ', final logZ: ' num2str(LogZ,'%e')]);
  saveas(gcf,fullfile(savingFolder,'logZRatios.png'));
  disp([' The plots saved!' ]);
  close all;
end



