00001 using System;
00002 using System.Windows.Forms;
00003
00004 namespace StephenAshley.Biostatistics
00005 {
00006 using NUMBER = Decimal;
00007
00014 public class ChiSquaredArray
00015 {
00019 protected ChiSquaredArray() { }
00020
00026 public ChiSquaredArray(Int32 columns, Int32 rows)
00027 {
00028 outcomesArray = new Outcome[(iColumns = columns) + 1, (iRows = rows) + 1];
00029 iColumns = columns;
00030 iRows = rows;
00031 }
00036 protected Outcome[,] outcomesArray;
00037
00038 private Int32 iColumns;
00039 private Int32 iRows;
00040
00055 public void Add(Int32 column, Int32 row, Int32 observed)
00056 {
00057 if (column < 0)
00058 throw new BiostatisticsException(
00059 "column value in Add method of ChiSquaredArray less than 0.");
00060
00061 if (column > iColumns)
00062 throw new BiostatisticsException(
00063 "column value in Add method of ChiSquaredArray greater than iColumns.");
00064
00065 if (row < 0)
00066 throw new BiostatisticsException(
00067 "row value in Add method of ChiSquaredArray less than 0.");
00068
00069 if (row > iRows)
00070 throw new BiostatisticsException(
00071 "row value in Add method of ChiSquaredArray greater than iRows.");
00072
00073 outcomesArray[column, row] = new Outcome(observed, 0);
00074 FillArray();
00075 }
00076
00092 public void Add(Int32 column, Int32 row, Int32 observed, NUMBER expected)
00093 {
00094 outcomesArray[column, row].decExpected = expected;
00095 Add(column, row, observed);
00096 }
00097
00112 public void Add(Int32 column, Int32 row, Outcome outcome)
00113 {
00114 Add(column, row, outcome.iObserved, outcome.decExpected);
00115 }
00116
00133 public void Add(Int32 iCols, Int32 iRows, TextBox[,] pitb)
00134 {
00135 for (Int32 i = 0; i < iCols; i++)
00136 for (Int32 j = 0; j < iRows; j++)
00137 Add(i, j, Convert.ToInt32(pitb[i, j].Text));
00138 }
00143 public NUMBER ChiSquared()
00144 {
00145 return outcomesArray[iColumns, iRows].decDifferenceSquared;
00146 }
00147
00152 public Int32 DegreesOfFreedom()
00153 {return (iColumns - 1) * (iRows - 1);}
00154
00160 public virtual NUMBER p()
00161 {return Convert.ToDecimal(Distributions.ProbabilityChiSq(Convert.ToDouble(ChiSquared()),
00162 DegreesOfFreedom()));}
00163
00164 private void FillArray()
00165 {
00166
00167 for (Int32 i = 0; i < iColumns; i++)
00168 {
00169 Int32 iTotal = 0;
00170 for (Int32 j = 0; j < iRows; j++)
00171 {
00172 iTotal += outcomesArray[i, j].iObserved;
00173 }
00174 outcomesArray[i, iRows].iObserved = iTotal;
00175 }
00176
00177
00178 for (Int32 i = 0; i < iRows; i++)
00179 {
00180 Int32 iTotal = 0;
00181 for (Int32 j = 0; j < iColumns; j++)
00182 iTotal += outcomesArray[j, i].iObserved;
00183 outcomesArray[iColumns, i].iObserved = iTotal;
00184 }
00185
00186
00187 Int32 iGrandTotal = 0;
00188 for (Int32 i = 0; i < iColumns; i++)
00189 {
00190 iGrandTotal += outcomesArray[i, iRows].iObserved;
00191 }
00192
00193 outcomesArray[iColumns, iRows].iObserved = iGrandTotal;
00194
00195 NUMBER decYatesCorrection = 0.0m;
00196 if (iColumns == 2 && iRows == 2)
00197 decYatesCorrection = 0.5m;
00198
00199
00200 for (Int32 i = 0; i < iColumns; i++)
00201 for (Int32 j = 0; j < iRows; j++)
00202 {
00203 if (outcomesArray[iColumns, iRows].iObserved != 0)
00204 outcomesArray[i, j].decExpected = Convert.ToDecimal(
00205 outcomesArray[iColumns, j].iObserved * outcomesArray[i, iRows].iObserved)
00206 / outcomesArray[iColumns, iRows].iObserved;
00207
00208 NUMBER decDifference = DecMath.Abs( outcomesArray[i,j].decExpected -
00209 outcomesArray[i,j].iObserved) - decYatesCorrection;
00210 outcomesArray[i, j].decDifferenceSquared = decDifference * decDifference;
00211 }
00212
00213 NUMBER decChiSquared = 0.0m;
00214 for (Int32 i = 0; i < iColumns; i++)
00215 for (Int32 j = 0; j < iRows; j++)
00216 {
00217 if (outcomesArray[i,j].decExpected != 0.0m)
00218 decChiSquared += outcomesArray[i, j].decDifferenceSquared /
00219 outcomesArray[i, j].decExpected;
00220 }
00221 outcomesArray[iColumns, iRows].decDifferenceSquared = decChiSquared;
00222 }
00223 }
00224
00225
00230 public struct Outcome
00231 {
00237 public Outcome(Int32 observed, Int32 expected)
00238 {
00239 iObserved = observed;
00240 decExpected = expected;
00241 decDifferenceSquared = 0.0m;
00242 }
00246 public Int32 iObserved;
00250 public NUMBER decExpected;
00254 public NUMBER decDifferenceSquared;
00255 }
00256 }