%mathpiper,def="AnovaCompletelyRandomizedBlock"


AnovaCompletelyRandomizedBlock(levelsList, alpha) :=
[
    Check(IsMatrix(levelsList), "Argument", "The first argument must be a list of equal-length lists.");
    
    Check(alpha >= 0 And alpha <= 1, "Argument", "The second argument must be a number between 0 and 1.");
    
    Local(
        topOfSummary,
        anovaBlockTableRow1,
        criticalFScore,
        anovaBlockTableRow3,
        anovaBlockTableRow2,
        lengthsList,
        summaryTableRow,
        sumsList,
        meanSquareWithin,
        topOfPage,
        htmlJavaString,
        index,
        variancesList,
        grandMean,
        row,
        topOfAnovaBlock,
        result,
        fScoreBlock,
        criticalFScoreBlock,
        blockMeansList,
        sumOfSquaresWithin',
        meanSquareBetween,
        sumOfSquaresBetween,
        fScore,
        summaryTableRows,
        meansList,
        sumOfSquaresBlock,
        b,
        blockSummaryTableRow,
        bottomOfAnovaBlock,
        sumOfSquaresWithin,
        bottomOfPage,
        k,
        sumOfSquaresTotal,
        meanSquareBlock,
        bottomOfSummary
    );
    
    meansList := {};
    
    variancesList := {};
    
    sumsList := {};
    
    lengthsList := {};
    
    
    //ANOVA calculations.
    ForEach(levelList, levelsList)
    [
        meansList := meansList : N(Mean(levelList));
        
        variancesList := variancesList : N(UnbiasedVariance(levelList));
        
        sumsList := sumsList : N(Sum(levelList));

        lengthsList := lengthsList : Length(levelList);
    ];
    
    sumOfSquaresWithin := Sum((lengthsList - 1) * variancesList);

    grandMean := N(Mean(meansList));
    
    sumOfSquaresBetween := Sum(lengthsList*(meansList - grandMean)^2);
    
    
    
    //Block calculations.
    blockMeansList := {};
    
    index := 1;
    
    While(index <= Length(First(levelsList)) )
    [
        row := MatrixColumn(levelsList, index);
        
        blockMeansList := Append(blockMeansList,N(Mean(row)));
    
        index++;
    ];
    
    b := Length(blockMeansList);
    
    k := Length(levelsList);
    
    sumOfSquaresBlock := Sum(j,1,b, k*(blockMeansList[j] - grandMean)^2);
    
    sumOfSquaresTotal := N(sumOfSquaresWithin + sumOfSquaresBetween);
    
    sumOfSquaresWithin' := N(sumOfSquaresTotal - sumOfSquaresBetween - sumOfSquaresBlock);
    
    meanSquareBetween := N(sumOfSquaresBetween/(k - 1));
    
    meanSquareWithin := N(sumOfSquaresWithin'/((k - 1)*(b - 1)));
    
    fScore := N(meanSquareBetween/meanSquareWithin);
    
    meanSquareBlock := N(sumOfSquaresBlock/(b - 1));
    
    fScoreBlock := N(meanSquareBlock/meanSquareWithin);
    
    criticalFScore := ProbabilityToFScore(k - 1, (k - 1)*(b - 1), 1-alpha);
    
    criticalFScoreBlock := ProbabilityToFScore(b - 1, (k - 1)*(b - 1), 1-alpha);
    
    
    
    topOfPage :=
"
    <html>
        <title>
            Anova: Completely Randomized Block
        </title>
        
        <body>
";
    
    topOfSummary :=
"
            <h2>Anova: Completely Randomized Block</h2>
            
            <TABLE BORDER>
                <CAPTION align=\"left\"> <h3>Summary</h3>  </CAPTION>
                
                <TR> <TH> Level </TH> <TH> Count</TH> <TH> Sum </TH> <TH> Mean </TH> <TH> Variance </TH> </TR>
";

    
    summaryTableRows := "";
    
    summaryTableRow := "<TR> <TD> <?Write(ToAtom(ToString(Level):ToString(index)));?> </TD> <TD align=\"right\"> <?Write(lengthsList[index]);?> </TD> <TD> <?Write(sumsList[index]);?> </TD>  <TD> <?Write(meansList[index]);?> </TD> <TD> <?Write(variancesList[index]);?> </TD> </TR>":Nl();
    
    
    //Data summary.
    index := 1;
    
    While(index <= Length(levelsList))
    [
        summaryTableRows := summaryTableRows : PatchString(summaryTableRow);
    
        index++;
    ];
    

    //Block summary.
    
    blockSummaryTableRow := "<TR> <TD> <?Write(ToAtom(\"Block\":ToString(index)));?> </TD> <TD align=\"right\"> <?Write(Length(row));?> </TD> <TD> <?Write(N(Sum(row)));?> </TD>  <TD> <?Write(N(Mean(row)));?> </TD> <TD> <?Write(N(UnbiasedVariance(row)));?> </TD> </TR>":Nl();

    index := 1;
    
    While(index <= Length(First(levelsList)) )
    [
        row := MatrixColumn(levelsList, index);
        
        summaryTableRows := summaryTableRows : PatchString(blockSummaryTableRow);
    
        index++;
    ];
    
    
    
    
    
    bottomOfSummary :=
"
            </TABLE>
";
    


    topOfAnovaBlock :=
"
            <br \>
            <br \>
            
            <TABLE BORDER>
                <CAPTION align=\"left\"> <h3>ANOVA: Completely Randomized Block</h3>  </CAPTION>
                
                <TR> <TH> Source of Variation </TH> <TH> Sum of Squares </TH> <TH> Degrees of Freedom </TH> <TH> Mean Square </TH> <TH> F </TH> <TH> F Critical </TH> </TR>
";

    
    
    anovaBlockTableRow1 := PatchString("<TR> <TD> <?Write(ToAtom(\"Between Levels\"));?> </TD> <TD > <?Write(sumOfSquaresBetween);?> </TD> <TD> <?Write(k - 1);?> </TD>   <TD > <?Write(meanSquareBetween);?> </TD><TD> <?Write(fScore);?> </TD> <TD> <?Write(criticalFScore);?> </TD> </TR>":Nl());
    
    anovaBlockTableRow2 := PatchString("<TR> <TD> <?Write(ToAtom(\"Between Blocks\"));?> </TD> <TD > <?Write(sumOfSquaresBlock);?> </TD> <TD> <?Write(b - 1);?> </TD>   <TD > <?Write(meanSquareBlock);?> </TD> <TD> <?Write(fScoreBlock);?> </TD> <TD> <?Write(criticalFScoreBlock);?> </TD> </TR>":Nl());

    anovaBlockTableRow3 := PatchString("<TR> <TD> <?Write(ToAtom(\"Within Levels\"));?> </TD> <TD > <?Write(sumOfSquaresWithin');?> </TD> <TD> <?Write(b - 1);?> </TD>   <TD > <?Write(meanSquareWithin);?> </TD></TR>":Nl());

    bottomOfAnovaBlock :=
"
            </TABLE>
";


    
    bottomOfPage :=
"
        </body>         
    </html>
";
    
    htmlJavaString := JavaNew("java.lang.String",
                topOfPage : 
                topOfSummary : 
                summaryTableRows : 
                bottomOfSummary : 
                topOfAnovaBlock : 
                anovaBlockTableRow1 : 
                anovaBlockTableRow2 : 
                anovaBlockTableRow3 : 
                bottomOfAnovaBlock :
                bottomOfPage);
                
                
                
     result := {};
     
     result["html"] := htmlJavaString;
     
     result["sumOfSquaresWithin'"] := sumOfSquaresWithin';
     
     result["sumOfSquaresBetween"] := sumOfSquaresBetween;
     
     result["sumOfSquaresBlock"] := sumOfSquaresBlock;
     
     result["sumOfSquaresTotal"] := sumOfSquaresTotal;
     
     result["meanSquareBetween"] := meanSquareBetween;
     
     result["meanSquareWithin"] := meanSquareWithin;
     
     result["meanSquareBlock"] := meanSquareBlock;
     
     result["fScore"] := fScore;
     
     result["criticalFScore"] := criticalFScore;
     
     result["fScoreBlock"] := fScoreBlock;
     
     result["criticalFScoreBlock"] := criticalFScoreBlock;
     
     result;
];


%/mathpiper

    %output,preserve="false"
      Result: True
.   %/output









%mathpiper_docs,name="AnovaCompletelyRandomizedBlock",categories="User Functions;Statistics & Probability",access="experimental"
*CMD AnovaCompleteRandomizedBlock --- performs an ANOVA completely randomized block analysis

*CALL
	AnovaCompletelyRandomizedBlock(2dMatrix,alpha)

*PARMS
{2dMatrix} -- a two dimensional matrix which contain the data to be analyzed

{alpha} -- the alpha value to use in the analysis.

*DESC
This function performs an ANOVA completely randomized block analysis.  The various values that are
calculated during the analysis are returned in an association list and these
values are listed in the keys of the returned list (see the examples section).

If the {html} key is passed to the {ViewHtml} function, the results of the analysis
are displayed in a graphcs window as rendered HTML.

*E.G.
/%mathpiper,scope="nobuild",subtype="manual_test"

alpha := .05;

factor1List := {10.2,8.5,8.4,10.5,9.0,8.1};

factor2List := {11.6,12.0,9.2,10.3,9.9,12.5};

factor3List := {8.1,9.0,10.7,9.1,10.5,9.5};

Echo(anovaBlock := AnovaCompletelyRandomizedBlock({factor1List,factor2List,factor3List}, alpha));

NewLine();

Echo("F-Score of the block: ", anovaBlock["fScoreBlock"]);

ViewHtml(anovaBlock["html"]);

/%/mathpiper

    /%output,preserve="false"
      Result: True
      
      Side Effects:
      {"criticalFScoreBlock",3.325834530} {"fScoreBlock",0.08045614890} {"criticalFScore",4.102821015} {"fScore",3.078377024} 
      {"meanSquareBlock",0.1418888884} {"meanSquareWithin",1.763555556} {"meanSquareBetween",5.428888905} {"sumOfSquaresTotal",29.20277781} 
      {"sumOfSquaresBlock",0.7094444419} {"sumOfSquaresBetween",10.85777781} {"sumOfSquaresWithin'",17.63555556} {"html",java.lang.String} 
      
      F-Score of the block: 0.08045614890 
      
.   /%/output

*SEE ViewHtml, ScheffeTest
%/mathpiper_docs

    %output,preserve="false"
      
.   %/output









%mathpiper,scope="nobuild",subtype="manual_test"

alpha := .05;

factor1List := {10.2,8.5,8.4,10.5,9.0,8.1};

factor2List := {11.6,12.0,9.2,10.3,9.9,12.5};

factor3List := {8.1,9.0,10.7,9.1,10.5,9.5};

Echo(anovaBlock := AnovaCompletelyRandomizedBlock({factor1List,factor2List,factor3List}, alpha));

NewLine();

Echo("F-Score of the block: ", anovaBlock["fScoreBlock"]);

ViewHtml(anovaBlock["html"]);

%/mathpiper

    %output,preserve="false"
      Result: True
      
      Side Effects:
      {"criticalFScoreBlock",3.325834530} {"fScoreBlock",0.08045614890} {"criticalFScore",4.102821015} {"fScore",3.078377024} {"meanSquareBlock",0.1418888884} {"meanSquareWithin",1.763555556} {"meanSquareBetween",5.428888905} {"sumOfSquaresTotal",29.20277781} {"sumOfSquaresBlock",0.7094444419} {"sumOfSquaresBetween",10.85777781} {"sumOfSquaresWithin'",17.63555556} {"html",java.lang.String} 
      
      F-Score of the block: 0.08045614890 
      
.   %/output


