22 void PH_NEIGHBOURJOINING::remove_taxa_from_dist_list(
long i) {
25 for (a=0; a<swap_size; a++) {
29 nd = &(dist_matrix[i][j]);
32 nd = &(dist_matrix[j][i]);
35 net_divergence[j] -= nd->
val;
38 void PH_NEIGHBOURJOINING::add_taxa_to_dist_list(
long i) {
43 for (a=0; a<swap_size; a++) {
47 nd = &(dist_matrix[i][j]);
50 nd = &(dist_matrix[j][i]);
53 pos = (
int)(nd->
val*dist_list_corr);
54 if (pos >= dist_list_size) {
55 pos = dist_list_size-1;
58 nd->
add(&(dist_list[pos]));
60 net_divergence[j] += nd->
val;
63 net_divergence[i] = my_nd;
66 AP_FLOAT PH_NEIGHBOURJOINING::get_max_net_divergence() {
69 for (a=0; a<swap_size; a++) {
71 if (net_divergence[i] > max) max = net_divergence[i];
76 void PH_NEIGHBOURJOINING::remove_taxa_from_swap_tab(
long i) {
79 source = dest = swap_tab;
80 for (a=0; a<swap_size; a++) {
81 if (swap_tab[a] == i) {
85 *(dest++) = *(source++);
92 size = smatrix.
size();
96 swap_tab =
new long[size];
97 for (
long i=0; i<swap_size; i++) swap_tab[i] = i;
101 dist_list_size = size;
103 dist_list_corr = (dist_list_size-2.0)/smatrix.
get_max_value();
106 for (
long i=0; i<size; i++) {
108 for (
long j=0; j<i; j++) {
110 dist_matrix[i][j].
i = i;
111 dist_matrix[i][j].
j = j;
114 for (
long i=0; i<size; i++) {
116 add_taxa_to_dist_list(i);
122 for (
long i=0; i<size; i++)
delete [] dist_matrix[i];
123 delete [] dist_matrix;
125 free(net_divergence);
132 AP_FLOAT maxri = get_max_net_divergence();
139 maxri = maxri*2.0*N_1;
144 for (pos=0; pos<dist_list_size; pos++) {
145 if (minval < pos/dist_list_corr - maxri)
break;
147 dl = dist_list[pos].
next;
148 for (; dl; dl=dl->
next) {
149 x = (net_divergence[dl->
i] + net_divergence[dl->
j])*N_1;
150 if (dl->
val-x<minval) {
167 leftl = dist*.5 + (net_divergence[i] - net_divergence[j])*.5/
169 rightl = dist - leftl;
171 remove_taxa_from_dist_list(j);
172 remove_taxa_from_swap_tab(j);
173 remove_taxa_from_dist_list(i);
177 for (a=0; a<swap_size; a++) {
182 d[k][i].
val = .5*(d[k][i].
val + d[k][j].
val - dji);
185 d[k][i].
val = .5*(d[k][i].
val + d[j][k].
val - dji);
189 d[i][k].
val = 0.5 * (d[i][k].
val + d[j][k].
val - dji);
192 add_taxa_to_dist_list(i);
201 return dist_matrix[j][i].
val;
209 const size_t msize = smatrix.
size();
217 TreeNode **nodes = ARB_calloc<TreeNode*>(msize);
219 for (
size_t i=0; i<msize; i++) {
221 nodes[i]->
name = strdup(names[i]);
225 size_t rest_size = msize;
226 for (
size_t i=2; i<msize && !progress.
aborted(); i++) {
248 if (aborted_flag) *aborted_flag =
true;
301 return all().ofgroup(expected);
304 #define TEST_EXPECT_MIN_IJ(nj,i,j,minval) TEST_EXPECTATION(min_ij_equals(nj,i,j,minval))
306 void TEST_neighbourjoining() {
307 const size_t SIZE = 4;
309 #define TEST_FORWARD_ORDER // @@@ changing the order of nodes here changes the resulting trees
312 #if defined(TEST_FORWARD_ORDER)
313 const char *
names[
SIZE] = {
"A",
"B",
"C",
"D"};
315 #else // !defined(TEST_FORWARD_ORDER)
316 const char *names[
SIZE] = {
"D",
"C",
"B",
"A"};
320 for (
int test = 1; test <= 2; ++test) {
324 for (
size_t i = 0; i <
SIZE; ++i) sym_matrix.set(i, i, 0.0);
326 sym_matrix.set(
A, B, 0.0765); sym_matrix.set(
A,
C, 0.1619); sym_matrix.set(
A,
D, 0.2266);
327 sym_matrix.set(B,
C, 0.1278); sym_matrix.set(B,
D, 0.2061);
330 case 1: sym_matrix.set(
C,
D, 0.1646);
break;
331 case 2: sym_matrix.set(
C,
D, 0.30);
break;
346 #define EXPECTED_MIN_IJ -0.361200
347 #if defined(TEST_FORWARD_ORDER)
348 TEST_EXPECT_MIN_IJ(nj,
A, B, EXPECTED_MIN_IJ);
349 #else // !defined(TEST_FORWARD_ORDER)
350 TEST_EXPECT_MIN_IJ(nj,
D,
C, EXPECTED_MIN_IJ);
352 #undef EXPECTED_MIN_IJ
358 #define EXPECTED_MIN_IJ -0.372250
359 #if defined(TEST_FORWARD_ORDER)
361 TEST_EXPECT_MIN_IJ(nj, B,
C, EXPECTED_MIN_IJ);
362 #else // !defined(ARB_64)
363 TEST_EXPECT_MIN_IJ(nj,
A,
D, EXPECTED_MIN_IJ);
365 #else // !defined(TEST_FORWARD_ORDER)
366 TEST_EXPECT_MIN_IJ(nj,
D,
A, EXPECTED_MIN_IJ);
368 #undef EXPECTED_MIN_IJ
378 #if defined(TEST_FORWARD_ORDER)
382 #else // !defined(ARB_64)
387 #else // !defined(TEST_FORWARD_ORDER)
PH_NEIGHBOURJOINING(const AP_smatrix &smatrix)
#define TEST_EXPECT_SIMILAR(expr, want, epsilon)
TreeRoot * get_tree_root() const
CONSTEXPR_INLINE long sum_of_triangular_numbers(const long L)
AP_FLOAT get_min_ij(long &i, long &j)
TreeNode * neighbourjoining(const char *const *names, const AP_smatrix &smatrix, TreeRoot *troot, bool *aborted_flag)
CONSTEXPR_INLINE long triangular_number(const long N)
#define TEST_PUBLISH(testfunction)
#define TEST_EXPECT_NEWICK(format, tree, expected_newick)
virtual TreeNode * makeNode() const =0
expectation_group & add(const expectation &e)
TYPE * ARB_calloc(size_t nelem)
void get_last_ij(long &i, long &j)
#define fulfills(pred, arg)
AP_FLOAT get_dist(long i, long j)
void join_nodes(long i, long j, AP_FLOAT &leftl, AP_FLOAT &rightlen)
PH_NEIGHBOUR_DIST * previous
void add(PH_NEIGHBOUR_DIST *root)
void destroy(TreeNode *that)
virtual void change_root(TreeNode *old, TreeNode *newroot)
T fast_get(size_t i, size_t j) const