function [kn,flag,Errs] = ChooseKn(pricemat,spec)
%%
%  kn = choosekn(y,spec)
% 
%  Choose the tuning parameter of the ReMeDI estimators
% 
%  Inputs:  logprice --- the logarithmic price
%           spec--- a struct that specifies the criterion of the selection
%               spec.max: the max kn
%               spec.tol: the error tolerance
%               spec.errwin: the error window
%
%  Outputs: kn --- the selected tuning parameter (an integer)
%           flag --- flag = 0: kn = max kn, fail to select kn within the specified
%           range; flag = 1: kn is selected within the specified range. 
%  
%  References:
% 
%  Li, Z. Merrick and Oliver Linton (2018):
%  "A ReMeDI for microstructure noise."
% 
%  Authors : Z. Merrick Li and Oliver Linton
% 
%  Date : 31 July 2018
%%

ReMeDI2a = @(logprice) ReMeDI2(logprice,0,1);
roll2 = splitapply(ReMeDI2a,pricemat,1:size(pricemat,2));

Knsmax = spec.max;
Errs = zeros(Knsmax,1);
for k = 1:Knsmax
   
   ReMeDI2b = @(logprice) ReMeDI2(logprice,0:3,k);
   covs = splitapply(ReMeDI2b,pricemat,1:size(pricemat,2));
    
   est = covs(1,:) - covs(2,:) - covs(3,:) + covs(4,:);
   errtemp = est - roll2;
   Errs(k) = mean(errtemp)^2;
   
end
maxErrs = max(Errs(1:(floor(Knsmax/2)+1)));
for kn = 1:Knsmax - spec.errwin
    minerrtemp = min(Errs(kn:kn+spec.errwin));
    maxerrtemp = max(Errs(kn:kn+spec.errwin));
    if and(minerrtemp/maxErrs< spec.tol, ...
            maxerrtemp/maxErrs< spec.tol)
        break;
    end
end
if kn == Knsmax - spec.errwin
    flag = 0;
    [~,kn] = min(Errs(3:5));
    kn = kn+2;
else
    flag = 1;
end
end
    
    