% RANK_TEST.M            05-31-2011          code by: Komunjer and Ng
% This function performs the rank test for identification derived in
% Proposition 2-S (SINGULAR CASE) of Komunjer and Ng (2011). The ranks are computed for a
% range of tolerance levels.

function table0 = rank_test(Delta_0,n_theta,n_x,n_eps,n_y,print_details,tol0,steps)

Delta_L=Delta_0(:,1:n_theta);
Delta_T=Delta_0(:,n_theta+1:n_theta+n_x^2);
Delta_U=Delta_0(:,n_theta+n_x^2+1:end);
table_n=[n_theta n_x^2 n_eps^2  n_theta+n_x^2 n_theta+n_eps^2 n_theta+n_x^2+n_eps^2  1];
table0=[];
for i=1:steps;
    % range of tolerance levels
    tol=tol0/10^(i-1);
    n_required=n_theta+n_x^2+n_eps^2;
    n_actual=rank(Delta_0,tol);
    pass_order = (n_theta <= (n_y*n_x + n_eps*(n_x+n_y-n_eps) + n_eps*(n_eps+1)/2));
    pass_rank = (n_actual == n_required);
    table0=[table0; tol rank(Delta_L,tol)  rank(Delta_T,tol)  rank(Delta_U,tol)  ...
	         rank([Delta_L Delta_T],tol)  rank([Delta_L Delta_U],tol)  ...
	       rank(Delta_0,tol) pass_rank];
    if print_details==1;
        disp(sprintf('n_theta = %d',n_theta));
        disp(sprintf('n_eps = %d',n_eps));
        disp(sprintf('n_y = %d',n_y));
        disp(sprintf('rank Delta =%d, Required = %d\n',rank(Delta_0,tol), n_required));
        disp(sprintf('rank Delta-Lambda =%d Required = %d\n',rank(Delta_L,tol),n_theta));
        disp(sprintf('rank Delta-T =%d Required = %d\n',rank(Delta_T,tol),n_x^2));
        disp(sprintf('rank Delta-U =%d Required = %d\n',rank(Delta_U,tol),n_eps^2));
    end;
end;
% now use default tolerance
told = max(size(Delta_0)*eps(norm(Delta_0)));
n_required=n_theta+n_x^2+n_eps^2;
n_actual=rank(Delta_0);
pass_order = (n_theta <= (n_y*n_x + n_eps*(n_x+n_y-n_eps) + n_eps*(n_eps+1)/2));
pass_rank = (n_actual == n_required);
  table0=[table0; told rank(Delta_L)  rank(Delta_T)  rank(Delta_U)    ...
               rank([Delta_L Delta_T])   rank([Delta_L Delta_U]) ...
	       rank(Delta_0) pass_rank];
if print_details==1;
    disp(sprintf('rank Delta =%d, Required = %d\n',rank(Delta_0), n_required));
    disp(sprintf('rank Delta-Lambda =%d Required = %d\n',rank(Delta_L),n_theta));
    disp(sprintf('rank Delta-T =%d Required = %d\n',rank(Delta_T),n_x^2));
    disp(sprintf('rank Delta-U =%d Required = %d\n',rank(Delta_U),n_eps^2));
    disp(sprintf(' Order condition %d',pass_order));
    disp(sprintf(' Rank condition %d',pass_rank));
end;

disp(sprintf('\n\n'));
disp('** Summary **');
disp(sprintf('n_theta = %d  n_x= %d  n_eps = %d',n_theta,n_x,n_eps));
disp(sprintf('Order condition: n_theta %d n_delta %d',...
	     n_theta,(n_y*n_x + n_eps*(n_x+n_y-n_eps) + n_eps*(n_eps+1)/2)));
fmt0=['%4e &' repmat('%5d&',1,cols(table0)-2) ' %5d' ' \\\\'];
fmt1=['%s&', repmat('%5d&',1, cols(table_n)-1) ' %5d' ' \\\\'] ;

disp(sprintf(' tol             DL     DT    DU   LT    LU    LTU    pass ' ));
for i=1:rows(table0);
    disp(sprintf(fmt0,table0(i,:)));
end;
disp(sprintf(fmt1,'  Require     ', table_n(1,:)));




