//Ordinal 2*5 crosstable analysis online.
//copyright: Daan G Uitenbroek PhD

function cut(real,lenght)  // changes scientific into normal notation and makes to size
{
var str=""+real;
var r="0.";
var pt=str.indexOf("e");
if (pt>0 ) 
    {
     var a=str.substring(0,1)+str.substring(2,pt+1);
     for (var index=1;index<=(str.substring(pt+2,pt+5)*1-1);index++)
        r+=0;
     var st=r+a;
      for (var index=st.length;index<=lenght;index++)
         st+="0";
     return (st.substring(0,lenght));
     };
for (var index=str.length;index<=lenght;index++)
      str+="0";
pt=str.indexOf(".");
if (pt==0) str="0"+str           //solves that newer versions of Netscape give inconsistent numeric notations
return str.substring(0,lenght);
}

function truncate(real,places)  // truncates 'real' numbers n 'places' behind the decimal dot
{
var multi=Math.pow(10,places);
return (Math.round(real*multi)/multi)
}

function odt(len1)   // to create a onedimensional table
{
  this.lenght=len1;
   for (var i=1;i<=len1;i++)
      this[i]=0;
  return this
}

function table(len1,len2)   // to create a two dimensional table
{
   this.lenght=len1;
      for (var j=1;j<=len1;j++)
           this[j]=new odt(len2);
    return this
}
function currentCI()
{
this.interval="95%"
this.intzval=1.96
}

function CI(length)
{
this.length=length
   for (var j=1;j<=length;j++)
      this[j]=new currentCI();

this[1].interval="80%"
this[1].intzval=1.282
this[2].interval="90%"
this[2].intzval=1.645
this[3].interval="95%"
this[3].intzval=1.96
this[4].interval="99%"
this[4].intzval=2.575
}

function changeCI(prop)
{
currentoption=prop.selectedIndex;
currentoption+=1*1;
CIcurrent=allCI[currentoption];
}

//following are statements to innitialize the confidence interval
currentoption=3  //3 is for 95% CI
CIcurrent=new currentCI()
allCI=new CI(4)  //because we allow for four different Confidence Intervals

function zpr(zval)  
{
if ((zval>5)||(zval<-5)) outp=0
else
{
if (zval == 0.0)     
     var x  = 0.0;        
else      
     {  
     var y = 0.5 * Math.abs (zval);        
     if (y >= (10000* 0.5))        
             x=1.0;  
     else if (y < 1.0)         
     {         
     var w = y*y;          
     x = ((((((((0.000124818987 * w  
          -0.001075204047) * w +0.005198775019) * w  
          -0.019198292004) * w +0.059054035642) * w  
          -0.151968751364) * w +0.319152932694) * w  
          -0.531923007300) * w +0.797884560593) * y * 2.0;     

    
     }         
     else      
     {  
     y -= 2.0;         
     x  = (((((((((((((-0.000045255659 * y  
          +0.000152529290) * y -0.000019538132) * y  
          -0.000676904986) * y +0.001390604284) * y  
          -0.000794620820) * y -0.002034254874) * y  
          +0.006549791214) * y -0.010557625006) * y  
          +0.011630447319) * y -0.009279453341) * y  
          +0.005353579108) * y -0.002141268741) * y  
          +0.000535310849) * y +0.999936657524*1;      
     }          
     }  
var outp=((zval > 0.0 ? ((x*1+1.0*1) * 0.5) : ((1.0 -x) * 0.5))) 
if ((outp>1)||(outp<-1)) (outp=1) 
}
return (outp) 
} 

function odd(number)    //returns zero if number is not odd, one if it is
{
var isodd=0*1;
if (Math.round(number/2+0.00001)==number/2)  isodd=1*1;
return isodd
}

function c2prob(chi2,df)
{
writeln="\n";
if (navigator.appVersion.lastIndexOf('Win') != -1) writeln="\r\n";

var add=0;
var mult=1;
if (odd(df)<0.5)
 {
      add=1;
      mult=Math.sqrt(2/chi2/Math.PI);
   }
var denominator=1;
for (var index=df;index>1;index-=2)
         denominator=denominator*index;
var numerator=Math.pow(chi2,((df*1+add*1)/2))*Math.exp(chi2*-1/2);
sum=1*1;
m=1*1;

for (var count=df*1+2*1;m>0.00000000001;count+=2)
   {
      m=(m*chi2)/count;
      sum=sum*1+m*1;
   }
var pval=1-sum*mult*numerator/denominator
return pval
}

function printtable(table)
{
writeln="\n";
if (navigator.appVersion.lastIndexOf('Win') != -1) writeln="\r\n";

for (var index=1;index<=6;index++)
   {
   for (var jndex=1;jndex<=3;jndex++)
      document.form1.outp.value+=table[index][jndex]+"  "
   document.form1.outp.value+=writeln
   }
document.form1.outp.value+=writeln
}

function concord(table)
{
var concordantpairs=0
for (var index=1;index<=4.5;index++)
  for (var jndex=(index+1);jndex<=5.5;jndex++)
      concordantpairs+=table[index][1]*table[jndex][2]
return concordantpairs
}

function discord(table)
{
var discordantpairs=0
for (var index=1;index<=4.5;index++)
   for (var jndex=(index+1);jndex<=5.5;jndex++)
      discordantpairs+=table[index][2]*table[jndex][1]
return discordantpairs
}

function tiehor(table)
{
var tiehorizontal=0
for (var index=1;index<=5.5;index++)
   tiehorizontal+=table[index][2]*table[index][1]
return tiehorizontal
}

function tiever(table)
{
writeln="\n";
if (navigator.appVersion.lastIndexOf('Win') != -1) writeln="\r\n";

var tievertical=0
for (var index=1;index<=2.5;index++)
  for (var jndex=1;jndex<=5.5;jndex++)
     tievertical+=table[jndex][index]*(table[6][index]-table[jndex][index])
return (tievertical/2)
}

function probtab(table,con)
{
var pointprob=0
for (var index=1;index<=5;index++)
 for (var jndex=1;jndex<=2;jndex++)
   pointprob=pointprob+factors[table[index][jndex]+1*1]*1
pointprob=Math.exp(con-pointprob)
return pointprob
}

function threeby2(n11,n12,n21,n22,n31,n32,n41,n42,n51,n52,checkbox)
{
writeln="\n";
if (navigator.appVersion.lastIndexOf('Win') != -1) writeln="\r\n";

data=new table(6,3);
data[1][1]=n11/1;
data[1][2]=n12/1;
data[2][1]=n21/1;
data[2][2]=n22/1;
data[3][1]=n31/1;
data[3][2]=n32/1;
data[4][1]=n41/1;
data[4][2]=n42/1;
data[5][1]=n51/1;
data[5][2]=n52/1;

data[1][3]=data[1][1]+data[1][2]*1;
data[2][3]=data[2][1]+data[2][2]*1;
data[3][3]=data[3][1]+data[3][2]*1;
data[4][3]=data[4][1]+data[4][2]*1;
data[5][3]=data[5][1]+data[5][2]*1;
data[6][1]=data[1][1]+data[2][1]*1+data[3][1]*1+data[4][1]*1+data[5][1]*1;
data[6][2]=data[1][2]+data[2][2]*1+data[3][2]*1+data[4][2]*1+data[5][2]*1;     // make marginals
data[6][3]=data[6][1]+data[6][2]*1     //total in  6,3

exptable=new table(6,3)

exptable[1][1]=data[1][1]/data[6][1]
exptable[1][2]=data[1][2]/data[6][2]
for (var index=2;index<6;index++) 
 for (var jndex=1;jndex<3;jndex++)    
  exptable[index][jndex]=exptable[index-1][jndex]+data[index][jndex]/data[6][jndex]

//printtable(data)

factors=new odt(data[6][3]+1*1); 
factors[1]=0; 
factors[2]=0; 
for (var i=1;i<(data[6][3]+2*1);i++)   
factors[i+1]=factors[i]+Math.log(i); //make an array of log factorials

constant=factors[data[1][3]+1*1]+factors[data[2][3]+1*1]*1+factors[data[3][3]+1*1]*1
constant=constant+factors[data[4][3]+1*1]*1+factors[data[5][3]+1*1]*1
constant=constant+factors[data[6][1]+1*1]*1+factors[data[6][2]+1*1]*1-factors[data[6][3]+1*1]

var pointpr=probtab(data,constant)
document.form1.outp.value+="the pointprobability eq: "+pointpr+writeln+writeln 

//printtable(data)

var totpair=data[6][3]*(data[6][3]-1)/2
var concordants=concord(data)
var discordants=discord(data)
var difcordants=concordants-discordants
document.form1.outp.value+="this table total pairs: "+totpair+writeln
                            +"concordant pairs: "+concordants+writeln
                            +"discordant pairs: "+discordants+writeln
                            +"pairs tied in collumns: "+tiever(data)+writeln
                            +"pairs tied in rows: "+tiehor(data)+writeln
                            +"difcordance (concordant-discordant): "+difcordants+writeln


var gamma=(concordants-discordants)/(concordants*1+discordants*1)
var tau=(concordants-discordants)/totpair

concortab=new table(6,3)
for (var index=1;index<=6.5;index++)
   for (var jndex=1;jndex<=2.5;jndex++)
      concortab[index][jndex]=0
for (var index=2;index<5.5;index++)
  for (var jndex=1;jndex<=(index-1);jndex++)
     concortab[index][2]+=data[jndex][1]
for (var index=1;index<4.5;index++)
  for (var jndex=(index+1*1);jndex<=5.5;jndex++)
     concortab[index][1]+=data[jndex][2]

discortab=new table(6,3)
for (var index=1;index<=6.5;index++)
   for (var jndex=1;jndex<=2.5;jndex++)
      discortab[index][jndex]=0
for (var index=2;index<5.5;index++)
  for (var jndex=1;jndex<=(index-1);jndex++)
     discortab[index][1]+=data[jndex][2]
for (var index=1;index<4.5;index++)
  for (var jndex=(index+1*1);jndex<=5.5;jndex++)
     discortab[index][2]+=data[jndex][1]

wtab=new table(6,3)
for (var index=1;index<=6.5;index++)
   for (var jndex=1;jndex<=2.5;jndex++)
      wtab[index][jndex]=concortab[index][jndex]-discortab[index][jndex]

var fw=0
for (var index=1;index<=5.5;index++)
   for (var jndex=1;jndex<=2.5;jndex++)
      fw+=wtab[index][jndex]*data[index][jndex]
var fw2=0
for (var index=1;index<=5.5;index++)
   for (var jndex=1;jndex<=2.5;jndex++)
      fw2+=wtab[index][jndex]*data[index][jndex]*wtab[index][jndex]
var fwsq=fw*fw

//sd for gamma
frgamma=0
for (var index=1;index<=5.5;index++)
   for (var jndex=1;jndex<=2.5;jndex++)
      frgamma+=data[index][jndex]*(concortab[index][jndex]+discortab[index][jndex]*1)
fr2gamma=0
for (var index=1;index<=5.5;index++)
   for (var jndex=1;jndex<=2.5;jndex++)
      fr2gamma+=data[index][jndex]*(concortab[index][jndex]+discortab[index][jndex]*1)
                *(concortab[index][jndex]+discortab[index][jndex]*1)
fwrgamma=0
for (var index=1;index<=5.5;index++)
   for (var jndex=1;jndex<=2.5;jndex++)
      fwrgamma+=data[index][jndex]*wtab[index][jndex]
               *(concortab[index][jndex]+discortab[index][jndex]*1)
var frsqgamma=frgamma*frgamma

sdgamma=2/frsqgamma
sdgamma*=Math.sqrt(fw2*frsqgamma-2*frgamma*fw*fwrgamma+fwsq*fr2gamma)

//sd for tau
frtau=0
for (var index=1;index<=5.5;index++)
   for (var jndex=1;jndex<=2.5;jndex++)
      frtau+=data[index][jndex]*(data[6][3]-1)
fr2tau=0
for (var index=1;index<=5.5;index++)
   for (var jndex=1;jndex<=2.5;jndex++)
      fr2tau+=data[index][jndex]*(data[6][3]-1)*(data[6][3]-1)
fwrtau=0
for (var index=1;index<=5.5;index++)
   for (var jndex=1;jndex<=2.5;jndex++)
      fwrtau+=data[index][jndex]*wtab[index][jndex]
               *(data[6][3]-1)

var frsqtau=frtau*frtau

sdtau=2/frsqtau
sdtau*=Math.sqrt(fw2*frsqtau-2*frtau*fw*fwrtau+fwsq*fr2tau)

var hulp=new odt(3)
for (jndex=1;jndex<3.5;jndex++)
for (var index=5;index>1.5;index--)
if (data[index][3]==0)  
{var hulp=data[index]
 data[index]=data[index-1]
 data[index-1]=hulp
}     //bubble smaller tables to bottom

nofdif=0
nofconcord=0
nofconcord2=0
duble2=0;
duble=0;
divpr=0;
noftables=0*1

if (checkbox.checked)
{
roworcol=data[1][3];
if (roworcol>data[6][1]) roworcol=data[6][1]
colrow=data[2][3];
if (colrow>data[6][1]) colrow=data[6][1]
rowcol=data[3][3];
if (rowcol>data[6][1]) rowcol=data[6][1]

for (var index=0;index<=roworcol;index++)
{data[1][1]=index
 data[1][2]=data[1][3]-index

 for (var kndex=0;kndex<=colrow;kndex++)
  {data[2][1]=kndex
   data[2][2]=data[2][3]-kndex

   for (var lndex=0;lndex<=rowcol;lndex++)
    {data[3][1]=lndex
     data[3][2]=data[3][3]-lndex

     var colorrow=data[6][1]-index-kndex-lndex;  
     if (colorrow>data[4][3]) colorrow=data[4][3]
     var start=0
     if (data[5][3]<(data[6][1]-index-kndex-lndex)) 
         start=data[6][1]-data[5][3]-index-kndex-lndex
 
      for (var jndex=start;jndex<=colorrow;jndex++)
       {data[4][1]=jndex
        data[4][2]=data[4][3]-jndex
        data[5][1]=data[6][1]-index-kndex-lndex-jndex
        data[5][2]=data[5][3]-data[5][1]
        noftables++
        //document.form1.outp.value+="accepted "+writeln
        prval=probtab(data,constant);
        if ((concord(data)-discord(data))>=difcordants) 
             {nofdif++
              divpr=divpr+prval*1
             }
        if (concord(data)>=concordants)
            {nofconcord++
             duble=duble+prval*1
            }
        if (concord(data)>concordants)
            {nofconcord2++
             duble2=duble2+prval*1
            }
      } 
    }
   //printtable(data)
 }
} //produce all permutations of the table

document.form1.outp.value+=writeln+"Use of * (starred) statistics is advised"+writeln
document.form1.outp.value+=writeln+noftables+" tables evaluated"+writeln
                           +nofconcord+" had more/same number of concordant pairs"+writeln
                           +"p(O(c)>=E(c)): "+truncate(duble,10)+"; 1-p: "+truncate((1-duble),10)+writeln
                           +nofconcord2+" tables had more concordant pairs"+writeln
                           +"p(O(c)>E(c)): "+truncate(duble2,10)+"; 1-p: "+truncate((1-duble2),10)+writeln
                           +nofdif+" had same or higher difcordance"+" *"+writeln
                           +"p(O(d)>=E(d)): "+truncate(divpr,10)+"; 1-p: "+truncate((1-divpr),10)+writeln
} //end of if statement checkbox

document.form1.outp.value+=writeln+"gamma: "+truncate(gamma,7)+"; sd: "+truncate(sdgamma,7)+"; p= "+truncate(zpr(gamma/sdgamma),7)+" *"+writeln
          +CIcurrent.interval+" CI: "+truncate((gamma-sdgamma*CIcurrent.intzval),4)+"<gamma<"+truncate((gamma+sdgamma*CIcurrent.intzval),4)+writeln
          +"tau-a: "+truncate(tau,7)+"; sd: "+truncate(sdtau,7)+"; p= "+truncate(zpr(tau/sdtau),7)+writeln
          +CIcurrent.interval+" CI: "+truncate((tau-sdtau*CIcurrent.intzval),4)+"<tau<"+truncate((tau+sdtau*CIcurrent.intzval),4)+writeln

var dif=Math.abs(exptable[1][1]-exptable[1][2])
for (var index=1;index<5;index++) 
  if (((exptable[index][1]-exptable[index][2])>dif)||((exptable[index][1]-exptable[index][2])>dif))  //changed this
      dif=Math.abs(exptable[index][1]-exptable[index][2])

var chi=4*dif*dif*data[6][1]*data[6][2]/(data[6][1]+data[6][2])

document.form1.outp.value+=writeln+"K-S prob that collumns are from same ordering"+writeln
                           +"d= "+truncate(dif,4)+"; chi2= "+truncate(chi,3)+" (2df); p= "+truncate(c2prob(chi,2),5)
                           +writeln+writeln

//printtable(exptable)
}

function ClearOutp()
{
var writeln="\n";
if (navigator.appVersion.lastIndexOf('Win') != -1) writeln="\r\n"; 

document.form1.outp.value="cleared; "+writeln;
}

