Update to 2.0.0 tree from current Fremantle build
[opencv] / 3rdparty / lapack / dlamch.c
1 #include "clapack.h"
2 #include <float.h>
3 #include <stdio.h>
4
5 /* *********************************************************************** */
6
7 doublereal dlamc3_(doublereal *a, doublereal *b)
8 {
9     /* System generated locals */
10     doublereal ret_val;
11     
12     
13     /*  -- LAPACK auxiliary routine (version 3.1) -- */
14     /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
15     /*     November 2006 */
16     
17     /*     .. Scalar Arguments .. */
18     /*     .. */
19     
20     /*  Purpose */
21     /*  ======= */
22     
23     /*  DLAMC3  is intended to force  A  and  B  to be stored prior to doing */
24     /*  the addition of  A  and  B ,  for use in situations where optimizers */
25     /*  might hold one of these in a register. */
26     
27     /*  Arguments */
28     /*  ========= */
29     
30     /*  A       (input) DOUBLE PRECISION */
31     /*  B       (input) DOUBLE PRECISION */
32     /*          The values A and B. */
33     
34     /* ===================================================================== */
35     
36     /*     .. Executable Statements .. */
37     
38     ret_val = *a + *b;
39     
40     return ret_val;
41     
42     /*     End of DLAMC3 */
43     
44 } /* dlamc3_ */
45
46
47 #if 1
48
49 /* simpler version of dlamch for the case of IEEE754-compliant FPU module by Piotr Luszczek S.
50    taken from http://www.mail-archive.com/numpy-discussion@lists.sourceforge.net/msg02448.html */
51
52 #ifndef DBL_DIGITS
53 #define DBL_DIGITS 53
54 #endif
55
56 doublereal
57 dlamch_(char *cmach) {
58     char ch = cmach[0];
59     double eps = DBL_EPSILON*0.5, sfmin, small;
60     
61     if ('B' == ch || 'b' == ch) {
62         return FLT_RADIX;
63     } else if ('E' == ch || 'e' == ch) {
64         return eps;
65     } else if ('L' == ch || 'l' == ch) {
66         return DBL_MAX_EXP;
67     } else if ('M' == ch || 'm' == ch) {
68         return DBL_MIN_EXP;
69     } else if ('N' == ch || 'n' == ch) {
70         return DBL_DIGITS;
71     } else if ('O' == ch || 'o' == ch) {
72         return DBL_MAX;
73     } else if ('P' == ch || 'p' == ch) {
74         return eps * FLT_RADIX;
75     } else if ('R' == ch || 'r' == ch) {
76         return FLT_ROUNDS < 2;
77     } else if ('S' == ch || 's' == ch) {
78         /* Use SMALL plus a bit, to avoid the possibility of rounding causing overflow
79          when computing  1/sfmin. */
80         sfmin = DBL_MIN;
81         small = 2. / DBL_MAX;
82         if (small <= sfmin) small = sfmin * (1 + eps);
83         return small;
84     } else if ('U' == ch || 'u' == ch) {
85         return DBL_MIN;
86     }
87     
88     return 0;
89 }
90
91 #else
92
93 /* Table of constant values */
94
95 static integer c__1 = 1;
96 static doublereal c_b32 = 0.;
97
98 doublereal dlamch_(char *cmach)
99 {
100     /* Initialized data */
101
102     static logical first = TRUE_;
103
104     /* System generated locals */
105     integer i__1;
106     doublereal ret_val;
107
108     /* Builtin functions */
109     double pow_di(doublereal *, integer *);
110
111     /* Local variables */
112     static doublereal t;
113     integer it;
114     static doublereal rnd, eps, base;
115     integer beta;
116     static doublereal emin, prec, emax;
117     integer imin, imax;
118     logical lrnd;
119     static doublereal rmin, rmax;
120     doublereal rmach;
121     extern logical lsame_(char *, char *);
122     doublereal small;
123     static doublereal sfmin;
124     extern /* Subroutine */ int dlamc2_(integer *, integer *, logical *, 
125             doublereal *, integer *, doublereal *, integer *, doublereal *);
126
127
128 /*  -- LAPACK auxiliary routine (version 3.1) -- */
129 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
130 /*     November 2006 */
131
132 /*     .. Scalar Arguments .. */
133 /*     .. */
134
135 /*  Purpose */
136 /*  ======= */
137
138 /*  DLAMCH determines double precision machine parameters. */
139
140 /*  Arguments */
141 /*  ========= */
142
143 /*  CMACH   (input) CHARACTER*1 */
144 /*          Specifies the value to be returned by DLAMCH: */
145 /*          = 'E' or 'e',   DLAMCH := eps */
146 /*          = 'S' or 's ,   DLAMCH := sfmin */
147 /*          = 'B' or 'b',   DLAMCH := base */
148 /*          = 'P' or 'p',   DLAMCH := eps*base */
149 /*          = 'N' or 'n',   DLAMCH := t */
150 /*          = 'R' or 'r',   DLAMCH := rnd */
151 /*          = 'M' or 'm',   DLAMCH := emin */
152 /*          = 'U' or 'u',   DLAMCH := rmin */
153 /*          = 'L' or 'l',   DLAMCH := emax */
154 /*          = 'O' or 'o',   DLAMCH := rmax */
155
156 /*          where */
157
158 /*          eps   = relative machine precision */
159 /*          sfmin = safe minimum, such that 1/sfmin does not overflow */
160 /*          base  = base of the machine */
161 /*          prec  = eps*base */
162 /*          t     = number of (base) digits in the mantissa */
163 /*          rnd   = 1.0 when rounding occurs in addition, 0.0 otherwise */
164 /*          emin  = minimum exponent before (gradual) underflow */
165 /*          rmin  = underflow threshold - base**(emin-1) */
166 /*          emax  = largest exponent before overflow */
167 /*          rmax  = overflow threshold  - (base**emax)*(1-eps) */
168
169 /* ===================================================================== */
170
171 /*     .. Parameters .. */
172 /*     .. */
173 /*     .. Local Scalars .. */
174 /*     .. */
175 /*     .. External Functions .. */
176 /*     .. */
177 /*     .. External Subroutines .. */
178 /*     .. */
179 /*     .. Save statement .. */
180 /*     .. */
181 /*     .. Data statements .. */
182 /*     .. */
183 /*     .. Executable Statements .. */
184
185     if (first) {
186         dlamc2_(&beta, &it, &lrnd, &eps, &imin, &rmin, &imax, &rmax);
187         base = (doublereal) beta;
188         t = (doublereal) it;
189         if (lrnd) {
190             rnd = 1.;
191             i__1 = 1 - it;
192             eps = pow_di(&base, &i__1) / 2;
193         } else {
194             rnd = 0.;
195             i__1 = 1 - it;
196             eps = pow_di(&base, &i__1);
197         }
198         prec = eps * base;
199         emin = (doublereal) imin;
200         emax = (doublereal) imax;
201         sfmin = rmin;
202         small = 1. / rmax;
203         if (small >= sfmin) {
204
205 /*           Use SMALL plus a bit, to avoid the possibility of rounding */
206 /*           causing overflow when computing  1/sfmin. */
207
208             sfmin = small * (eps + 1.);
209         }
210     }
211
212     if (lsame_(cmach, "E")) {
213         rmach = eps;
214     } else if (lsame_(cmach, "S")) {
215         rmach = sfmin;
216     } else if (lsame_(cmach, "B")) {
217         rmach = base;
218     } else if (lsame_(cmach, "P")) {
219         rmach = prec;
220     } else if (lsame_(cmach, "N")) {
221         rmach = t;
222     } else if (lsame_(cmach, "R")) {
223         rmach = rnd;
224     } else if (lsame_(cmach, "M")) {
225         rmach = emin;
226     } else if (lsame_(cmach, "U")) {
227         rmach = rmin;
228     } else if (lsame_(cmach, "L")) {
229         rmach = emax;
230     } else if (lsame_(cmach, "O")) {
231         rmach = rmax;
232     }
233
234     ret_val = rmach;
235     first = FALSE_;
236     return ret_val;
237
238 /*     End of DLAMCH */
239
240 } /* dlamch_ */
241
242
243 /* *********************************************************************** */
244
245 /* Subroutine */ int dlamc1_(integer *beta, integer *t, logical *rnd, logical 
246         *ieee1)
247 {
248     /* Initialized data */
249
250     static logical first = TRUE_;
251
252     /* System generated locals */
253     doublereal d__1, d__2;
254
255     /* Local variables */
256     doublereal a, b, c__, f, t1, t2;
257     static integer lt;
258     doublereal one, qtr;
259     static logical lrnd;
260     static integer lbeta;
261     doublereal savec;
262     extern doublereal dlamc3_(doublereal *, doublereal *);
263     static logical lieee1;
264
265
266 /*  -- LAPACK auxiliary routine (version 3.1) -- */
267 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
268 /*     November 2006 */
269
270 /*     .. Scalar Arguments .. */
271 /*     .. */
272
273 /*  Purpose */
274 /*  ======= */
275
276 /*  DLAMC1 determines the machine parameters given by BETA, T, RND, and */
277 /*  IEEE1. */
278
279 /*  Arguments */
280 /*  ========= */
281
282 /*  BETA    (output) INTEGER */
283 /*          The base of the machine. */
284
285 /*  T       (output) INTEGER */
286 /*          The number of ( BETA ) digits in the mantissa. */
287
288 /*  RND     (output) LOGICAL */
289 /*          Specifies whether proper rounding  ( RND = .TRUE. )  or */
290 /*          chopping  ( RND = .FALSE. )  occurs in addition. This may not */
291 /*          be a reliable guide to the way in which the machine performs */
292 /*          its arithmetic. */
293
294 /*  IEEE1   (output) LOGICAL */
295 /*          Specifies whether rounding appears to be done in the IEEE */
296 /*          'round to nearest' style. */
297
298 /*  Further Details */
299 /*  =============== */
300
301 /*  The routine is based on the routine  ENVRON  by Malcolm and */
302 /*  incorporates suggestions by Gentleman and Marovich. See */
303
304 /*     Malcolm M. A. (1972) Algorithms to reveal properties of */
305 /*        floating-point arithmetic. Comms. of the ACM, 15, 949-951. */
306
307 /*     Gentleman W. M. and Marovich S. B. (1974) More on algorithms */
308 /*        that reveal properties of floating point arithmetic units. */
309 /*        Comms. of the ACM, 17, 276-277. */
310
311 /* ===================================================================== */
312
313 /*     .. Local Scalars .. */
314 /*     .. */
315 /*     .. External Functions .. */
316 /*     .. */
317 /*     .. Save statement .. */
318 /*     .. */
319 /*     .. Data statements .. */
320 /*     .. */
321 /*     .. Executable Statements .. */
322
323     if (first) {
324         one = 1.;
325
326 /*        LBETA,  LIEEE1,  LT and  LRND  are the  local values  of  BETA, */
327 /*        IEEE1, T and RND. */
328
329 /*        Throughout this routine  we use the function  DLAMC3  to ensure */
330 /*        that relevant values are  stored and not held in registers,  or */
331 /*        are not affected by optimizers. */
332
333 /*        Compute  a = 2.0**m  with the  smallest positive integer m such */
334 /*        that */
335
336 /*           fl( a + 1.0 ) = a. */
337
338         a = 1.;
339         c__ = 1.;
340
341 /* +       WHILE( C.EQ.ONE )LOOP */
342 L10:
343         if (c__ == one) {
344             a *= 2;
345             c__ = dlamc3_(&a, &one);
346             d__1 = -a;
347             c__ = dlamc3_(&c__, &d__1);
348             goto L10;
349         }
350 /* +       END WHILE */
351
352 /*        Now compute  b = 2.0**m  with the smallest positive integer m */
353 /*        such that */
354
355 /*           fl( a + b ) .gt. a. */
356
357         b = 1.;
358         c__ = dlamc3_(&a, &b);
359
360 /* +       WHILE( C.EQ.A )LOOP */
361 L20:
362         if (c__ == a) {
363             b *= 2;
364             c__ = dlamc3_(&a, &b);
365             goto L20;
366         }
367 /* +       END WHILE */
368
369 /*        Now compute the base.  a and c  are neighbouring floating point */
370 /*        numbers  in the  interval  ( beta**t, beta**( t + 1 ) )  and so */
371 /*        their difference is beta. Adding 0.25 to c is to ensure that it */
372 /*        is truncated to beta and not ( beta - 1 ). */
373
374         qtr = one / 4;
375         savec = c__;
376         d__1 = -a;
377         c__ = dlamc3_(&c__, &d__1);
378         lbeta = (integer) (c__ + qtr);
379
380 /*        Now determine whether rounding or chopping occurs,  by adding a */
381 /*        bit  less  than  beta/2  and a  bit  more  than  beta/2  to  a. */
382
383         b = (doublereal) lbeta;
384         d__1 = b / 2;
385         d__2 = -b / 100;
386         f = dlamc3_(&d__1, &d__2);
387         c__ = dlamc3_(&f, &a);
388         if (c__ == a) {
389             lrnd = TRUE_;
390         } else {
391             lrnd = FALSE_;
392         }
393         d__1 = b / 2;
394         d__2 = b / 100;
395         f = dlamc3_(&d__1, &d__2);
396         c__ = dlamc3_(&f, &a);
397         if (lrnd && c__ == a) {
398             lrnd = FALSE_;
399         }
400
401 /*        Try and decide whether rounding is done in the  IEEE  'round to */
402 /*        nearest' style. B/2 is half a unit in the last place of the two */
403 /*        numbers A and SAVEC. Furthermore, A is even, i.e. has last  bit */
404 /*        zero, and SAVEC is odd. Thus adding B/2 to A should not  change */
405 /*        A, but adding B/2 to SAVEC should change SAVEC. */
406
407         d__1 = b / 2;
408         t1 = dlamc3_(&d__1, &a);
409         d__1 = b / 2;
410         t2 = dlamc3_(&d__1, &savec);
411         lieee1 = t1 == a && t2 > savec && lrnd;
412
413 /*        Now find  the  mantissa, t.  It should  be the  integer part of */
414 /*        log to the base beta of a,  however it is safer to determine  t */
415 /*        by powering.  So we find t as the smallest positive integer for */
416 /*        which */
417
418 /*           fl( beta**t + 1.0 ) = 1.0. */
419
420         lt = 0;
421         a = 1.;
422         c__ = 1.;
423
424 /* +       WHILE( C.EQ.ONE )LOOP */
425 L30:
426         if (c__ == one) {
427             ++lt;
428             a *= lbeta;
429             c__ = dlamc3_(&a, &one);
430             d__1 = -a;
431             c__ = dlamc3_(&c__, &d__1);
432             goto L30;
433         }
434 /* +       END WHILE */
435
436     }
437
438     *beta = lbeta;
439     *t = lt;
440     *rnd = lrnd;
441     *ieee1 = lieee1;
442     first = FALSE_;
443     return 0;
444
445 /*     End of DLAMC1 */
446
447 } /* dlamc1_ */
448
449
450 /* *********************************************************************** */
451
452 /* Subroutine */ int dlamc2_(integer *beta, integer *t, logical *rnd, 
453         doublereal *eps, integer *emin, doublereal *rmin, integer *emax, 
454         doublereal *rmax)
455 {
456     /* Initialized data */
457
458     static logical first = TRUE_;
459     static logical iwarn = FALSE_;
460
461     /* Format strings */
462     static char fmt_9999[] = "(//\002 WARNING. The value EMIN may be incorre"
463             "ct:-\002,\002  EMIN = \002,i8,/\002 If, after inspection, the va"
464             "lue EMIN looks\002,\002 acceptable please comment out \002,/\002"
465             " the IF block as marked within the code of routine\002,\002 DLAM"
466             "C2,\002,/\002 otherwise supply EMIN explicitly.\002,/)";
467
468     /* System generated locals */
469     integer i__1;
470     doublereal d__1, d__2, d__3, d__4, d__5;
471
472     /* Builtin functions */
473     double pow_di(doublereal *, integer *);
474     //integer s_wsfe(cilist *), do_fio(integer *, char *, ftnlen), e_wsfe(void);
475
476     /* Local variables */
477     doublereal a, b, c__;
478     integer i__;
479     static integer lt;
480     doublereal one, two;
481     logical ieee;
482     doublereal half;
483     logical lrnd;
484     static doublereal leps;
485     doublereal zero;
486     static integer lbeta;
487     doublereal rbase;
488     static integer lemin, lemax;
489     integer gnmin;
490     doublereal small;
491     integer gpmin;
492     doublereal third;
493     static doublereal lrmin, lrmax;
494     doublereal sixth;
495     extern /* Subroutine */ int dlamc1_(integer *, integer *, logical *, 
496             logical *);
497     extern doublereal dlamc3_(doublereal *, doublereal *);
498     logical lieee1;
499     extern /* Subroutine */ int dlamc4_(integer *, doublereal *, integer *), 
500             dlamc5_(integer *, integer *, integer *, logical *, integer *, 
501             doublereal *);
502     integer ngnmin, ngpmin;
503
504     /* Fortran I/O blocks */
505     static cilist io___58 = { 0, 6, 0, fmt_9999, 0 };
506
507
508
509 /*  -- LAPACK auxiliary routine (version 3.1) -- */
510 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
511 /*     November 2006 */
512
513 /*     .. Scalar Arguments .. */
514 /*     .. */
515
516 /*  Purpose */
517 /*  ======= */
518
519 /*  DLAMC2 determines the machine parameters specified in its argument */
520 /*  list. */
521
522 /*  Arguments */
523 /*  ========= */
524
525 /*  BETA    (output) INTEGER */
526 /*          The base of the machine. */
527
528 /*  T       (output) INTEGER */
529 /*          The number of ( BETA ) digits in the mantissa. */
530
531 /*  RND     (output) LOGICAL */
532 /*          Specifies whether proper rounding  ( RND = .TRUE. )  or */
533 /*          chopping  ( RND = .FALSE. )  occurs in addition. This may not */
534 /*          be a reliable guide to the way in which the machine performs */
535 /*          its arithmetic. */
536
537 /*  EPS     (output) DOUBLE PRECISION */
538 /*          The smallest positive number such that */
539
540 /*             fl( 1.0 - EPS ) .LT. 1.0, */
541
542 /*          where fl denotes the computed value. */
543
544 /*  EMIN    (output) INTEGER */
545 /*          The minimum exponent before (gradual) underflow occurs. */
546
547 /*  RMIN    (output) DOUBLE PRECISION */
548 /*          The smallest normalized number for the machine, given by */
549 /*          BASE**( EMIN - 1 ), where  BASE  is the floating point value */
550 /*          of BETA. */
551
552 /*  EMAX    (output) INTEGER */
553 /*          The maximum exponent before overflow occurs. */
554
555 /*  RMAX    (output) DOUBLE PRECISION */
556 /*          The largest positive number for the machine, given by */
557 /*          BASE**EMAX * ( 1 - EPS ), where  BASE  is the floating point */
558 /*          value of BETA. */
559
560 /*  Further Details */
561 /*  =============== */
562
563 /*  The computation of  EPS  is based on a routine PARANOIA by */
564 /*  W. Kahan of the University of California at Berkeley. */
565
566 /* ===================================================================== */
567
568 /*     .. Local Scalars .. */
569 /*     .. */
570 /*     .. External Functions .. */
571 /*     .. */
572 /*     .. External Subroutines .. */
573 /*     .. */
574 /*     .. Intrinsic Functions .. */
575 /*     .. */
576 /*     .. Save statement .. */
577 /*     .. */
578 /*     .. Data statements .. */
579 /*     .. */
580 /*     .. Executable Statements .. */
581
582     if (first) {
583         zero = 0.;
584         one = 1.;
585         two = 2.;
586
587 /*        LBETA, LT, LRND, LEPS, LEMIN and LRMIN  are the local values of */
588 /*        BETA, T, RND, EPS, EMIN and RMIN. */
589
590 /*        Throughout this routine  we use the function  DLAMC3  to ensure */
591 /*        that relevant values are stored  and not held in registers,  or */
592 /*        are not affected by optimizers. */
593
594 /*        DLAMC1 returns the parameters  LBETA, LT, LRND and LIEEE1. */
595
596         dlamc1_(&lbeta, &lt, &lrnd, &lieee1);
597
598 /*        Start to find EPS. */
599
600         b = (doublereal) lbeta;
601         i__1 = -lt;
602         a = pow_di(&b, &i__1);
603         leps = a;
604
605 /*        Try some tricks to see whether or not this is the correct  EPS. */
606
607         b = two / 3;
608         half = one / 2;
609         d__1 = -half;
610         sixth = dlamc3_(&b, &d__1);
611         third = dlamc3_(&sixth, &sixth);
612         d__1 = -half;
613         b = dlamc3_(&third, &d__1);
614         b = dlamc3_(&b, &sixth);
615         b = abs(b);
616         if (b < leps) {
617             b = leps;
618         }
619
620         leps = 1.;
621
622 /* +       WHILE( ( LEPS.GT.B ).AND.( B.GT.ZERO ) )LOOP */
623 L10:
624         if (leps > b && b > zero) {
625             leps = b;
626             d__1 = half * leps;
627 /* Computing 5th power */
628             d__3 = two, d__4 = d__3, d__3 *= d__3;
629 /* Computing 2nd power */
630             d__5 = leps;
631             d__2 = d__4 * (d__3 * d__3) * (d__5 * d__5);
632             c__ = dlamc3_(&d__1, &d__2);
633             d__1 = -c__;
634             c__ = dlamc3_(&half, &d__1);
635             b = dlamc3_(&half, &c__);
636             d__1 = -b;
637             c__ = dlamc3_(&half, &d__1);
638             b = dlamc3_(&half, &c__);
639             goto L10;
640         }
641 /* +       END WHILE */
642
643         if (a < leps) {
644             leps = a;
645         }
646
647 /*        Computation of EPS complete. */
648
649 /*        Now find  EMIN.  Let A = + or - 1, and + or - (1 + BASE**(-3)). */
650 /*        Keep dividing  A by BETA until (gradual) underflow occurs. This */
651 /*        is detected when we cannot recover the previous A. */
652
653         rbase = one / lbeta;
654         small = one;
655         for (i__ = 1; i__ <= 3; ++i__) {
656             d__1 = small * rbase;
657             small = dlamc3_(&d__1, &zero);
658 /* L20: */
659         }
660         a = dlamc3_(&one, &small);
661         dlamc4_(&ngpmin, &one, &lbeta);
662         d__1 = -one;
663         dlamc4_(&ngnmin, &d__1, &lbeta);
664         dlamc4_(&gpmin, &a, &lbeta);
665         d__1 = -a;
666         dlamc4_(&gnmin, &d__1, &lbeta);
667         ieee = FALSE_;
668
669         if (ngpmin == ngnmin && gpmin == gnmin) {
670             if (ngpmin == gpmin) {
671                 lemin = ngpmin;
672 /*            ( Non twos-complement machines, no gradual underflow; */
673 /*              e.g.,  VAX ) */
674             } else if (gpmin - ngpmin == 3) {
675                 lemin = ngpmin - 1 + lt;
676                 ieee = TRUE_;
677 /*            ( Non twos-complement machines, with gradual underflow; */
678 /*              e.g., IEEE standard followers ) */
679             } else {
680                 lemin = min(ngpmin,gpmin);
681 /*            ( A guess; no known machine ) */
682                 iwarn = TRUE_;
683             }
684
685         } else if (ngpmin == gpmin && ngnmin == gnmin) {
686             if ((i__1 = ngpmin - ngnmin, abs(i__1)) == 1) {
687                 lemin = max(ngpmin,ngnmin);
688 /*            ( Twos-complement machines, no gradual underflow; */
689 /*              e.g., CYBER 205 ) */
690             } else {
691                 lemin = min(ngpmin,ngnmin);
692 /*            ( A guess; no known machine ) */
693                 iwarn = TRUE_;
694             }
695
696         } else if ((i__1 = ngpmin - ngnmin, abs(i__1)) == 1 && gpmin == gnmin)
697                  {
698             if (gpmin - min(ngpmin,ngnmin) == 3) {
699                 lemin = max(ngpmin,ngnmin) - 1 + lt;
700 /*            ( Twos-complement machines with gradual underflow; */
701 /*              no known machine ) */
702             } else {
703                 lemin = min(ngpmin,ngnmin);
704 /*            ( A guess; no known machine ) */
705                 iwarn = TRUE_;
706             }
707
708         } else {
709 /* Computing MIN */
710             i__1 = min(ngpmin,ngnmin), i__1 = min(i__1,gpmin);
711             lemin = min(i__1,gnmin);
712 /*         ( A guess; no known machine ) */
713             iwarn = TRUE_;
714         }
715         first = FALSE_;
716 /* ** */
717 /* Comment out this if block if EMIN is ok */
718         if (iwarn) {
719             first = TRUE_;
720             printf("\n\n WARNING. The value EMIN may be incorrect:- ");
721             printf("EMIN = %8i\n",lemin);
722             printf("If, after inspection, the value EMIN looks acceptable");
723             printf("please comment out \n the IF block as marked within the"); 
724             printf("code of routine DLAMC2, \n otherwise supply EMIN"); 
725             printf("explicitly.\n");
726          /*
727             s_wsfe(&io___58);
728             do_fio(&c__1, (char *)&lemin, (ftnlen)sizeof(integer));
729             e_wsfe();
730          */
731         }
732 /* ** */
733
734 /*        Assume IEEE arithmetic if we found denormalised  numbers above, */
735 /*        or if arithmetic seems to round in the  IEEE style,  determined */
736 /*        in routine DLAMC1. A true IEEE machine should have both  things */
737 /*        true; however, faulty machines may have one or the other. */
738
739         ieee = ieee || lieee1;
740
741 /*        Compute  RMIN by successive division by  BETA. We could compute */
742 /*        RMIN as BASE**( EMIN - 1 ),  but some machines underflow during */
743 /*        this computation. */
744
745         lrmin = 1.;
746         i__1 = 1 - lemin;
747         for (i__ = 1; i__ <= i__1; ++i__) {
748             d__1 = lrmin * rbase;
749             lrmin = dlamc3_(&d__1, &zero);
750 /* L30: */
751         }
752
753 /*        Finally, call DLAMC5 to compute EMAX and RMAX. */
754
755         dlamc5_(&lbeta, &lt, &lemin, &ieee, &lemax, &lrmax);
756     }
757
758     *beta = lbeta;
759     *t = lt;
760     *rnd = lrnd;
761     *eps = leps;
762     *emin = lemin;
763     *rmin = lrmin;
764     *emax = lemax;
765     *rmax = lrmax;
766
767     return 0;
768
769
770 /*     End of DLAMC2 */
771
772 } /* dlamc2_ */
773
774
775
776 /* *********************************************************************** */
777
778 /* Subroutine */ int dlamc4_(integer *emin, doublereal *start, integer *base)
779 {
780     /* System generated locals */
781     integer i__1;
782     doublereal d__1;
783
784     /* Local variables */
785     doublereal a;
786     integer i__;
787     doublereal b1, b2, c1, c2, d1, d2, one, zero, rbase;
788     extern doublereal dlamc3_(doublereal *, doublereal *);
789
790
791 /*  -- LAPACK auxiliary routine (version 3.1) -- */
792 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
793 /*     November 2006 */
794
795 /*     .. Scalar Arguments .. */
796 /*     .. */
797
798 /*  Purpose */
799 /*  ======= */
800
801 /*  DLAMC4 is a service routine for DLAMC2. */
802
803 /*  Arguments */
804 /*  ========= */
805
806 /*  EMIN    (output) INTEGER */
807 /*          The minimum exponent before (gradual) underflow, computed by */
808 /*          setting A = START and dividing by BASE until the previous A */
809 /*          can not be recovered. */
810
811 /*  START   (input) DOUBLE PRECISION */
812 /*          The starting point for determining EMIN. */
813
814 /*  BASE    (input) INTEGER */
815 /*          The base of the machine. */
816
817 /* ===================================================================== */
818
819 /*     .. Local Scalars .. */
820 /*     .. */
821 /*     .. External Functions .. */
822 /*     .. */
823 /*     .. Executable Statements .. */
824
825     a = *start;
826     one = 1.;
827     rbase = one / *base;
828     zero = 0.;
829     *emin = 1;
830     d__1 = a * rbase;
831     b1 = dlamc3_(&d__1, &zero);
832     c1 = a;
833     c2 = a;
834     d1 = a;
835     d2 = a;
836 /* +    WHILE( ( C1.EQ.A ).AND.( C2.EQ.A ).AND. */
837 /*    $       ( D1.EQ.A ).AND.( D2.EQ.A )      )LOOP */
838 L10:
839     if (c1 == a && c2 == a && d1 == a && d2 == a) {
840         --(*emin);
841         a = b1;
842         d__1 = a / *base;
843         b1 = dlamc3_(&d__1, &zero);
844         d__1 = b1 * *base;
845         c1 = dlamc3_(&d__1, &zero);
846         d1 = zero;
847         i__1 = *base;
848         for (i__ = 1; i__ <= i__1; ++i__) {
849             d1 += b1;
850 /* L20: */
851         }
852         d__1 = a * rbase;
853         b2 = dlamc3_(&d__1, &zero);
854         d__1 = b2 / rbase;
855         c2 = dlamc3_(&d__1, &zero);
856         d2 = zero;
857         i__1 = *base;
858         for (i__ = 1; i__ <= i__1; ++i__) {
859             d2 += b2;
860 /* L30: */
861         }
862         goto L10;
863     }
864 /* +    END WHILE */
865
866     return 0;
867
868 /*     End of DLAMC4 */
869
870 } /* dlamc4_ */
871
872
873 /* *********************************************************************** */
874
875 /* Subroutine */ int dlamc5_(integer *beta, integer *p, integer *emin, 
876         logical *ieee, integer *emax, doublereal *rmax)
877 {
878     /* System generated locals */
879     integer i__1;
880     doublereal d__1;
881
882     /* Local variables */
883     integer i__;
884     doublereal y, z__;
885     integer try__, lexp;
886     doublereal oldy;
887     integer uexp, nbits;
888     extern doublereal dlamc3_(doublereal *, doublereal *);
889     doublereal recbas;
890     integer exbits, expsum;
891
892
893 /*  -- LAPACK auxiliary routine (version 3.1) -- */
894 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
895 /*     November 2006 */
896
897 /*     .. Scalar Arguments .. */
898 /*     .. */
899
900 /*  Purpose */
901 /*  ======= */
902
903 /*  DLAMC5 attempts to compute RMAX, the largest machine floating-point */
904 /*  number, without overflow.  It assumes that EMAX + abs(EMIN) sum */
905 /*  approximately to a power of 2.  It will fail on machines where this */
906 /*  assumption does not hold, for example, the Cyber 205 (EMIN = -28625, */
907 /*  EMAX = 28718).  It will also fail if the value supplied for EMIN is */
908 /*  too large (i.e. too close to zero), probably with overflow. */
909
910 /*  Arguments */
911 /*  ========= */
912
913 /*  BETA    (input) INTEGER */
914 /*          The base of floating-point arithmetic. */
915
916 /*  P       (input) INTEGER */
917 /*          The number of base BETA digits in the mantissa of a */
918 /*          floating-point value. */
919
920 /*  EMIN    (input) INTEGER */
921 /*          The minimum exponent before (gradual) underflow. */
922
923 /*  IEEE    (input) LOGICAL */
924 /*          A logical flag specifying whether or not the arithmetic */
925 /*          system is thought to comply with the IEEE standard. */
926
927 /*  EMAX    (output) INTEGER */
928 /*          The largest exponent before overflow */
929
930 /*  RMAX    (output) DOUBLE PRECISION */
931 /*          The largest machine floating-point number. */
932
933 /* ===================================================================== */
934
935 /*     .. Parameters .. */
936 /*     .. */
937 /*     .. Local Scalars .. */
938 /*     .. */
939 /*     .. External Functions .. */
940 /*     .. */
941 /*     .. Intrinsic Functions .. */
942 /*     .. */
943 /*     .. Executable Statements .. */
944
945 /*     First compute LEXP and UEXP, two powers of 2 that bound */
946 /*     abs(EMIN). We then assume that EMAX + abs(EMIN) will sum */
947 /*     approximately to the bound that is closest to abs(EMIN). */
948 /*     (EMAX is the exponent of the required number RMAX). */
949
950     lexp = 1;
951     exbits = 1;
952 L10:
953     try__ = lexp << 1;
954     if (try__ <= -(*emin)) {
955         lexp = try__;
956         ++exbits;
957         goto L10;
958     }
959     if (lexp == -(*emin)) {
960         uexp = lexp;
961     } else {
962         uexp = try__;
963         ++exbits;
964     }
965
966 /*     Now -LEXP is less than or equal to EMIN, and -UEXP is greater */
967 /*     than or equal to EMIN. EXBITS is the number of bits needed to */
968 /*     store the exponent. */
969
970     if (uexp + *emin > -lexp - *emin) {
971         expsum = lexp << 1;
972     } else {
973         expsum = uexp << 1;
974     }
975
976 /*     EXPSUM is the exponent range, approximately equal to */
977 /*     EMAX - EMIN + 1 . */
978
979     *emax = expsum + *emin - 1;
980     nbits = exbits + 1 + *p;
981
982 /*     NBITS is the total number of bits needed to store a */
983 /*     floating-point number. */
984
985     if (nbits % 2 == 1 && *beta == 2) {
986
987 /*        Either there are an odd number of bits used to store a */
988 /*        floating-point number, which is unlikely, or some bits are */
989 /*        not used in the representation of numbers, which is possible, */
990 /*        (e.g. Cray machines) or the mantissa has an implicit bit, */
991 /*        (e.g. IEEE machines, Dec Vax machines), which is perhaps the */
992 /*        most likely. We have to assume the last alternative. */
993 /*        If this is true, then we need to reduce EMAX by one because */
994 /*        there must be some way of representing zero in an implicit-bit */
995 /*        system. On machines like Cray, we are reducing EMAX by one */
996 /*        unnecessarily. */
997
998         --(*emax);
999     }
1000
1001     if (*ieee) {
1002
1003 /*        Assume we are on an IEEE machine which reserves one exponent */
1004 /*        for infinity and NaN. */
1005
1006         --(*emax);
1007     }
1008
1009 /*     Now create RMAX, the largest machine number, which should */
1010 /*     be equal to (1.0 - BETA**(-P)) * BETA**EMAX . */
1011
1012 /*     First compute 1.0 - BETA**(-P), being careful that the */
1013 /*     result is less than 1.0 . */
1014
1015     recbas = 1. / *beta;
1016     z__ = *beta - 1.;
1017     y = 0.;
1018     i__1 = *p;
1019     for (i__ = 1; i__ <= i__1; ++i__) {
1020         z__ *= recbas;
1021         if (y < 1.) {
1022             oldy = y;
1023         }
1024         y = dlamc3_(&y, &z__);
1025 /* L20: */
1026     }
1027     if (y >= 1.) {
1028         y = oldy;
1029     }
1030
1031 /*     Now multiply by BETA**EMAX to get RMAX. */
1032
1033     i__1 = *emax;
1034     for (i__ = 1; i__ <= i__1; ++i__) {
1035         d__1 = y * *beta;
1036         y = dlamc3_(&d__1, &c_b32);
1037 /* L30: */
1038     }
1039
1040     *rmax = y;
1041     return 0;
1042
1043 /*     End of DLAMC5 */
1044
1045 } /* dlamc5_ */
1046
1047 #endif