00001 #ifndef ANOVA1_HEADER
00002 #define ANOVA1_HEADER
00003
00004
00005
00015
00016
00017 #include <stdlib.h>
00018 #include <math.h>
00019
00020 #ifdef _STANDARD_C_PLUS_PLUS
00021 #include <vector>
00022 #include <algorithm>
00023 #include <iostream>
00024 #include <iomanip>
00025 #else
00026 #include <vector.h>
00027 #include <algo.h>
00028 #include <iostream.h>
00029 #include <iomanip.h>
00030 #endif
00031
00032 #include <string>
00033 using namespace std;
00034 #define NPOS string::npos
00035
00036
00037
00038 #include "Statexc.hh"
00039
00040
00041
00042 namespace RazorBack {
00043
00044 class Anova1_
00045 {
00046
00047 public:
00048
00053 class Group_
00054 {
00055
00056 private:
00057
00058 string Descr;
00059 double Sum;
00060 unsigned int Size;
00061
00062
00063 public:
00064
00066 explicit Group_(const string& D=string()):
00067 Descr(D), Sum(0.0), Size(0) {}
00068
00070 Group_(const string& D, double S, unsigned int N):
00071 Descr(D), Sum(S), Size(N) {}
00072
00073
00074
00075 const string& descr() const { return Descr; }
00076 unsigned int size() const { return Size; }
00077 double mean() const { return Sum/Size; }
00078
00079
00080 protected:
00081
00082 };
00083
00085 enum Sumidx_ {TOTAL=0, BETWEEN=1, WITHIN=2};
00086
00087
00088 private:
00089
00090 vector<Group_> Xgroups;
00091 vector<double> Sumsq, Meansq;
00092 unsigned int Groupno, Groupsize, Ntotal;
00093 vector<unsigned int> Degfree;
00094 bool Equalgroups;
00095 double Sumx, Sumx2, Sumgroup;
00096
00097
00098 public:
00099
00101 Anova1_()
00102 : Xgroups(), Sumsq(3), Meansq(3),
00103 Groupno(0), Groupsize(0), Ntotal(0), Degfree(3),
00104 Sumx(0.0), Sumx2(0.0), Sumgroup(0.0),
00105 Equalgroups(true) {}
00106
00108 void clear();
00109
00116 template <class Initer_>
00117 void add_group(const string& Groupname, Initer_ First, Initer_ Last)
00118 {
00119
00120
00121 register double X, Sx=0.0, Sx2=0.0;
00122 register unsigned int n=0;
00123
00124
00125 Initer_ Gp;
00126 for (Gp=First; Gp!=Last; ++Gp)
00127 {
00128 X=*Gp;
00129 Sx+=X; Sx2+=(X*X); ++n;
00130 }
00131 if (n<1)
00132 throw Toofewexc_("Anova1_::add_group()",
00133 "Data points in group", n);
00134
00135
00136 Group_ Newgroup(Groupname, Sx, n);
00137 Xgroups.push_back(Newgroup);
00138
00139
00140 update_sumsq(Sx, Sx2, n);
00141 }
00142
00143
00144
00146 const vector<Group_>& groups() const { return Xgroups; }
00147
00149 double sum_squares(Sumidx_ Idx) const { return Sumsq[Idx]; }
00150
00152 unsigned int degrees_freedom(Sumidx_ Idx) const { return Degfree[Idx]; }
00153
00155 double mean_squares(Sumidx_ Idx) const { return Meansq[Idx]; }
00156
00158 double f_ratio() const
00159 {
00160 return (Meansq[WITHIN]==0.0)?
00161 HUGE_VAL: Meansq[BETWEEN]/Meansq[WITHIN];
00162 }
00163
00164
00165
00166
00167
00168 vector<Anova1_::Group_>::const_iterator
00169 find_group(const string& Name) const;
00170
00178 double omnibus_ftest() const
00179 {
00180 if (Groupno<2)
00181 throw Toofewexc_("Anova1_::omnibus_ftest()", "Groupno", Groupno);
00182
00183 return (Meansq[WITHIN]==0.0)?
00184 0.0: f_test(f_ratio());
00185 }
00186
00192 double scheffe_test(vector<Group_>::const_iterator G1,
00193 vector<Group_>::const_iterator G2) const;
00194
00203 double scheffe_test(vector<Group_>::const_iterator F1,
00204 vector<Group_>::const_iterator L1,
00205 vector<Group_>::const_iterator F2,
00206 vector<Group_>::const_iterator L2) const;
00207
00215 double scheffe_test(const vector< vector<Group_>::const_iterator >& Metagroup1,
00216 const vector< vector<Group_>::const_iterator >& Metagroup2) const;
00217
00223 double tukey_atest(vector<Group_>::const_iterator G1,
00224 vector<Group_>::const_iterator G2) const;
00225
00226
00227 protected:
00228
00229 void update_sumsq(double Sx, double Sx2, unsigned int n);
00230 double f_test(double Fratio) const;
00231 double q_test(double q) const;
00232 };
00233
00234
00235 }
00236
00237
00238
00239 #endif // ANOVA1_HEADER