function mAP = ckn_patch_retrieval(train_test, verbose, sift)
  % Compute map on Rome using custom descriptors
  % The second parameter switches between the train and test part.
  % if verbose is 1, print all APs for the 1000 queries
  % if sift is true, computes the baseline (train: 91.6, test: 87.9)
    
  if nargin <= 2
    sift = false;
  end
  
  if strcmp(train_test,'train')
    load('patch_retrieval_Rome_train.mat');
    load('patch_retrieval_Rome_train_labels.mat');
  elseif strcmp(train_test,'test')
    load('patch_retrieval_Rome_test.mat');
    load('patch_retrieval_Rome_test_labels.mat');
  else
    sprintf('Error: second argument should be train or test');
    quit
  end
  
  if ~sift
    Xtr = reshape(permute(patches,[4,3,2,1]), 51, 51*3,10000); 

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %%% CHANGE THIS LINE TO YOUR PATCH DESCRIPTOR IMPLEMENTATION  %%
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
    descs = encode(Xtr);
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      
    else
      load(sprintf('patch_retrieval_Rome_sifts_%s.mat',train_test), 'descs');
      descs = descs';
    end
    
    
    % L2 normalization 
    descs = descs ./ repmat(sqrt(sum(descs.^2,1)),size(descs,1),1);
   
    descs_queries = descs(:,1:1000);
    descs = descs(:,1001:end);
    
    
    distances = bsxfun(@plus,dot(descs_queries,descs_queries,1)',dot(descs,descs,1))-2*(descs_queries'*descs);
    tic;
    
    mAP = 0;
    for i = 1:1000
      [sorted_distances, ranks] = sort(distances(i,:));
      l = labels_gt(i) == labels(ranks);

      ngroundtruth = sum(l);
      fprintf('%d\r',i);

      
      
      recall = cumsum(l) / ngroundtruth;
      precision = cumsum(l) ./ (1:length(l));
      recall = [0 recall];
      precision = [1 precision];
      ap =  sum((((precision(1:end-1))+(precision(2:end)))/2).*(recall(2:end)-recall(1:end-1)));

      if verbose
	fprintf('%g\n',ap);
      end
      
      mAP = mAP + ap;
    end
    toc
    mAP = mAP / 1000;
    
    if verbose
      fprintf('mAP : %g\n',mAP)
    end
    

  
  
  
  
  