5 * Part of TREE-PUZZLE 5.0 (June 2000)
7 * (c) 1999-2000 by Heiko A. Schmidt, Korbinian Strimmer,
8 * M. Vingron, and Arndt von Haeseler
9 * (c) 1995-1999 by Korbinian Strimmer and Arndt von Haeseler
11 * All parts of the source except where indicated are distributed under
12 * the GNU public licence. See http://www.opensource.org for details.
19 #ifndef PARALLEL /* because printf() runs significantly faster */
20 /* than fprintf(stdout) on an Apple McIntosh */
22 # define FPRINTF printf
25 # define FPRINTF fprintf
26 # define STDOUTFILE STDOUT,
27 extern int PP_NumProcs;
35 * memory allocation error handler
38 void maerror(char *message)
40 FPRINTF(STDOUTFILE "\n\n\nUnable to proceed (lack of memory: %s)\n\n", message);
41 FPRINTF(STDOUTFILE "Hint for Macintosh users:\n");
42 FPRINTF(STDOUTFILE "Use the <Get Info> command of the Finder to increase the memory partition!\n\n");
48 * memory allocate double vectors, matrices, and cubes
51 dvector new_dvector(int n)
55 v = (dvector) malloc((unsigned) (n * sizeof(double)));
56 if (v == NULL) maerror("step 1 in new_dvector");
61 dmatrix new_dmatrix(int nrow, int ncol)
66 m = (dmatrix) malloc((unsigned) (nrow * sizeof(dvector)));
67 if (m == NULL) maerror("step 1 in in new_dmatrix");
69 *m = (dvector) malloc((unsigned) (nrow * ncol * sizeof(double)));
70 if (*m == NULL) maerror("step 2 in in new_dmatrix");
72 for (i = 1; i < nrow; i++) m[i] = m[i-1] + ncol;
80 dcube new_dcube(int ntri, int nrow, int ncol)
85 c = (dcube) malloc((unsigned) (ntri * sizeof(dmatrix)));
86 if (c == NULL) maerror("step 1 in in new_dcube");
88 *c = (dmatrix) malloc((unsigned) (ntri * nrow * sizeof(dvector)));
89 if (*c == NULL) maerror("step 2 in in new_dcube");
91 **c = (dvector) malloc((unsigned) (ntri * nrow * ncol * sizeof(double)));
92 if (**c == NULL) maerror("step 3 in in new_dcube");
94 for (j = 1; j < nrow; j++) c[0][j] = c[0][j-1] + ncol;
96 for (i = 1; i < ntri; i++) {
98 c[i][0] = c[i-1][0] + nrow * ncol;
99 for (j = 1; j < nrow; j++) c[i][j] = c[i][j-1] + ncol;
105 void free_dvector(dvector v)
110 void free_dmatrix(dmatrix m)
116 void free_dcube(dcube c)
118 free((double *) **c);
125 * memory allocate char vectors, matrices, and cubes
128 cvector new_cvector(int n)
132 v = (cvector) malloc((unsigned)n * sizeof(char));
133 if (v == NULL) maerror("step1 in new_cvector");
138 cmatrix new_cmatrix(int nrow, int ncol)
143 m = (cmatrix) malloc((unsigned) (nrow * sizeof(cvector)));
144 if (m == NULL) maerror("step 1 in new_cmatrix");
146 *m = (cvector) malloc((unsigned) (nrow * ncol * sizeof(char)));
147 if (*m == NULL) maerror("step 2 in new_cmatrix");
149 for (i = 1; i < nrow; i++) m[i] = m[i-1] + ncol;
154 ccube new_ccube(int ntri, int nrow, int ncol)
159 c = (ccube) malloc((unsigned) (ntri * sizeof(cmatrix)));
160 if (c == NULL) maerror("step 1 in new_ccube");
162 *c = (cmatrix) malloc((unsigned) (ntri * nrow * sizeof(cvector)));
163 if (*c == NULL) maerror("step 2 in new_ccube");
165 **c = (cvector) malloc((unsigned) (ntri * nrow * ncol * sizeof(char)));
166 if (**c == NULL) maerror("step 3 in new_ccube");
168 for (j = 1; j < nrow; j++) c[0][j] = c[0][j-1] + ncol;
170 for (i = 1; i < ntri; i++) {
171 c[i] = c[i-1] + nrow;
172 c[i][0] = c[i-1][0] + nrow * ncol;
173 for (j = 1; j < nrow; j++) c[i][j] = c[i][j-1] + ncol;
179 void free_cvector(cvector v)
184 void free_cmatrix(cmatrix m)
190 void free_ccube(ccube c)
199 * memory allocate int vectors, matrices, and cubes
202 ivector new_ivector(int n)
206 v = (ivector) malloc((unsigned) (n * sizeof(int)));
207 if (v == NULL) maerror("step 1 in new_ivector");
212 imatrix new_imatrix(int nrow, int ncol)
217 m = (imatrix) malloc((unsigned) (nrow * sizeof(ivector)));
218 if (m == NULL) maerror("step 1 in new_imatrix");
220 *m = (ivector) malloc((unsigned) (nrow * ncol * sizeof(int)));
221 if (*m == NULL) maerror("step 2 in new_imatrix");
223 for (i = 1; i < nrow; i++) m[i] = m[i-1] + ncol;
228 icube new_icube(int ntri, int nrow, int ncol)
233 c = (icube) malloc((unsigned) (ntri * sizeof(imatrix)));
234 if (c == NULL) maerror("step 1 in new_icube");
236 *c = (imatrix) malloc((unsigned) (ntri * nrow * sizeof(ivector)));
237 if (*c == NULL) maerror("step 2 in new_icube");
239 **c = (ivector) malloc((unsigned) (ntri * nrow * ncol * sizeof(int)));
240 if (**c == NULL) maerror("step 3 in new_icube");
242 for (j = 1; j < nrow; j++) c[0][j] = c[0][j-1] + ncol;
244 for (i = 1; i < ntri; i++) {
245 c[i] = c[i-1] + nrow;
246 c[i][0] = c[i-1][0] + nrow * ncol;
247 for (j = 1; j < nrow; j++) c[i][j] = c[i][j-1] + ncol;
253 void free_ivector(ivector v)
258 void free_imatrix(imatrix m)
264 void free_icube(icube c)
273 * memory allocate uli vectors, matrices, and cubes
276 ulivector new_ulivector(int n)
280 v = (ulivector) malloc((unsigned) (n * sizeof(uli)));
281 if (v == NULL) maerror("step 1 in new_ulivector");
286 ulimatrix new_ulimatrix(int nrow, int ncol)
291 m = (ulimatrix) malloc((unsigned) (nrow * sizeof(ulivector)));
292 if (m == NULL) maerror("step 1 in new_ulimatrix");
294 *m = (ulivector) malloc((unsigned) (nrow * ncol * sizeof(uli)));
295 if (*m == NULL) maerror("step 2 in new_ulimatrix");
297 for (i = 1; i < nrow; i++) m[i] = m[i-1] + ncol;
302 ulicube new_ulicube(int ntri, int nrow, int ncol)
307 c = (ulicube) malloc((unsigned) (ntri * sizeof(ulimatrix)));
308 if (c == NULL) maerror("step 1 in new_ulicube");
310 *c = (ulimatrix) malloc((unsigned) (ntri * nrow * sizeof(ulivector)));
311 if (*c == NULL) maerror("step 2 in new_ulicube");
313 **c = (ulivector) malloc((unsigned) (ntri * nrow * ncol * sizeof(uli)));
314 if (**c == NULL) maerror("step 3 in new_ulicube");
316 for (j = 1; j < nrow; j++) c[0][j] = c[0][j-1] + ncol;
318 for (i = 1; i < ntri; i++) {
319 c[i] = c[i-1] + nrow;
320 c[i][0] = c[i-1][0] + nrow * ncol;
321 for (j = 1; j < nrow; j++) c[i][j] = c[i][j-1] + ncol;
327 void free_ulivector(ulivector v)
332 void free_ulimatrix(ulimatrix m)
338 void free_ulicube(ulicube c)
346 /******************************************************************************/
347 /* random numbers generator (Numerical recipes) */
348 /******************************************************************************/
351 #define IM1 2147483563
352 #define IM2 2147483399
362 #define NDIV (1+IMM1/NTAB)
364 #define RNMX (1.0-EPS)
369 double randomunitintervall()
370 /* Long period (> 2e18) random number generator. Returns a uniform random
371 deviate between 0.0 and 1.0 (exclusive of endpoint values).
374 Press et al., "Numerical recipes in C", Cambridge University Press, 1992
375 (chapter 7 "Random numbers", ran2 random number generator) */
379 static long idum2=123456789;
381 static long iv[NTAB];
390 for (j=NTAB+7;j>=0;j--) {
392 idum=IA1*(idum-k*IQ1)-k*IR1;
401 idum=IA1*(idum-k*IQ1)-k*IR1;
405 idum2=IA2*(idum2-k*IQ2)-k*IR2;
413 if ((temp=AM*iy) > RNMX)
434 int initrandom(int seed)
436 srand((unsigned) time(NULL));
443 for (n=0; n<PP_Myid; n++)
444 (void) randomunitintervall();
446 fprintf(stderr, "(%2d) !!! random seed set to %d, %dx drawn !!!\n", PP_Myid, seed, n);
451 fprintf(stderr, "!!! random seed set to %d !!!\n", seed);
458 /* returns a random integer in the range [0; n - 1] */
459 int randominteger(int n)
462 # ifndef FIXEDINTRAND
464 t = (int) floor(randomunitintervall()*n);
468 for (m=1; m<PP_NumProcs; m++)
469 (void) randomunitintervall();
470 PP_randn+=(m-1); PP_rand++;
471 return (int) floor(randomunitintervall()*n);
474 fprintf(stderr, "!!! fixed \"random\" integers for testing purposes !!!\n");
476 # endif /* FIXEDINTRAND */
479 /* Draw s numbers from the set 0,1,2,..,t-1 and put them
480 into slist (every number can be drawn only one time) */
481 void chooser(int t, int s, ivector slist)
486 isfree = new_ivector(t);
487 for (i = 0; i < t; i++) isfree[i] = TRUE;
488 for (i = 0; i < s; i++) {
489 /* random integer in the range [0, t-1-i] */
490 j = randominteger(t-i);
495 if (isfree[k] == TRUE) l++;
500 free_ivector(isfree);
503 /* a realloc function that works also on non-ANSI compilers */
504 void *myrealloc(void *p, size_t s)
506 if (p == NULL) return malloc(s);
507 else return realloc(p, s);
510 /* safer variant of gets */
511 /* Reads characters from stdin until a newline character or EOF
512 is received. The newline is not made part of the string.
513 If an error occurs a null string \0 is returned */
519 str = new_cvector(100);
523 while (c != '\n' && c != '\r' && n < 99 && c != EOF && !ferror(stdin))
529 if (c == EOF || ferror(stdin))
543 /******************************************************************************/
544 /* minimization of a function by Brents method (Numerical Recipes) */
545 /******************************************************************************/
547 double brent(double, double, double, double (*f )(double ), double, double *, double *, double, double, double);
551 #define CGOLD 0.3819660
552 #define GOLD 1.618034
556 #define SHFT(a,b,c,d) (a)=(b);(b)=(c);(c)=(d);
557 #define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
559 /* Brents method in one dimension */
560 double brent(double ax, double bx, double cx, double (*f)(double), double tol,
561 double *foptx, double *f2optx, double fax, double fbx, double fcx)
564 double a,b,d=0,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm;
568 a=(ax < cx ? ax : cx);
569 b=(ax > cx ? ax : cx);
583 for (iter=1;iter<=ITMAX;iter++) {
585 tol2=2.0*(tol1=tol*fabs(x)+ZEPS);
586 if (fabs(x-xm) <= (tol2-0.5*(b-a))) {
591 *f2optx = 2.0*(fv*xw + fx*wv + fw*vx)/
592 (v*v*xw + x*x*wv + w*w*vx);
595 if (fabs(e) > tol1) {
604 if (fabs(p) >= fabs(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x))
605 d=CGOLD*(e=(x >= xm ? a-x : b-x));
609 if (u-a < tol2 || b-u < tol2)
613 d=CGOLD*(e=(x >= xm ? a-x : b-x));
615 u=(fabs(d) >= tol1 ? x+d : x+SIGN(tol1,d));
618 if (u >= x) a=x; else b=x;
622 if (u < x) a=u; else b=u;
623 if (fu <= fw || w == x) {
628 } else if (fu <= fv || v == x || v == w) {
638 *f2optx = 2.0*(fv*xw + fx*wv + fw*vx)/
639 (v*v*xw + x*x*wv + w*w*vx);
651 /* one-dimensional minimization - as input a lower and an upper limit and a trial
652 value for the minimum is needed: xmin < xguess < xmax
653 the function and a fractional tolerance has to be specified
654 onedimenmin returns the optimal x value and the value of the function
655 and its second derivative at this point
657 double onedimenmin(double xmin, double xguess, double xmax, double (*f)(double),
658 double tol, double *fx, double *f2x)
660 double eps, optx, ax, bx, cx, fa, fb, fc;
662 /* first attempt to bracketize minimum */
663 eps = xguess*tol*50.0;
665 if (ax < xmin) ax = xmin;
668 if (cx > xmax) cx = xmax;
670 /* check if this works */
675 /* if it works use these borders else be conservative */
676 if ((fa < fb) || (fc < fb)) {
677 if (ax != xmin) fa = (*f)(xmin);
678 if (cx != xmax) fc = (*f)(xmax);
679 optx = brent(xmin, xguess, xmax, f, tol, fx, f2x, fa, fb, fc);
681 optx = brent(ax, bx, cx, f, tol, fx, f2x, fa, fb, fc);
683 return optx; /* return optimal x */
686 /* two-dimensional minimization with borders and calculations of standard errors */
687 /* we optimize along basis vectors - not very optimal but it seems to work well */
688 void twodimenmin(double tol,
689 int active1, double min1, double *x1, double max1, double (*func1)(double), double *err1,
690 int active2, double min2, double *x2, double max2, double (*func2)(double), double *err2)
692 int it, nump, change;
699 /* count number of parameters */
703 do { /* repeat until nothing changes any more */
707 /* optimize first variable */
710 if ((*x1) <= min1) (*x1) = min1 + 0.2*(max1-min1);
711 if ((*x1) >= max1) (*x1) = max1 - 0.2*(max1-min1);
713 (*x1) = onedimenmin(min1, (*x1), max1, func1, tol, &fx, &f2x);
714 if ((*x1) < min1) (*x1) = min1;
715 if ((*x1) > max1) (*x1) = max1;
716 /* same tolerance as 1D minimization */
717 if (fabs((*x1) - x1old) > 3.3*tol) change = TRUE;
721 if (1.0/(max1*max1) < f2x) (*err1) = sqrt(1.0/f2x);
726 /* optimize second variable */
729 if ((*x2) <= min2) (*x2) = min2 + 0.2*(max2-min2);
730 if ((*x2) >= max2) (*x2) = max2 - 0.2*(max2-min2);
732 (*x2) = onedimenmin(min2, (*x2), max2, func2, tol, &fx, &f2x);
733 if ((*x2) < min2) (*x2) = min2;
734 if ((*x2) > max2) (*x2) = max2;
735 /* same tolerance as 1D minimization */
736 if (fabs((*x2) - x2old) > 3.3*tol) change = TRUE;
740 if (1.0/(max2*max2) < f2x) (*err2) = sqrt(1.0/f2x);
745 if (nump == 1) return;
747 } while (it != MAXITS && change);