source: tags/initial/GDE/MOLPHY/njmtree.c

Last change on this file was 2, checked in by oldcode, 24 years ago

Initial revision

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.1 KB
Line 
1/*
2 * njmtree.c   Adachi, J.   1995.10.09
3 * Copyright (C) 1992-1995 J. Adachi & M. Hasegawa. All rights reserved.
4 */
5
6#include "protml.h"
7
8
9void 
10initsubplkl(op)
11Node *op;
12{
13        /*      op
14         *     (a)----------(d)...
15         *    iprob <---...
16         */
17        Node *cp;
18
19        if (op->kinp->isop == NULL) { /* external branch */
20                partelkl(op);
21        } else { /* internal branch */
22                /*
23                 *     ( )   op        start  ( )---...
24                 *          (a)----------(d)
25                 *     ( )                    ( )---...
26                 */
27                cp = op->kinp;
28                do {
29                        cp = cp->isop->kinp;
30                        if (cp->isop == NULL) { /* external node */
31                                cp = cp->kinp; /* not descen */
32                                if (Debug) printf("mse %3d\n", cp->num+1);
33                                partelkl(cp);
34                        } else { /* internal node */
35                                if (!cp->descen) {
36                                        if (Debug) printf("msi %3d\n", cp->num+1);
37                                        prodpart(cp->kinp->isop);
38                                        partilkl(cp);
39                                }
40                        }
41                } while (cp != op);
42        }
43} /*_ initsubplkl */
44
45
46void
47mlepartlen(ip, jp, rotup, nr, ns)
48Node *ip, *jp;
49Node **rotup;
50int nr, ns;
51{
52        /* ...(a) - - - - - -      (a)-----(d)...
53         *          (a)-----(d)
54         * ...(a) - - - - - -      (a)-----(d)...
55         * ...(a) - - - - - -
56         */
57        boolean conv;
58        Node *cp, *kp, *xp;
59        int k, l, m, maxm, nconv, nconv2;
60        double lendiff, eps;
61
62        kp = jp->isop;
63        nconv = nconv2 = 0;
64        Numit = 0;
65        Converg = FALSE;
66        for (l = 0; l < MAXIT; l++) { /* MAXIT */
67                Numit++;
68                if (Debug) printf("ml:%3d\n", l);
69                if      (l == 0) eps = 1.0;
70                else if (l == 1) eps = 0.2;
71                else if (l == 2) eps = 0.1;
72                else             eps = EPSILON;
73
74                copypart1(kp, rotup[0]);
75                for (k = 1; k < nr; k++) prodpart1(kp, rotup[k]);
76                jp->isop = kp;
77        /*      kp->isop = ip; */
78                nconv = nconv2 = 0;
79                if (l < 1) maxm = 5; else maxm = 1;
80                for (m = 0; m < maxm; m++) {
81                        conv = TRUE;
82                        cp = kp;
83                        do {
84                                cp = cp->isop->kinp;
85                                if (maxm > 1) {
86                                        m == 0 ? copypart1(kp->kinp, kp) : copypart1(kp, kp->kinp);
87                                }
88                                prodpart(cp->kinp->isop);
89                                if (cp->isop == NULL) { /* external node */
90                                        cp = cp->kinp; /* not descen */
91                                        lendiff = cp->length;
92                                        mlebranch(cp, eps, 5);
93                                        lendiff = fabs(lendiff - cp->length);
94                                        lendiff < EPSILON ? (nconv++)  : (nconv = 0);
95                                        lendiff < 0.1     ? (nconv2++) : (nconv2 = 0);
96                                        if (lendiff > EPSILON) conv = FALSE;
97                                } else { /* internal node */
98                                        if (cp->descen) {
99                                                partilkl(cp);
100                                        } else {
101                                                lendiff = cp->length;
102                                                mlibranch(cp, eps, 5);
103                                                lendiff = fabs(lendiff - cp->length);
104                                                lendiff < EPSILON ? (nconv++)  : (nconv = 0);
105                                                lendiff < 0.1     ? (nconv2++) : (nconv2 = 0);
106                                                if (lendiff > EPSILON) conv = FALSE;
107                                        }
108                                }
109                        } while (cp != jp);
110                        if (conv) break;
111                }
112                if (Debug) putchar('\n');
113                prodpart1(ip, jp);
114                for (k = 0; k < nr; k++) {
115                        xp = rotup[k];
116                /*      xp->isop = ip; */
117                        jp->isop = xp;
118#if 1
119                        lendiff = xp->length;
120                        if (xp->kinp->isop == NULL) { /* external branch */
121                                mlebranch(xp, eps, 5);
122                        } else { /* internal branch */
123                                mlibranch(xp, eps, 5);
124                        }
125                        lendiff = fabs(lendiff - xp->length);
126                        lendiff < EPSILON ? (nconv++)  : (nconv = 0);
127                        lendiff < 0.1     ? (nconv2++) : (nconv2 = 0);
128                        if (lendiff > EPSILON) conv = FALSE;
129#else
130                        cp = jp;
131                        do {
132                                cp = cp->isop->kinp;
133                                if (cp->kinp->isop != ip) prodpart(cp->kinp->isop);
134                                if (cp->isop == NULL) { /* external node */
135                                        cp = cp->kinp; /* not descen */
136                                        lendiff = cp->length;
137                                        mlebranch(cp, eps, 5);
138                                        lendiff = fabs(lendiff - cp->length);
139                                        lendiff < EPSILON ? (nconv++)  : (nconv = 0);
140                                        lendiff < 0.1     ? (nconv2++) : (nconv2 = 0);
141                                        if (lendiff > EPSILON) conv = FALSE;
142                                } else { /* internal node */
143                                        if (cp->descen) {
144                                                partilkl(cp);
145                                        } else {
146                                                lendiff = cp->length;
147                                                mlibranch(cp, eps, 5);
148                                                lendiff = fabs(lendiff - cp->length);
149                                                lendiff < EPSILON ? (nconv++)  : (nconv = 0);
150                                                lendiff < 0.1     ? (nconv2++) : (nconv2 = 0);
151                                                if (lendiff > EPSILON) conv = FALSE;
152                                        }
153                                }
154                        } while (cp != xp);
155#endif
156                }
157                jp->isop = kp;
158                if (nconv >= Numbrnch) goto convergence;
159                if (conv) goto convergence;
160
161        }
162        if (nconv2 >= Numbrnch) Converg = 2;
163        return;
164
165convergence:
166        Converg = TRUE;
167} /*_ mlepartlen */
168
169
170void
171remldmat(dmat, dij, psotu, rotup, otui, otuj, ns)
172dmatrix dmat;
173double dij;
174Node **psotu, **rotup;
175int otui, otuj, ns;
176{
177        int k, nr;
178        double dis;
179        Node *cp, *ip, *jp;
180
181        ip = psotu[otui];
182        jp = psotu[otuj];
183        psotu[otui] = psotu[otuj] = NULL;
184        for (k = 0, nr = 0; k < ns; k++) {
185                cp = psotu[k];
186                if (cp != NULL) {
187                        dis = (dmat[otui][k] + dmat[otuj][k] - dij) * 0.5;
188                        if (dis < Llimit) dis = Llimit;
189                        cp->length = cp->kinp->length = dis;
190                        cp->isop = ip;
191                        initsubplkl(cp);
192                        rotup[nr++] = cp;
193                }
194        }
195        initsubplkl(ip);
196        initsubplkl(jp);
197
198        mlepartlen(ip, jp, rotup, nr, ns);
199
200        for (k = 0; k < ns; k++) {
201                if (psotu[k] != NULL) {
202                        dis = psotu[k]->length;
203                        dmat[otui][k] = dmat[k][otui] = dis;
204                }
205                dmat[otuj][k] = dmat[k][otuj] = 0.0;
206        }
207
208} /* remldmat */
209
210
211void
212njmtree(tr, distan, ns, flag)
213Tree *tr;
214dmatrix distan;
215int ns;
216boolean flag;
217{
218        int i, j, otui, otuj, otuk, nsp2, cinode, step, restsp, nitr;
219        double dij, bix, bjx, bkx, sij, smax, q, dnsp2;
220        dvector r;
221        dmatrix dmat;
222        Node **psotu, **rotup, *cp, *ip, *jp, *kp;
223
224        dmat = new_dmatrix(ns, ns);
225        for (i = 0; i < ns; i++) {
226                for (j = 0; j < ns; j++) dmat[i][j] = distan[i][j];
227        }
228        nitr = 0;
229        nsp2 = ns - 2;
230        dnsp2 = 1.0 / nsp2;
231        cinode = ns;
232        r = new_dvector(ns);
233        psotu = (Node **)new_npvector(ns);
234        rotup = (Node **)new_npvector(ns);
235        for (i = 0; i < ns; i++) psotu[i] = tr->ebrnchp[i]->kinp;
236#if 0
237        if (Debug) {
238                for (i = 0; i < ns; i++) {
239                                printf("%3d", i+1);
240                                for (j = 0; j < ns; j++) printf("%8.3f",dmat[i][j]);
241                                putchar('\n');
242                } putchar('\n');
243        }
244#endif
245        for (step = 0, restsp = ns; restsp > 3; step++) {
246               
247                if (Verbs_optn) fprintf(stderr," %d %d", step+1, restsp);
248
249                for (i = 0, q = 0.0; i < ns; i++) {
250                        if (psotu[i] != NULL) {
251                                for (j = 0, r[i] = 0.0; j < ns; j++) {
252                                        if (psotu[j] != NULL) r[i] += dmat[i][j];
253                                }
254                                q += r[i];
255                        }
256                }
257                for (i = 0, smax = -1.0e300; i < ns-1; i++) {
258                        if (psotu[i] != NULL) {
259                                for (j = i+1; j < ns; j++) {
260                                        if (psotu[j] != NULL) {
261                                                sij = ( r[i] + r[j] ) * dnsp2 - dmat[i][j];
262#if 0
263                                                if (Debug)
264                                                        printf("%3d%3d %9.4f %9.4f %9.4f\n",
265                                                                i+1,j+1,sij,r[i],r[j]);
266#endif
267                                                if (!flag) sij = -sij;
268                                                if (sij > smax) {
269                                                        smax = sij;
270                                                        otui = i;
271                                                        otuj = j;
272                                                }
273                                        }
274                                }
275                        }
276                }
277                dij = dmat[otui][otuj];
278                bix = (dij + r[otui]/nsp2 - r[otuj]/nsp2) * 0.5;
279                bjx = dij - bix;
280                if (bix < Llimit) bix = Llimit;
281                if (bjx < Llimit) bjx = Llimit;
282                ip = psotu[otui];
283                jp = psotu[otuj];
284                ip->length += bix;
285                jp->length += bjx;
286                ip->kinp->length = ip->length;
287                jp->kinp->length = jp->length;
288                cp = tr->ibrnchp[cinode-ns];
289                cp->isop = ip;
290                ip->isop = jp;
291                jp->isop = cp;
292
293                if (Debug)
294                printf ("%3d%3d %9.4f %9.4f %9.4f %9.4f\n", ip->num+1, jp->num+1,
295                        ip->length, jp->length, ip->kinp->length, jp->kinp->length);
296
297                remldmat(dmat, dij, psotu, rotup, otui, otuj, ns);
298                psotu[otui] = cp->kinp;
299                psotu[otuj] = NULL;
300                nitr += Numit;
301#if 0
302                if (Debug) {
303                        putchar('\n');
304                        for (i = 0; i < ns; i++) {
305                                        printf("%3d", i+1);
306                                        for (j = 0; j < ns; j++) printf("%8.3f",dmat[i][j]);
307                                        putchar('\n');
308                        } putchar('\n');
309                }
310#endif
311                cinode++;
312                Numibrnch++;
313                Numbrnch++;
314                Numbrnch = cinode;
315                restsp--;
316                nsp2--;
317                dnsp2 = 1.0 / nsp2;
318                if (Verbs_optn) fprintf(stderr," %d\n", Numit);
319
320        } /* for step restsp */
321
322        otui = otuj = otuk = -1;
323        for (i = 0; i < ns; i++) {
324                if (psotu[i] != NULL) {
325                        if (otui == -1)
326                                otui = i;
327                        else if (otuj == -1)
328                                otuj = i;
329                        else
330                                otuk = i;
331                }
332        }
333        bix = (dmat[otui][otuj] + dmat[otui][otuk] - dmat[otuj][otuk]) * 0.5;
334        bjx = dmat[otui][otuj] - bix;
335        bkx = dmat[otui][otuk] - bix;
336        if (bix < Llimit) bix = Llimit;
337        if (bjx < Llimit) bjx = Llimit;
338        if (bkx < Llimit) bkx = Llimit;
339        ip = psotu[otui];
340        jp = psotu[otuj];
341        kp = psotu[otuk];
342        ip->isop = jp;
343        jp->isop = kp;
344        kp->isop = ip;
345        ip->length += bix;
346        jp->length += bjx;
347        kp->length += bkx;
348        ip->kinp->length = ip->length;
349        jp->kinp->length = jp->length;
350        kp->kinp->length = kp->length;
351
352        reroot(tr, tr->ebrnchp[ns-1]->kinp);
353
354        if (Verbs_optn) fprintf(stderr, "iter: %d\n", nitr);
355
356        free_dvector(r);
357        free_npvector(psotu);
358        free_npvector(rotup);
359        free_dmatrix(dmat);
360} /*_ njmtree */
Note: See TracBrowser for help on using the repository browser.