function [trslt,tstat,tvalue,tname]=trand(x,verbose,alpha)
%        TESTING RANDOMNESS USING 5 TESTS FROM THE Cipra's BOOK BELOW
% =============================================================================
% function [trslt,tstat,tvalue,tname]=trand(x,verbose,alpha)
% INPUT:
% x       ... is an n x 1 or 1 x n data vector of observations
% verbose ... scalar controlling verbose output of test results (optional):
%             ~= 0 ... yes (=default=[])
%             == 0 ... no
% alpha   ... is a percentual confidence risk (optional: default=[]=5%)
% OUTPUT:
% trslt ... trslt(i) is the result of i-th test (logical value):
%           =0 => randomness hypothesis rejected with risk alpha%
%           =1 => not rejected
% tstat ... tstat(i) is the value of the testing statistics for the i-th test
%           = NaN if test not applicable (usually n small)
% tvalue... tvalue(1) = number of positive difference in the 1-st test
%           tvalue(2) = number of runs up and down in the 2-nd test
%           tvalue(3) = number of pairs s<t where x(s)<x(t) in the 3-rd test
%           tvalue(4) = Spearman coefficient in the 4-th test
%           tvalue(5) = number of groups of adjacent values lying
%                       above or below the median value in the 5-th test
% tname ... tname(i,:) is the verbose name for the i-th test
%
% REFERENCES: T. Cipra: Analyza casovych rad s aplikacemi v ekonomii,
%                       SNTL, Praha 1986 (in Czech), pp. 94-99.

% (C) 1997, V. Vesely, Masaryk University of Brno (Czech Republic)
%

tname=str2mat('Test based on sign differences: ',...
              'Test based on runs up and down: ',...
              'Test based on Kendall coefficient: ',...
              'Test based on Spearman coefficient: ',...
              'Median test: '...
              );

error(nargchk(1,3,nargin));
if nargin<2, verbose = []; end
if nargin<3, alpha   = []; end
if isempty(verbose), verbose = 1; end
if isempty(alpha)  , alpha = 5; end

if min(size(x))>1, error('x is not a vector'); end

alpha = 0.01*alpha;
if alpha==0.05
   nu = 1.96;
else
   nu = norminv(1-alpha/2);
end
nu = nu*ones(1,5);

n  = length(x);
x = reshape(x,n,1);
dx = x(2:n)-x(1:n-1);
dx = dx(dx~=0);      % select nonzero differences
m  = length(dx);

% 1. Test based on sign differences, Cipra: eq.(10.4):
k  = sum(dx>0);
Ek = m./2;
Sk = sqrt((m+2)./12);
tstat(1) = abs(k-Ek)./Sk;
tvalue(1) = k;

% 2. Test based on runs up and down, Cipra: eq. (10.8):
r  = sum(sign(dx(1:m-1))~=sign(dx(2:m)));
clear dx;
Er = 2*(m-1)./3;
Sr = sqrt((16*(m+1)-29)./90);
tstat(2) = abs(r-Er)./Sr;
tvalue(2) = r;

% 3. Test based on Kendall coefficient, Cipra: eq. (10.13):
X=x*ones(1,n);
v = sum(sum(triu(X<X')));
clear X;
tau  = 4*v/(n*(n-1)) - 1;    % Kendall coefficient
Stau = sqrt( 2*(2*n+5)./(9*n*(n-1)) );
tstat(3) = abs(tau)./Stau;
tvalue(3) = v;

% 4. Test based on Spearman coefficient, Cipra: eq. (10.17):
[ans,I] = sort(x);
rho = 1 - (6./(n*(n.^2-1)))*norm((1:n)-I.').^2; % Spearman coefficient
rs = getcvtab(n,'spearman',100*alpha);
if isnan(rs)
   if n<=5
      tstat(4)=NaN;
      disp('WARNING: Test No. 4 not applicable');
   else
      tstat(4) = abs(rho)*sqrt(n-1);
   end
else
   nu(4) = rs;
   tstat(4) = abs(rho);
end
tvalue(4) = rho;

% Median test, Cipra: eq. (10.19)
med = median(x);
I   = find(x==med);
d   = sum(x<med) - sum(x>med);
x(I(1:abs(d))) = x(I(1:abs(d)))*(1+sign(d)*eps);
I = x<med;
m = sum(I);
u = sum(xor([I(1);I],[I;~I(2*m)]));
tstat(5) = abs(u-(m+1))./sqrt(m*(m-1)./(2*m-1));
tvalue(5) = u;

trslt = tstat < nu;
if verbose
  disp('Tests not rejecting the hypothesis of data being white noise:')
  disp(tname(trslt,:));
end
