00001 using System; 00002 00003 namespace StephenAshley.Biostatistics 00004 { 00005 using NUMBER = Decimal; 00011 public class ZTest 00012 { 00016 public ZTest() 00017 { 00018 data = new ZTest.Fields(2, 2, 0.0000000000000000000000000001m, 00019 0.0000000000000000000000000001m); 00020 } 00021 00030 public ZTest(Int32 iSampleSize1, Int32 iSampleSize2, NUMBER decProportion1, 00031 NUMBER decProportion2) 00032 { 00033 SetN1(iSampleSize1); 00034 SetN2(iSampleSize2); 00035 SetP1(decProportion1); 00036 SetP2(decProportion2); 00037 } 00038 00039 private Fields data; 00040 00041 #region ****** properties ****** 00048 public Int32 N1() 00049 { 00050 return data.iN1; 00051 } 00052 00058 public void SetN1(Int32 value) 00059 { 00060 if (value < 2) throw new BiostatisticsException("N1 value in ZTest less than 2."); 00061 data.iN1 = value; 00062 } 00063 00068 public Int32 N2() 00069 { 00070 return data.iN2; 00071 } 00072 00079 public void SetN2(Int32 value) 00080 { 00081 if (value < 2) throw new BiostatisticsException("N2 value in ZTest less than 2."); 00082 data.iN2 = value; 00083 } 00084 00091 public NUMBER P1() 00092 { 00093 return data.decP1; 00094 } 00095 00101 public void SetP1(NUMBER value) 00102 { 00103 if (value <= 0.0m) 00104 throw new BiostatisticsException("P1 value in ZTest less than 0."); 00105 data.decP1 = value; 00106 } 00111 public NUMBER P2() 00112 { 00113 return data.decP2; 00114 } 00115 00122 public void SetP2(NUMBER value) 00123 { 00124 if (value <= 0.0m) 00125 throw new BiostatisticsException("P2 value in ZTest less than 0."); 00126 data.decP2 = value; 00127 } 00132 public NUMBER ConfidenceLevelLowerLimit() 00133 { 00134 return Difference() - 00135 1.959964394569397m * StandardErrorOfDifference(); 00136 } 00137 00141 public NUMBER ConfidenceLevelUpperLimit() 00142 { 00143 return Difference() + 1.959964394569397m * StandardErrorOfDifference(); 00144 } 00145 00150 public NUMBER Difference() { return P1() - P2(); } 00151 00157 public NUMBER p() { return Distributions.ProbabilityZ(Z()); } 00158 00167 public NUMBER PooledProportion() 00168 { 00169 NUMBER decResult; 00170 00171 try 00172 { 00173 decResult = (N1() * P1() + N2() * P2()) / (N1() + N2()); 00174 } 00175 catch (Exception e) 00176 { 00177 throw new BiostatisticsException(e.Source + ": " + e.Message, e); 00178 } 00179 return decResult; 00180 } 00181 00190 public NUMBER StandardErrorOfDifference() 00191 { 00192 NUMBER decStandardErrorOfDifference; 00193 try 00194 { 00195 decStandardErrorOfDifference = DecMath.Sqrt(PooledProportion() * 00196 (1.0m - PooledProportion()) 00197 * (1.0m / N1() + 1.0m / N2())); 00198 } 00199 catch (Exception e) 00200 { 00201 throw new BiostatisticsException(e.Source + ": " + e.Message, e); 00202 } 00203 return decStandardErrorOfDifference; 00204 } 00205 00211 public NUMBER Z() 00212 { 00213 NUMBER decZ; 00214 00215 try 00216 { 00217 if (StandardErrorOfDifference() == 0.0m) 00218 decZ = Decimal.MaxValue; 00219 else 00220 decZ = (DecMath.Abs(Difference()) - 0.5m * ((1.0m / N1()) + (1.0m / N2()))) 00221 / StandardErrorOfDifference(); 00222 } 00223 catch (Exception e) 00224 { 00225 throw new BiostatisticsException(e.Source + ": " + e.Message, e); 00226 } 00227 00228 return decZ; 00229 } 00230 00231 #endregion 00232 00233 00234 private struct Fields 00235 { 00236 public Fields(Int32 N1, Int32 N2, NUMBER P1, NUMBER P2) 00237 { 00238 if (N1 < 2) 00239 throw new BiostatisticsException( 00240 "N1 value in Fields constructor of ZTest < 2."); 00241 if (N2 < 2) 00242 throw new BiostatisticsException( 00243 "N2 value in Fields constructor of ZTest < 2."); ; 00244 if (P1 < 0.0000000000000000000000000001m) 00245 throw new BiostatisticsException( 00246 "P1 value in Fields constructor of ZTest < minimum positive value of a Decimal."); 00247 if (P2 < 0.0000000000000000000000000001m) 00248 throw new BiostatisticsException( 00249 "P2 value in Fields constructor of ZTest < minimum positive value of a Decimal."); 00250 00251 iN1 = N1; 00252 iN2 = N2; 00253 decP1 = P1; 00254 decP2 = P2; 00255 } 00256 00257 public Fields(Fields fields) 00258 { 00259 iN1 = fields.iN1; 00260 iN2 = fields.iN2; 00261 decP1 = fields.decP1; 00262 decP2 = fields.decP2; 00263 } 00264 00265 public Int32 iN1; 00266 public Int32 iN2; 00267 public NUMBER decP1; 00268 public NUMBER decP2; 00269 } 00270 } 00271 }