annotate ext/cblas/src/dlamch.c @ 211:a41bea655151 msvc

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