MODULE Num_Constants

Module Num_Constants exports constants and functions for the machine dependent constants of real type of kind stnd.

Routines for identifying and manipulating NaNs (e.g., Not A Number) for real (or complex) data of kind stnd are also provided.

These special routines will use the intrinsic modules IEEE_EXCEPTIONS, IEEE_ARITHMETIC and IEEE_FEATURES , if the compiler provides support for the IEEE standard with this kind stnd and if the cpp macro _F2003 is activated at compilation of the STATPACK library. If support for the IEEE standard is not available, but the intrinsic function isnan() is available with your compiler, you can alternatively activate the cpp macro _ISNAN at compilation of the STATPACK library so that this intrinsic function will be used inside the STATPACK library to check for the presence of NaNs. However, if the cpp macro _F2003 is activated, the cpp macro _ISNAN has no effect.

The real/complex kind type stnd is defined in module Select_Parameters.

Note, finally, that the code of module Num_Constants is in the source file Modules_Constants.F90

Here is the list of the public constants exported by module Num_Constants:

!
! VALUES OF MACHINE NUMERIC CHARACTERISTICS
! WITH INTRINSIC VALUES IN FORTRAN90.
!
integer(i4b), parameter ::              &
    maxexp      = maxexponent(unitrnd), & ! LARGEST EXPONENT BEFORE OVERFLOW
    minexp      = minexponent(unitrnd), & ! MINIMUM EXPONENT BEFORE (GRADUAL) UNDERFLOW
    base        = radix(unitrnd),       & ! BASE OF THE MACHINE
    nbasedigits = digits(unitrnd),      & ! NUMBER OF (base) DIGITS IN THE MANTISSA
    decprec     = precision(unitrnd),   & ! NUMBER OF EQUIVALENT DECIMAL DIGITS IN THE MANTISSA
    decexpr     = range(unitrnd)          ! EQUIVALENT DECIMAL EXPONENT RANGE
!
real(stnd), parameter ::                 &
    machmaxexp      = maxexp,            & ! LARGEST EXPONENT BEFORE OVERFLOW
    machminexp      = minexp,            & ! MINIMUM EXPONENT BEFORE (GRADUAL) UNDERFLOW
    machbase        = base,              & ! BASE OF THE MACHINE
    machnbasedigits = nbasedigits,       & ! NUMBER OF (base) DIGITS IN THE MANTISSA
    machdecprec     = decprec,           & ! NUMBER OF EQUIVALENT DECIMAL DIGITS IN THE MANTISSA
    machdecexpr     = decexpr,           & ! EQUIVALENT DECIMAL EXPONENT RANGE
    machulp         = epsilon(unitrnd),  & ! MACHINE PRECISION   :  base**(1-nbasedigits)
    macheps         = machulp*half,      & ! MACHINE EPSILON, ASSUMING ROUNDING :  half*machulp
    machtiny        = tiny(unitrnd),     & ! UNDERFLOW THRESHOLD :  base**(minexp-1)
    machhuge        = huge(unitrnd)        ! OVERFLOW THRESHOLD  : (base**maxexp)*(1-base**(-nbasedigits))
!
! SCALING CONSTANTS FOR COMPUTING EUCLIDEAN OR FROBENIUS NORMS OF REAL OR COMPLEX ARRAYS AND
! SCALING SUBROUTINES, SEE https://doi.org/10.1145/3061665 FOR MORE DETAILS.
!
real(stnd), parameter ::                                   &
    safmin     = machbase**max(minexp-1_i4b,1_i4b-maxexp), & ! SAFE MINIMUM : base**max(minexp-1,1-maxexp)
    safmax     = one/safmin,                               & ! SAFE MAXIMUM
    machsmlnum = safmin/machulp,                           & ! SCALED MINIMUM
    machbignum = safmax*machulp,                           & ! SCALED MAXIMUM
    rtmin      = sqrt(machsmlnum),                         & ! SQUARE ROOT OF SCALED MINIMUM
    rtmax      = sqrt(machbignum)                            ! SQUARE ROOT OF SCALED MAXIMUM
!
! SCALING CONSTANTS FOR COMPUTING EUCLIDEAN OR FROBENIUS NORMS OF REAL OR COMPLEX ARRAYS
! WITH THE BLUE'S ALGORITHM (e.g., https://doi.org/10.1145/355769.355771). NOTE THAT lcs HAS
! BEEN CORRECTED TO SCALE DENORMALIZED NUMBERS CORRECTLY, SEE https://doi.org/10.1145/3061665
! FOR MORE DETAILS.
!
integer, parameter ::  lcb = ceiling(real(minexp-1_i4b,kind=stnd)*half),            &
                       ucb = floor(real(maxexp-nbasedigits+1_i4b,kind=stnd)*half),  &
                       lcs = floor(real(minexp-nbasedigits,kind=stnd)*half),        &
                       ucs = ceiling(real(maxexp+nbasedigits-1_i4b,kind=stnd)*half)
!
real(stnd), parameter  :: tbig = machbase**(ucb),  &
                          sbig = machbase**(-ucs), &
                          ubig = machbase**(ucs)
!
real(stnd), parameter  :: tsml = machbase**(lcb),  &
                          ssml = machbase**(-lcs), &
                          usml = machbase**(lcs)

In order to use one of these constants or one of the routines listed below, you must include an appropriate use Num_Constants or use Statpack statement in your Fortran program, like:

use Num_Constants, only: base

or :

use Statpack, only: base

Here is the list of the public routines exported by module Num_Constants:

lamch()

Purpose:

lamch() determines machine parameters for the real/complex parameterized precision stnd as defined in the Select_Parameters module.

The routine is based on the routine DLAMCH() in LAPACK.

Synopsis:

x = lamch( cmach )
mach()

Purpose:

mach() is intended to determine the parameters and the properties of the floating-point arithmetic system specified with the real/complex parameterized precision stnd, as defined in the Select_Parameters module.

This subroutines is based on the MACHAR() subroutine developped by [Cody:1988] and DLAMCH() in LAPACK.

See [Malcolm:1972] [Gentleman_Marovich:1974] [Cody:1988] for more details.

Synopsis:

call mach( basedigits=basedigits , irnd=irnd , iuflow=iuflow , igrd=igrd , iexp=iexp , ifloat=ifloat , &
           expepspos=expepspos , expepsneg=expepsneg , minexpbase=minexpbase , maxexpbase=maxexpbase , &
           epspos=epspos , epsneg=epsneg , epsilpos=epsilpos , epsilneg=epsilneg , rndunit=rndunit     )
test_ieee()

Purpose:

test_ieee() try to determine if the computer follows the IEEE standard 754 for binary floating-point arithmetic for the real/complex parameterized precision stnd defined in the Select_Parameters module.

test_ieee() returns true if the computer seems to follow the IEEE standard 754 and false otherwise.

If the compiler follows the Fortran 2003 standard and the cpp macro _F2003 is activated at compilation of the STATPACK library, the facilities provided by the IEEE_ARITHMETIC intrinsic module are used to determine if the computer follows the IEEE standard 754 for binary floating-point arithmetic. Otherwise results from [Cody_Coonen:1993] are used.

Synopsis:

test = test_ieee( )
test_nan()

Purpose:

test_nan() returns true if NaNs exist, and false otherwise.

If the compiler follows the Fortran 2003 standard and the cpp macro _F2003 is activated at compilation of the STATPACK library, the facilities provided by the IEEE_ARITHMETIC intrinsic module are used to determine if NaNs exist as defined in the IEEE standard 754 for binary floating-point arithmetic.

Otherwise, test_nan() exploits the IEEE requirement that NaNs compare as unequal to all values, including themselves [Cody_Coonen:1993].

Synopsis:

test = test_nan( )
is_nan()

Purpose:

is_nan() returns true if the real scalar X is a NaN or if the real array X contains a NaN, and false otherwise.

If the compiler follows the Fortran 2003 standard and the cpp macro _F2003 is activated at compilation of the STATPACK library, the facilities provided by the IEEE_ARITHMETIC intrinsic module are used to determine if NaNs are present as defined in the IEEE standard 754 for binary floating-point arithmetic. Alternatively, if the cpp macro _F2003 is not activated, but the compiler supports the intrinsic function isnan(), this function will used to detect NaNs if the cpp macro _ISNAN is activated at compilation of the STATPACK library.

Otherwise, is_nan() exploits the IEEE requirement that NaNs compare as unequal to all values, including themselves [Cody_Coonen:1993].

Synopsis:

test = is_nan( x      )
test = is_nan( x(:)   )
test = is_nan( x(:,:) )
replace_nan()

Purpose:

replace_nan() replaces:

  • the real scalar X with the scalar MISSING, if X is a NaN on input;
  • the NaNs in the input real array X with the scalar MISSING.

If the compiler follows the Fortran 2003 standard and the cpp macro _F2003 is activated at compilation of the STATPACK library, the facilities provided by the IEEE_ARITHMETIC intrinsic module are used to determine if NaNs are present as defined in the IEEE standard 754 for binary floating-point arithmetic. Alternatively, if the cpp macro _F2003 is not activated, but the compiler supports the intrinsic function isnan(), this function will used to detect NaNs if the cpp macro _ISNAN is activated at compilation of the STATPACK library.

Otherwise, replace_nan() exploits the IEEE requirement that NaNs compare as unequal to all values, including themselves [Cody_Coonen:1993].

Synopsis:

call replace_nan( x      , missing )
call replace_nan( x(:)   , missing )
call replace_nan( x(:,:) , missing )
nan()

Purpose:

nan() returns as a scalar function, the bit pattern corresponding to a quiet NaN in the IEEE standard 754 for binary floating-point arithmetic if the machine recognizes NaNs or the maximum floating point number of kind stnd otherwise (e.g. huge(1._stnd).

If the compiler follows the Fortran 2003 standard, the facilities provided by the IEEE_ARITHMETIC module are used to create a quiet NaN as defined in the IEEE standard 754 for binary floating-point arithmetic.

Otherwise, the routine exploits the IEEE requirement that NaNs compare as unequal to all values, including themselves [Cody_Coonen:1993].

Finally, NAN returns the maximum floating point number of kind stnd, if the computer does not follow the IEEE standard 754 for binary floating-point arithmetic.

Synopsis:

x = nan( )
true_nan()

Purpose:

true_nan() returns as a scalar function, the bit pattern corresponding to a quiet NaN in the IEEE standard 754 for binary floating-point arithmetic, independently of the fact that the computer follows or not the IEEE standard 754 for binary floating-point arithmetic for the real/complex datat of kind stnd.

Synopsis:

x = true_nan( )
Flag Counter