annotate ext/cblas/src/dlamch.c @ 209:ccd2019190bf msvc

Some MSVC fixes, including (temporarily, probably) renaming the FFT source file to avoid getting it mixed up with the Vamp SDK one in our object dir
author Chris Cannam
date Thu, 01 Feb 2018 16:34:08 +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_ */