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;
77 dcube new_dcube(int ntri, int nrow, int ncol)
82 c = (dcube) malloc((unsigned) (ntri * sizeof(dmatrix)));
83 if (c == NULL) maerror("step 1 in in new_dcube");
85 *c = (dmatrix) malloc((unsigned) (ntri * nrow * sizeof(dvector)));
86 if (*c == NULL) maerror("step 2 in in new_dcube");
88 **c = (dvector) malloc((unsigned) (ntri * nrow * ncol * sizeof(double)));
89 if (**c == NULL) maerror("step 3 in in new_dcube");
91 for (j = 1; j < nrow; j++) c[0][j] = c[0][j-1] + ncol;
93 for (i = 1; i < ntri; i++) {
95 c[i][0] = c[i-1][0] + nrow * ncol;
96 for (j = 1; j < nrow; j++) c[i][j] = c[i][j-1] + ncol;
102 void free_dvector(dvector v)
107 void free_dmatrix(dmatrix m)
113 void free_dcube(dcube c)
115 free((double *) **c);
122 * memory allocate char vectors, matrices, and cubes
125 cvector new_cvector(int n)
129 v = (cvector) malloc((unsigned)n * sizeof(char));
130 if (v == NULL) maerror("step1 in new_cvector");
135 cmatrix new_cmatrix(int nrow, int ncol)
140 m = (cmatrix) malloc((unsigned) (nrow * sizeof(cvector)));
141 if (m == NULL) maerror("step 1 in new_cmatrix");
143 *m = (cvector) malloc((unsigned) (nrow * ncol * sizeof(char)));
144 if (*m == NULL) maerror("step 2 in new_cmatrix");
146 for (i = 1; i < nrow; i++) m[i] = m[i-1] + ncol;
151 ccube new_ccube(int ntri, int nrow, int ncol)
156 c = (ccube) malloc((unsigned) (ntri * sizeof(cmatrix)));
157 if (c == NULL) maerror("step 1 in new_ccube");
159 *c = (cmatrix) malloc((unsigned) (ntri * nrow * sizeof(cvector)));
160 if (*c == NULL) maerror("step 2 in new_ccube");
162 **c = (cvector) malloc((unsigned) (ntri * nrow * ncol * sizeof(char)));
163 if (**c == NULL) maerror("step 3 in new_ccube");
165 for (j = 1; j < nrow; j++) c[0][j] = c[0][j-1] + ncol;
167 for (i = 1; i < ntri; i++) {
168 c[i] = c[i-1] + nrow;
169 c[i][0] = c[i-1][0] + nrow * ncol;
170 for (j = 1; j < nrow; j++) c[i][j] = c[i][j-1] + ncol;
176 void free_cvector(cvector v)
181 void free_cmatrix(cmatrix m)
187 void free_ccube(ccube c)
196 * memory allocate int vectors, matrices, and cubes
199 ivector new_ivector(int n)
203 v = (ivector) malloc((unsigned) (n * sizeof(int)));
204 if (v == NULL) maerror("step 1 in new_ivector");
209 imatrix new_imatrix(int nrow, int ncol)
214 m = (imatrix) malloc((unsigned) (nrow * sizeof(ivector)));
215 if (m == NULL) maerror("step 1 in new_imatrix");
217 *m = (ivector) malloc((unsigned) (nrow * ncol * sizeof(int)));
218 if (*m == NULL) maerror("step 2 in new_imatrix");
220 for (i = 1; i < nrow; i++) m[i] = m[i-1] + ncol;
225 icube new_icube(int ntri, int nrow, int ncol)
230 c = (icube) malloc((unsigned) (ntri * sizeof(imatrix)));
231 if (c == NULL) maerror("step 1 in new_icube");
233 *c = (imatrix) malloc((unsigned) (ntri * nrow * sizeof(ivector)));
234 if (*c == NULL) maerror("step 2 in new_icube");
236 **c = (ivector) malloc((unsigned) (ntri * nrow * ncol * sizeof(int)));
237 if (**c == NULL) maerror("step 3 in new_icube");
239 for (j = 1; j < nrow; j++) c[0][j] = c[0][j-1] + ncol;
241 for (i = 1; i < ntri; i++) {
242 c[i] = c[i-1] + nrow;
243 c[i][0] = c[i-1][0] + nrow * ncol;
244 for (j = 1; j < nrow; j++) c[i][j] = c[i][j-1] + ncol;
250 void free_ivector(ivector v)
255 void free_imatrix(imatrix m)
261 void free_icube(icube c)
270 * memory allocate uli vectors, matrices, and cubes
273 ulivector new_ulivector(int n)
277 v = (ulivector) malloc((unsigned) (n * sizeof(uli)));
278 if (v == NULL) maerror("step 1 in new_ulivector");
283 ulimatrix new_ulimatrix(int nrow, int ncol)
288 m = (ulimatrix) malloc((unsigned) (nrow * sizeof(ulivector)));
289 if (m == NULL) maerror("step 1 in new_ulimatrix");
291 *m = (ulivector) malloc((unsigned) (nrow * ncol * sizeof(uli)));
292 if (*m == NULL) maerror("step 2 in new_ulimatrix");
294 for (i = 1; i < nrow; i++) m[i] = m[i-1] + ncol;
299 ulicube new_ulicube(int ntri, int nrow, int ncol)
304 c = (ulicube) malloc((unsigned) (ntri * sizeof(ulimatrix)));
305 if (c == NULL) maerror("step 1 in new_ulicube");
307 *c = (ulimatrix) malloc((unsigned) (ntri * nrow * sizeof(ulivector)));
308 if (*c == NULL) maerror("step 2 in new_ulicube");
310 **c = (ulivector) malloc((unsigned) (ntri * nrow * ncol * sizeof(uli)));
311 if (**c == NULL) maerror("step 3 in new_ulicube");
313 for (j = 1; j < nrow; j++) c[0][j] = c[0][j-1] + ncol;
315 for (i = 1; i < ntri; i++) {
316 c[i] = c[i-1] + nrow;
317 c[i][0] = c[i-1][0] + nrow * ncol;
318 for (j = 1; j < nrow; j++) c[i][j] = c[i][j-1] + ncol;
324 void free_ulivector(ulivector v)
329 void free_ulimatrix(ulimatrix m)
335 void free_ulicube(ulicube c)
343 /******************************************************************************/
344 /* random numbers generator (Numerical recipes) */
345 /******************************************************************************/
348 #define IM1 2147483563
349 #define IM2 2147483399
359 #define NDIV (1+IMM1/NTAB)
361 #define RNMX (1.0-EPS)
366 double randomunitintervall()
367 /* Long period (> 2e18) random number generator. Returns a uniform random
368 deviate between 0.0 and 1.0 (exclusive of endpoint values).
371 Press et al., "Numerical recipes in C", Cambridge University Press, 1992
372 (chapter 7 "Random numbers", ran2 random number generator) */
376 static long idum2=123456789;
378 static long iv[NTAB];
387 for (j=NTAB+7;j>=0;j--) {
389 idum=IA1*(idum-k*IQ1)-k*IR1;
398 idum=IA1*(idum-k*IQ1)-k*IR1;
402 idum2=IA2*(idum2-k*IQ2)-k*IR2;
410 if ((temp=AM*iy) > RNMX)
431 int initrandom(int seed)
433 srand((unsigned) time(NULL));
440 for (n=0; n<PP_Myid; n++)
441 (void) randomunitintervall();
443 fprintf(stderr, "(%2d) !!! random seed set to %d, %dx drawn !!!\n", PP_Myid, seed, n);
448 fprintf(stderr, "!!! random seed set to %d !!!\n", seed);
455 /* returns a random integer in the range [0; n - 1] */
456 int randominteger(int n)
459 # ifndef FIXEDINTRAND
461 t = (int) floor(randomunitintervall()*n);
465 for (m=1; m<PP_NumProcs; m++)
466 (void) randomunitintervall();
467 PP_randn+=(m-1); PP_rand++;
468 return (int) floor(randomunitintervall()*n);
471 fprintf(stderr, "!!! fixed \"random\" integers for testing purposes !!!\n");
473 # endif /* FIXEDINTRAND */
476 /* Draw s numbers from the set 0,1,2,..,t-1 and put them
477 into slist (every number can be drawn only one time) */
478 void chooser(int t, int s, ivector slist)
483 isfree = new_ivector(t);
484 for (i = 0; i < t; i++) isfree[i] = TRUE;
485 for (i = 0; i < s; i++) {
486 /* random integer in the range [0, t-1-i] */
487 j = randominteger(t-i);
492 if (isfree[k] == TRUE) l++;
497 free_ivector(isfree);
500 /* a realloc function that works also on non-ANSI compilers */
501 void *myrealloc(void *p, size_t s)
503 if (p == NULL) return malloc(s);
504 else return realloc(p, s);
507 /* safer variant of gets */
508 /* Reads characters from stdin until a newline character or EOF
509 is received. The newline is not made part of the string.
510 If an error occurs a null string \0 is returned */
516 str = new_cvector(100);
520 while (c != '\n' && c != '\r' && n < 99 && c != EOF && !ferror(stdin))
526 if (c == EOF || ferror(stdin))
540 /******************************************************************************/
541 /* minimization of a function by Brents method (Numerical Recipes) */
542 /******************************************************************************/
544 double brent(double, double, double, double (*f )(double ), double, double *, double *, double, double, double);
548 #define CGOLD 0.3819660
549 #define GOLD 1.618034
553 #define SHFT(a,b,c,d) (a)=(b);(b)=(c);(c)=(d);
554 #define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
556 /* Brents method in one dimension */
557 double brent(double ax, double bx, double cx, double (*f)(double), double tol,
558 double *foptx, double *f2optx, double fax, double fbx, double fcx)
561 double a,b,d=0,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm;
565 a=(ax < cx ? ax : cx);
566 b=(ax > cx ? ax : cx);
580 for (iter=1;iter<=ITMAX;iter++) {
582 tol2=2.0*(tol1=tol*fabs(x)+ZEPS);
583 if (fabs(x-xm) <= (tol2-0.5*(b-a))) {
588 *f2optx = 2.0*(fv*xw + fx*wv + fw*vx)/
589 (v*v*xw + x*x*wv + w*w*vx);
592 if (fabs(e) > tol1) {
601 if (fabs(p) >= fabs(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x))
602 d=CGOLD*(e=(x >= xm ? a-x : b-x));
606 if (u-a < tol2 || b-u < tol2)
610 d=CGOLD*(e=(x >= xm ? a-x : b-x));
612 u=(fabs(d) >= tol1 ? x+d : x+SIGN(tol1,d));
615 if (u >= x) a=x; else b=x;
619 if (u < x) a=u; else b=u;
620 if (fu <= fw || w == x) {
625 } else if (fu <= fv || v == x || v == w) {
635 *f2optx = 2.0*(fv*xw + fx*wv + fw*vx)/
636 (v*v*xw + x*x*wv + w*w*vx);
648 /* one-dimensional minimization - as input a lower and an upper limit and a trial
649 value for the minimum is needed: xmin < xguess < xmax
650 the function and a fractional tolerance has to be specified
651 onedimenmin returns the optimal x value and the value of the function
652 and its second derivative at this point
654 double onedimenmin(double xmin, double xguess, double xmax, double (*f)(double),
655 double tol, double *fx, double *f2x)
657 double eps, optx, ax, bx, cx, fa, fb, fc;
659 /* first attempt to bracketize minimum */
660 eps = xguess*tol*50.0;
662 if (ax < xmin) ax = xmin;
665 if (cx > xmax) cx = xmax;
667 /* check if this works */
672 /* if it works use these borders else be conservative */
673 if ((fa < fb) || (fc < fb)) {
674 if (ax != xmin) fa = (*f)(xmin);
675 if (cx != xmax) fc = (*f)(xmax);
676 optx = brent(xmin, xguess, xmax, f, tol, fx, f2x, fa, fb, fc);
678 optx = brent(ax, bx, cx, f, tol, fx, f2x, fa, fb, fc);
680 return optx; /* return optimal x */
683 /* two-dimensional minimization with borders and calculations of standard errors */
684 /* we optimize along basis vectors - not very optimal but it seems to work well */
685 void twodimenmin(double tol,
686 int active1, double min1, double *x1, double max1, double (*func1)(double), double *err1,
687 int active2, double min2, double *x2, double max2, double (*func2)(double), double *err2)
689 int it, nump, change;
696 /* count number of parameters */
700 do { /* repeat until nothing changes any more */
704 /* optimize first variable */
707 if ((*x1) <= min1) (*x1) = min1 + 0.2*(max1-min1);
708 if ((*x1) >= max1) (*x1) = max1 - 0.2*(max1-min1);
710 (*x1) = onedimenmin(min1, (*x1), max1, func1, tol, &fx, &f2x);
711 if ((*x1) < min1) (*x1) = min1;
712 if ((*x1) > max1) (*x1) = max1;
713 /* same tolerance as 1D minimization */
714 if (fabs((*x1) - x1old) > 3.3*tol) change = TRUE;
718 if (1.0/(max1*max1) < f2x) (*err1) = sqrt(1.0/f2x);
723 /* optimize second variable */
726 if ((*x2) <= min2) (*x2) = min2 + 0.2*(max2-min2);
727 if ((*x2) >= max2) (*x2) = max2 - 0.2*(max2-min2);
729 (*x2) = onedimenmin(min2, (*x2), max2, func2, tol, &fx, &f2x);
730 if ((*x2) < min2) (*x2) = min2;
731 if ((*x2) > max2) (*x2) = max2;
732 /* same tolerance as 1D minimization */
733 if (fabs((*x2) - x2old) > 3.3*tol) change = TRUE;
737 if (1.0/(max2*max2) < f2x) (*err2) = sqrt(1.0/f2x);
742 if (nump == 1) return;
744 } while (it != MAXITS && change);