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