00001 #ifndef NJTREE_H
00002
00003 #define NJTREE_H
00004
00005
00006 #include <iostream>
00007 #include <cstdlib>
00008 #include <cstdio>
00009 #include <fstream>
00010
00011
00012
00013 #define PRC 20
00014 #define LEN 50
00015
00022 struct word
00023 {
00024 word() : next(0) { }
00025 word(const char n[]) { strcpy(name, n); }
00026 char name[LEN];
00027 struct word *next;
00028 };
00029
00033 struct wordList
00034 {
00035 wordList() :head(0), tail(0) {}
00036 word *head;
00037 word *tail;
00038 };
00039
00042 class njtree
00043 {
00044 public:
00045 enum inputformat { MATRIX, NUMTAXON };
00046 njtree() : trees(0), delta(0), n(0) { };
00047 ~njtree();
00070 bool load(std::istream &ins, inputformat ipf);
00080 bool load_generic(std::istream &ins);
00081
00082 int taxonCount() const { return n; }
00083 int remainingCount() const { return r; }
00091 bool symmetric();
00092 void compute_sums_Sx();
00093 void best_pair(int &a, int &b) const;
00094 void reduction(int a, int b);
00095 void finish(std::ostream &ous);
00096 void output(int i, std::ostream &ous);
00097
00098 private:
00099 bool empty(int i) const { return trees[i].head == 0; }
00100
00101 double distance(int i, int j) const;
00102 double variance(int i, int j) const;
00103
00104 double agglomerative_criterion(int i, int j) const;
00105 double branch_length(int a, int b) const;
00106 double lamda(int a, int b) const;
00107 double reduction4(int a, double la, int b, double lb, int i, double lam) const;
00108 double reduction10(int a, int b, int i, double lam, double vab) const;
00109 void concatenate(const char chn1[], int ind, int post);
00110 double finish_branch_length(int i, int j, int k) const;
00111 void clear();
00112
00114
00117 double **delta;
00122 int n;
00123 int r;
00124
00127 wordList *trees;
00128
00130 static int PREC;
00131 };
00132
00134
00135 inline double njtree::agglomerative_criterion(int i, int j) const
00136 {
00137 return (r-2)*distance(i,j) - delta[i][i] - delta[j][j];
00138
00139 }
00140
00141 inline double njtree::distance(int i, int j) const
00142 {
00143 return i>j? delta[i][j] : delta[j][i];
00144 }
00145
00146 inline double njtree::variance(int i, int j) const
00147 {
00148 return (i > j)? (delta[j][i]) : (delta[i][j]);
00149 }
00150
00151 inline double njtree::branch_length(int a, int b) const
00152 {
00153
00154 return 0.5*(distance(a,b) + (delta[a][a]-delta[b][b])/(r-2));
00155 }
00156
00157 inline double njtree::reduction4(int a, double la, int b, double lb, int i, double lam) const
00158 {
00159 return lam*(distance(a,i)-la) +(1-lam)*(distance(b,i)-lb);
00160
00161 }
00162
00163 inline double njtree::reduction10(int a, int b, int i, double lam, double vab) const
00164 {
00165 return lam*variance(a,i)+(1-lam)*variance(b,i) -lam*(1-lam)*vab;
00166
00167 }
00168
00169 inline double njtree::finish_branch_length(int i, int j, int k) const
00170 {
00171 return 0.5*(distance(i,j) + distance(i,k) -distance(j,k));
00172
00173 }
00174 #endif