function [nest2] = nest2(X)
%Two-level nested analysis of variance design with unequal sample sizes. 
%(referred to the levels of nested factor).
%
%   Syntax: function [nest2] = nest2(X) 
%      
%     Inputs:
%          X - data matrix.
%      (column 1:data; column 2:main factor; column 3:nested factor).
%     Output:
%          No. of levels of main factor.
%          Maximum No. of levels of nested factor.
%          Minimum No. of levels of nested factor.
%          Complete analysis of variance table.
%
%    Example: From the problem on Box 10.4 from Sokal and Rohlf (1981, pp. 294-
%             299) for a two-level nested analysis of variance with unequal
%             sample sizes Model II.
%
%             Total data matrix must be:
%    X=[48 1 1;48 1 1;52 1 1;54 1 1;48 1 2;53 1 2;43 1 2;39 1 2;45 2 1;43 2 1;49 2 1;40 2 1;40 2 1
%    50 2 2;45 2 2;43 2 2;36 2 2;40 3 1;45 3 1;42 3 1;48 3 1;45 3 2;33 3 2;40 3 2;46 3 2;40 3 3;47 3 3
%    40 3 3;47 3 3;47 3 3;38 4 1;48 4 1;46 4 1;37 4 2;31 4 2;45 4 2;41 4 2;44 5 1;51 5 1;49 5 1;51 5 1
%    52 5 1;49 5 2;49 5 2;49 5 2;50 5 2;48 5 3;59 5 3;59 5 3;54 6 1;36 6 1;36 6 1;40 6 1;44 6 2;47 6 2
%    48 6 2;48 6 2;43 6 3;52 6 3;50 6 3;46 6 3;39 6 3;41 7 1;42 7 1;36 7 1;47 7 1;47 7 2;36 7 2;43 7 2
%    38 7 2;41 7 2;53 7 3;40 7 3;44 7 3;40 7 3;45 7 3;52 8 1;53 8 1;48 8 1;40 8 2;48 8 2;50 8 2;40 8 2
%    51 8 2;40 9 1;34 9 1;37 9 1;45 9 1;42 9 2;37 9 2;46 9 2;40 9 2;39 10 1;31 10 1;30 10 1;41 10 1
%    48 10 1;50 10 2;44 10 2;40 10 2;45 10 2;52 11 1;54 11 1;52 11 1;56 11 1;53 11 1;56 11 2;39 11 2
%    52 11 2;49 11 2;48 11 2;50 12 1;45 12 1;43 12 1;44 12 1;49 12 1;52 12 2;43 12 2;38 12 2;33 12 2
%    39 13 1;37 13 1;33 13 1;43 13 1;42 13 1;43 13 2;38 13 2;44 13 2;46 13 3;44 13 3;37 13 3;54 13 3
%    50 14 1;53 14 1;51 14 1;43 14 1;44 14 2;45 14 2;39 14 2;52 14 2;42 14 3;48 14 3;45 14 3;51 14 3
%    48 14 3;47 15 1;49 15 1;45 15 1;43 15 1;42 15 1;45 15 2;42 15 2;52 15 2;51 15 2;32 15 2;51 15 3
%    51 15 3;53 15 3;45 15 3;51 15 3];
%
%             Calling on Matlab the function: 
%                nest2(X)
%
%       Immediately it display:
%  The number of groups of main factor are:15
%  The maximum number of levels of nested factor are: 3
%  The minimum number of levels of nested factor are: 2
%
%       Then it asks:
%             -Model II [pure] (1) or mixed [III] (2):
%             For this example you must to put it after the colon, 1
%
%       Answer is:
%  Nested factor always is random. Here, the highest level of classification also is random.    
%  -----------------------------------------------------------------------------------------------------
%  SV                SS         df     dfs      MS        MSs        F       Fs        P     % Comp.var.
%  -----------------------------------------------------------------------------------------------------
%  Gps.           1780.174      14           127.155                        3.473   0.0050      23.69
%  Subgps(Gps.)    800.237      22     21     36.374     36.617    1.471            0.0966       7.55
%  Error          3042.533     123            24.736                                            68.76
%  Total          5622.944     159
%  -----------------------------------------------------------------------------------------------------
%  Due that there are no exact tests of significance with an unequal sample sizes for testing the upper
%  factor. A test of significance usually referred to as Satterthwaite's approximation is carried out
%  by synthesizing a new denominator mean square (MSs) to obtain a Fs variance ratio whose significance
%  is evaluated against a F critical value with dfs denominator degrees of freedom. The Gaylor and Hopper
%  rules decides whether or not the Satterthwaite approximation can be used. If conditions are not meet
%  then the ordinary F test is used.
%

%  Created by A. Trujillo-Ortiz and R. Hernandez-Walls
%             Facultad de Ciencias Marinas
%             Universidad Autonoma de Baja California
%             Apdo. Postal 453
%             Ensenada, Baja California
%             Mexico.
%             atrujo@uabc.mx
%  February 30, 2003.
%
%  To cite this file, this would be an appropriate format:
%  Trujillo-Ortiz, A. and R. Hernandez-Walls. (2003). nest2: Two-level nested analysis of variance 
%    design with unequal sample sizes. A MATLAB file. [WWW document]. URL http://www.mathworks.com/
%    matlabcentral/fileexchange/loadFile.do?objectId=3065&objectType=file
%
%  References:
% 
%  Sokal, R. R. and Rohlf, F. J. (1981), Biometry. 2nd. ed. 
%              New-York:W. H. Freeman & Co. pp. 293-300.
%  Gaylor, D. W. and Hopper, F. N. (1969), Estimating the degrees of
%              freedom for linear combinations of mean squares by
%              Satterthwaite's formula. Technometrics, 11:691-705.
%

if nargin < 1, 
    error('Requires at least one input arguments.'); 
end 

a=max(X(:,2)); %Number of levels of the main factor.
b=max(X(:,3)); %Maximum number of levels of the nested factor.
     
indice=X(:,2);
for i=1:a
   Xe=find(indice==i);
   eval(['G' num2str(i) '=X(Xe,1);']);
end

C=(sum(X(:,1)))^2/length(X(:,1));  %Correction term.
SSTO=sum(X(:,1).^2)-C;  %Total sum of squares.
dfTO=length(X(:,1))-1;  %Total degrees of freedom.

for i=1:a
   for j=1:b
      Xe=find((X(:,2)==i) & (X(:,3)==j));
      eval(['T' num2str(i) num2str(j) '=X(Xe,1);']);
   end
end

%Procedure related to the subgroups (nested factor).
NSG=[];
for i=1:a
   for j=1:b
   eval(['n' num2str(i) num2str(j) '=length(T' num2str(i) num2str(j) ');'])
   eval(['x= n' num2str(i) num2str(j) ';'])
   NSG=[NSG,x];  
   end
end

%Due it is an unequal sample sizes design, some subgroups arithmetic operations 
%could been not-a-number (like 0.0/0.0). So it is necessary to make the estimations
%ignoring NaNs.
warning off;
SG=[];
for i=1:a
   for j=1:b
   eval(['x =((sum(T' num2str(i) num2str(j) ').^2)/length(T' num2str(i) num2str(j) '));'])
   SG=[SG,x];
   nans = isnan(SG);
   r = find(nans);
   SG(r) = zeros(size(r));
   end
end
warning on;

SSSG=sum(SG)-C;
dfSG=(a*b)-1;

%Procedure related to the groups (main factor).
G=[];
for i=1:a
   eval(['x =((sum(G' num2str(i) ').^2)/length(G' num2str(i) '));'])
   G=[G,x];
end
SSG=sum(G)-C;
dfG=a-1;
MSG=SSG/dfG;

%Procedure for estimation of sample size for unequal sample sizes.
         no1=[]; no2=[];  
         for i=1:a
            for j=1:b
               eval(['x =length(T' num2str(i) num2str(j) ');']);
               no1=[no1,x];
               eval(['x =length(T' num2str(i) num2str(j) ').^2;']);
               no2=[no2,x];
            end
         end
         no3=[];
         for i=1:a
            eval(['x =length(G' num2str(i) ').^2;']);
            no3=[no3,x];
         end
         
         %Procedure related to the within subgroups (error).
         SSE=SSTO-SSSG;
         nneg = length(find((no1-1)<0));
         dfE=sum(no1-1)+nneg;                             
         MSE=SSE/dfE;
   
         no4=sum(reshape(no2,b,a))./sum(reshape(no1,b,a));
         noo=(sum(no4)-(sum(sum(no2))/sum(no1)))/dfG;
         
         %Procedure related to the among subgroups within groups.
         SSSGG=SSTO-SSG-SSE;
         dfSGG=dfTO-dfG-dfE;
         MSSGG=SSSGG/dfSGG;
         
         no=(sum(no1)-sum(no4))/dfSGG;
         

        %Before to perform the significance test for groups, we need check whether the
        %given data satisfy the Gaylor and Hopper (1969) conditions under which the
        %Satterthwaite approximation can be used.
         R=(noo/(noo-no))*(MSSGG/MSE);
         C=finv(.975,dfE,dfSGG)*finv(.5,dfSGG,dfE);
         
         if R > C  %Satterthwaite approximation can be used.
            w2=noo/no;
            w1=1-w2;
            MSSGGoo=(w1*MSE)+(w2*MSSGG);
            dfSGGoo=floor((MSSGGoo^2)/(((w1*MSE)^2/dfE)+((w2*MSSGG)^2/dfSGG)));
            Foo=MSG/MSSGGoo;
            FSGG=MSSGG/MSE;
            PrG = 1 - fcdf(Foo,dfG,dfSGGoo);  %Probability associated to the groups F statistic.
            PrSGGoo = 1 - fcdf(FSGG,dfSGG,dfE);  %Probability associated to the among subgroups within groups F statistic.
            %Variance components.
            s2=MSE;
            s2SGG=(MSSGG - MSE)/no;
            nbo=(sum(no1) - (sum(no3)/sum(no1)))/dfG; 
            s2G=(MSG - MSE - (noo*s2SGG))/nbo;
            s2TO=s2 + s2SGG + s2G;
            if s2 < 0
               s2 = 0;
            else
            end
            if s2G < 0
               s2G = 0;
            else
            end
            if s2SGG < 0
               s2SGG = 0;
            else
            end
            ps2=(s2/s2TO)*100;
            ps2G=(s2G/s2TO)*100;
            ps2SGG=(s2SGG/s2TO)*100;
            fprintf('The number of levels of main factor are:%2i\n', a);
            fprintf('The maximum number of levels of nested factor are:%2i\n', b);
            c=min(full(sum(spones(reshape(no2,b,a))))); %Minimum number of levels of the nested factor.
            fprintf('The minimum number of levels of nested factor are:%2i\n', c);
            disp('     ')
            mod=input ('Model II [pure] (1) or mixed [III] (2):');
            if (mod==1);
               disp('Nested factor always is random. Here, the highest level of classification also is random.')
               disp('     ')
               fprintf('-----------------------------------------------------------------------------------------------------\n');
               disp('SV                SS         df     dfs      MS        MSs        F       Fs        P     % Comp.var.')
               fprintf('-----------------------------------------------------------------------------------------------------\n');
               fprintf('Gps.      %13.3f%8i%18.3f%29.3f%9.4f%11.2f\n\n',SSG,dfG,MSG,(Foo),PrG,ps2G);
               fprintf('Subgps(Gps.)%11.3f%8i%7i%11.3f%11.3f%9.3f%18.4f%11.2f\n\n',SSSGG,dfSGG,(dfSGGoo),MSSGG,(MSSGGoo),FSGG,PrSGGoo,ps2SGG);
               fprintf('Error %17.3f%8i%18.3f%49.2f\n\n',SSE,dfE,MSE,ps2);
               fprintf('Total %17.3f%8i\n',SSTO,dfTO);
               fprintf('-----------------------------------------------------------------------------------------------------\n');
               disp('Due that there are no exact tests of significance with an unequal sample sizes for testing the upper')
               disp('factor. A test of significance usually referred to as Satterthwaite''s approximation is carried out') 
               disp('by synthesizing a new denominator mean square (MSs) to obtain a Fs variance ratio whose significance') 
               disp('is evaluated against a F critical value with dfs denominator degrees of freedom. The Gaylor and Hopper') 
               disp('rules decides whether or not the Satterthwaite approximation can be used. If conditions are not meet')
               disp('then the ordinary F test is used.')
               disp('     ')
            else
               disp('Nested factor always is random. Here, the highest level of classification is fixed.')   
               disp('     ')
               FG=MSG/MSE;
               fprintf('----------------------------------------------------------------------------------------\n');
               disp('SV                SS         df     dfs      MS        MSs        F       Fs        P     ')
               fprintf('----------------------------------------------------------------------------------------\n');
               fprintf('Gps.      %13.3f%8i%18.3f%20.3f%18.4f\n\n',SSG,dfG,MSG,FG,PrG);
               fprintf('Subgps(Gps.)%11.3f%8i%7i%11.3f%11.3f%9.3f%18.4f\n\n',SSSGG,dfSGG,(dfSGGoo),MSSGG,(MSSGGoo),FSGG,PrSGGoo);
               fprintf('Error %17.3f%8i%18.3f\n\n',SSE,dfE,MSE);
               fprintf('Total %17.3f%8i\n',SSTO,dfTO);
               fprintf('----------------------------------------------------------------------------------------\n');
               disp('     ')
            end
               
         else
            fprintf('The number of levels of main factor are:%2i\n', a);
            fprintf('The maximum number of levels of nested factor are:%2i\n', b);
            c=min(full(sum(spones(reshape(no2,b,a))))); %Minimum number of levels of the nested factor.
            fprintf('The minimum number of levels of nested factor are:%2i\n', c);
            disp('     ')
            mod=input ('Model II [pure] (1) or mixed [III] (2):');
         if (mod==1);
            FG=MSG/MSSGG;
            FSGG=MSSGG/MSE;
            PrG = 1 - fcdf(FG,dfG,dfSGG);  %Probability associated to the groups F statistic.
            PrSGG = 1 - fcdf(FSGG,dfSGG,dfE);  %Probability associated to the among subgroups within groups F statistic.
            %Variance components.
            s2=MSE;
            s2G=(MSG-MSSGG)/(NSG(1)*b/a);
            s2SGG=(MSSGG-MSE)/NSG(1);
            if s2 < 0
               s2 = 0;
            else
            end
            if s2G < 0
               s2G = 0;
            else
            end
            if s2SGG < 0
               s2SGG = 0;
            else
            end
           
            s2TO=s2+s2G+s2SGG;
            ps2=(s2/s2TO)*100;
            ps2G=(s2G/s2TO)*100;
            ps2SGG=(s2SGG/s2TO)*100;
            disp('Nested factor always is random. Here, the highest level of classification also is random.')   
            disp('     ')
            fprintf('------------------------------------------------------------------------------\n');
            disp('SV              SS           df      MS          F        P       % Comp.var.')
            fprintf('------------------------------------------------------------------------------\n');
            fprintf('Gps.      %11.3f%10i%10.3f%11.2f%9.4f%13.2f\n\n',SSG,dfG,MSG,FG,PrG,ps2G);
            fprintf('Subgps(Gps.)%9.3f%10i%10.3f%11.2f%9.4f%13.2f\n\n',SSSGG,dfSGG,MSSGG,FSGG,PrSGG,ps2SGG);
            fprintf('Error %15.3f%10i%10.3f%33.2f\n\n',SSE,dfE,MSE,ps2);
            fprintf('Total %15.3f%10i\n',SSTO,dfTO);
            fprintf('------------------------------------------------------------------------------\n');
            disp('     ')
         else
            disp('Nested factor always is random. Here, the highest level of classification is fixed.')   
            FG=MSG/MSE;
            FSGG=MSSGG/MSE;
            PrG = 1 - fcdf(FG,dfG,dfE);  %Probability associated to the groups F-statistic.
            PrSGG = 1 - fcdf(FSGG,dfSGG,dfE);  %Probability associated to the among subgroups within groups F-statistic.
            disp('     ')
            fprintf('--------------------------------------------------------------\n');
            disp('SV                SS          df     MS          F        P')
            fprintf('--------------------------------------------------------------\n');
            fprintf('Gps.      %11.3f%10i%10.3f%11.2f%9.4f\n\n',SSG,dfG,MSG,FG,PrG);
            fprintf('Subgps(Gps.)%9.3f%10i%10.3f%11.2f%9.4f\n\n',SSSGG,dfSGG,MSSGG,FSGG,PrSGG);
            fprintf('Error %15.3f%10i%10.3f\n\n',SSE,dfE,MSE);
            fprintf('Total %15.3f%10i\n',SSTO,dfTO);
            fprintf('--------------------------------------------------------------\n');
            disp('     ')  
         end 
         end