NAG Fortran Compiler, Release 7.2: Intrinsic procedures and modules

Navigation: Previous Up Next

## 10.6 Intrinsic procedures and modules

### 10.6.1 Additional mathematical intrinsic functions [mostly 5.3.1]

- The elemental intrinsic functions `ACOSH`, `ASINH` and `ATANH` compute the inverse hyperbolic cosine, sine or tangent respectively. There is a single argument `X`, which may be of type Real or Complex; the result of the function has the same type and kind. When the argument is Complex, the imaginary part is expressed in radians and lies in the range 0≤im≤π for the `ACOSH` function, and −π/2≤im≤π/2 for the `ASINH` and `ATANH` functions.

  For example, `ACOSH(1.543081)`, `ASINH(1.175201)` and `ATANH(0.7615942)` are all approximately equal to `1.0`.

- [6.1] The new elemental intrinsic functions `BESSEL_J0`, `BESSEL_Y0`, `BESSEL_J1` and `BESSEL_Y1` compute the Bessel functions J0, Y0, J1 and Y1 respectively. These functions are solutions to Bessel's differential equation. The J functions are of the 1st kind and the Y functions are of the 2nd kind; the following subscript indicates the order (0 or 1). There is a single argument `X`, which must be of type Real; the result of the function has the same type and kind. For functions of the 2nd kind (`BESSEL_Y0` and `BESSEL_Y1`), the argument `X` must be positive.

  For example, `BESSEL_J0(1.5)` is approximately `0.5118276`, `BESSEL_Y0(1.5)` is approximately `0.3824489`, `BESSEL_J1(1.5)` is approximately `0.5579365` and `BESSEL_Y1(1.5)` is approximately `-0.4123086`.

- [6.1] The new intrinsic functions `BESSEL_JN` and `BESSEL_YN` compute the Bessel functions Jn and Yn respectively. These functions come in two forms: an elemental form and a transformational form.

  The elemental form has two arguments: `N`, the order of the function to compute, and `X`, the argument of the Bessel function. `BESSEL_JN(0,X)` is identical to `BESSEL_J0(X)`, etc..

  The transformational form has three scalar arguments: `N1`, `N2` and `X`. The result is a vector of size `MAX(N2-N1+1,0)`, containing approximations to the Bessel functions of orders `N1` to `N2` applied to `X`.

  For example, `BESSEL_JN(5,7.5)` is approximately `0.283474`, `BESSEL_YN(5,7.5)` is approximately `0.175418`, `BESSEL_JN(3,5,7.5)` is approximately `[ -0.258061, 0.023825, 0.283474 ]` and `BESSEL_YN(3,5,7.5)` is approximately `[ 0.159708, 0.314180, 0.175418 ]`.

- [6.0] The elemental intrinsic functions `ERF`, `ERFC` and `ERFC_SCALED` compute the error function, the complementary error function and the scaled complementary error function, respectively. The single argument `X` must be of type real.

  The error function is the integral of −t2 from 0 to `X`, times 2/`SQRT`(π); this rapidly converges to 1. The complementary error function is 1 minus the error function, and fairly quickly converges to zero. The scaled complementary error function scales the value (of 1 minus the error function) by `EXP`(`X`**2); this also converges to zero but only very slowly.

- [6.0] The elemental intrinsic functions `GAMMA` and `LOG_GAMMA` compute the gamma function and the natural logarithm of the absolute value of the gamma function respectively. The single argument `X` must be of type real, and must not be zero or a negative integer.

  The gamma function is the extension of factorial from the integers to the reals; for positive integers, `GAMMA(X)` is equal to (`X`−1)!, i.e. factorial of `X`−1. This grows very rapidly and thus overflows for quite small `X`; `LOG_GAMMA` also diverges but much more slowly.

- The elemental intrinsic function `HYPOT` computes the “Euclidean distance function” (square root of the sum of squares) of its arguments `X` and `Y` without overflow or underflow for very large or small `X` or `Y` (unless the result itself overflows or underflows). The arguments must be of type Real with the same kind, and the result is of type Real with that kind. Note that `HYPOT(X,Y)` is semantically and numerically equal to `ABS(CMPLX(X,Y,KIND(X)))`.

  For example, `HYPOT(3e30,4e30)` is approximately equal to `5e30`.

- The array reduction intrinsic function `NORM2(X,DIM)` reduces Real arrays using the L2-norm operation. This operates exactly the same as `SUM` and `PRODUCT`, except for the operation involved. The L2 norm of an array is the square root of the sum of the squares of the elements. Note that unlike most of the other reduction functions, `NORM2` does not have a `MASK` argument. The `DIM` argument is optional; an actual argument for `DIM` is not itself permitted to be an optional dummy argument.

  The calculation of the result value is done in such a way as to avoid intermediate overflow and underflow, except when the result itself is outside the maximum range. For example, `NORM2([X,Y])` is approximately the same as `HYPOT(X,Y)`.

### 10.6.2 Additional intrinsic functions for bit manipulation [mostly 5.3]

- The elemental intrinsic functions `BGE`, `BGT`, `BLE` and `BLT` perform bitwise (i.e. unsigned) comparisons. They each have two arguments, `I` and `J`, which must be of type Integer but may be of different kind. The result is default Logical.

  For example, `BGE(INT(Z'FF',INT8),128)` is true, while `INT(Z'FF',INT8)>=128` is false.

- [5.3.1] The elemental intrinsic functions `DSHIFTL` and `DSHIFTR` perform double-width shifting. They each have three arguments, `I`, `J` and `SHIFT` which must be of type Integer, except that one of `I` or `J` may be a BOZ literal constant – it will be converted to the type and kind of the other `I` or `J` argument. `I` and `J` must have the same kind if they are both of type Integer. The result is of type Integer, with the same kind as `I` and `J`. The `I` and `J` arguments are effectively concatenated to form a single double-width value, which is shifted left or right by `SHIFT` positions; for `DSHIFTL` the result is the top half of the combined shift, and for `DSHIFTR` the result is the bottom half of the combined shift.

  For example, `DSHIFTL(INT(B'11000101',1),B'11001001',2)` has the value `INT(B'00010111',1)` (decimal value 23), whereas `DSHIFTR(INT(B'11000101',1),B'11001001',2)` has the value `INT(B'01110010',1)` (decimal value 114).

- The array reduction intrinsic functions `IALL`, `IANY` and `IPARITY` reduce arrays using bitwise operations. These are exactly the same as `SUM` and `PRODUCT`, except that instead of reducing the array by the `+` or `*` operation, they reduce it by the `IAND`, `IOR` and `IEOR` intrinsic functions respectively. That it, each element of the result is the bitwise-and, bitwise-or, or bitwise-exclusive-or of the reduced elements. If the number of reduced elements is zero, the result is zero for `IANY` and `IPARITY`, and `NOT(`zero`)` for `IALL`.
- The elemental intrinsic functions `LEADZ` and `TRAILZ` return the number of leading (most significant) and trailing (least significant) zero bits in the argument `I`, which must be of type Integer (of any kind). The result is default Integer.
- The elemental intrinsic functions `MASKL` and `MASKR` generate simple left-justified and right-justified bitmasks. The value of `MASKL(I,KIND)` is an integer with the specified kind that has its leftmost `I` bits set to one and the rest set to zero; `I` must be non-negative and less than or equal to the bitsize of the result. If `KIND` is omitted, the result is default integer. The value of `MASKR` is similar, but has its rightmost `I` bits set to one instead.
- [5.3.1] The elemental intrinsic function `MERGE_BITS(I,J,MASK)` merges the bits from Integer values `I` and `J`, taking the bit from `I` when the corresponding bit in `MASK` is `1`, and taking the bit from `J` when it is zero. All arguments must be BOZ literal constants or of type Integer, and all the Integer arguments must have the same kind; at least one of `I` and `J` must be of type Integer, and the result has the same type and kind.

  Note that `MERGE_BITS(I,J,MASK)` is identical to `IOR(IAND(I,MASK),IAND(J,NOT(MASK)))`.

  For example, `MERGE_BITS(INT(B'00110011',1),B'11110000',B'10101010')` is equal to `INT(B'01110010')` (decimal value 114).

- The array reduction intrinsic function `PARITY` reduces Logical arrays. It is exactly the same as `ALL` and `ANY`, except that instead of reducing the array by the `.AND.` or `.OR.` operation, it reduces it by the `.NEQV.` operation. That is, each element of the result is `.TRUE.` if an odd number of reduced elements is `.TRUE.`.
- The elemental intrinsic function `POPCNT(I)` returns the number of bits in the Integer argument `I` that are set to 1. The elemental intrinsic function `POPPAR(I)` returns zero if the number of bits in `I` that are set to 1 are even, and one if it is odd. The result is default Integer.

### 10.6.3 Other new intrinsic procedures [mostly 5.3.1]

- The intrinsic subroutine `EXECUTE_COMMAND_LINE` passes a command line to the operating system's command processor for execution. It has five arguments, in order these are:
  `CHARACTER(*),INTENT(IN) :: COMMAND` — the command to be executed;
  `LOGICAL,INTENT(IN),OPTIONAL :: WAIT` — whether to wait for command completion (default true);
  `INTEGER,INTENT(INOUT),OPTIONAL :: EXITSTAT` — the result value of the command;
  `INTEGER,INTENT(OUT),OPTIONAL :: CMDSTAT` — see below;
  `CHARACTER(*),INTENT(INOUT),OPTIONAL :: CMDMSG` — the error message if `CMDSTAT` is non-zero.

  `CMDSTAT` values are zero for success, −1 if command line execution is not supported, −2 if `WAIT` is present and false but asynchronous execution is not supported, and a positive value to indicate some other error. If `CMDSTAT` is not present but would have been set non-zero, the program will be terminated. Note that Release 5.3.1 supports command line execution on all systems, and does not support asynchronous execution on any system.

  For example, `CALL EXECUTE_COMMAND_LINE('echo Hello')` will probably display ‘`Hello`’ in the console window.

- The intrinsic function `STORAGE_SIZE(A,KIND)` returns the size in bits of a scalar object with the same dynamic type and type parameters as `A`, when it is stored as an array element (i.e. including any padding). The `KIND` argument is optional; the result is type Integer with kind `KIND` if it is present, and default kind otherwise.

  If `A` is allocatable or a pointer, it does not have to be allocated unless it has a deferred type parameter (e.g. `CHARACTER(:)`) or is `CLASS(*)`. If it is a polymorphic pointer, it must not have an undefined status.

  For example, `STORAGE_SIZE(13_1)` is equal to 8 (bits).

- [6.0] The intrinsic inquiry function `IS_CONTIGUOUS` has a single argument `ARRAY`, which can be an array of any type. The function returns true if `ARRAY` is stored contiguously, and false otherwise. Note that this question has no meaning for an array with no elements, or for an array expression since that is a value and not a variable.
- [7.0] The intrinsic function `FINDLOC` is similar to `MAXLOC` and `MINLOC`, but instead of finding the location of the maximum or minimum value of an array, it finds a location that is equal to a specified value; thus it is available for all intrinsic types including `COMPLEX` and `LOGICAL`. It has one of the following two forms:

             FINDLOC (ARRAY, VALUE, DIM, MASK, KIND, BACK )
             FINDLOC (ARRAY, VALUE, MASK, KIND, BACK )

  where

  `ARRAY` | is an array of intrinsic type, with rank N;
  `VALUE` | is a scalar of the same type (if `LOGICAL`) or which may be compared with `ARRAY` using the intrinsic
  | operator `==` (or `.EQ.`);
  `DIM` | is a scalar `INTEGER` in the range 1 to N;
  `MASK` | (optional) is an array of type `LOGICAL` with the same shape as `ARRAY`
  `KIND` | (optional) is a scalar `INTEGER` constant expression that is a valid Integer kind number;
  `BACK` | (optional) is a scalar `LOGICAL` value.

  The result of the function is type `INTEGER`, or `INTEGER(KIND)` if `KIND` is present.

  In the form without `DIM`, the result is a vector of length N, and is the location of the element of `ARRAY` that is equal to `VALUE`; if `MASK` is present, only elements for which the corresponding element of `MASK` are `.TRUE.` are considered. As in `MAXLOC` and `MINLOC`, the location is reported with 1 for the first element in each dimension; if no element equal to `VALUE` is found, the result is zero. If `BACK` is present with the value `.TRUE.`, the element found is the last one (in array element order); otherwise, it is the first one.

  In the form with `DIM`, the result has rank N−1 (thus scalar if `ARRAY` is a vector), the shape being that of `ARRAY` with dimension `DIM` removed, and each element of the result is the location of the (masked) element in the dimension `DIM` vector that is equal to `VALUE`.

  For example, if `ARRAY` is an Integer vector with value `[ 10,20,30,40,50 ]`, `FINDLOC(ARRAY,30)` will return the vector `[ 3 ]` and `FINDLOC(ARRAY,7)` will return the vector `[ 0 ]`.

### 10.6.4 Changes to existing intrinsic procedures [mostly 5.3.1]

- The intrinsic functions `ACOS`, `ASIN`, `ATAN`, `COSH`, `SINH`, `TAN` and `TANH` now accept arguments of type Complex. Note that the hyperbolic and non-hyperbolic versions of these functions and the new `ACOSH`, `ASINH` and `ATANH` functions are all related by simple algebraic identities, for example the new `COSH(X)` is identical to the old `COS((0,1)*X)` and the new `SINH(X)` is identical to the old `(0,-1)*SIN((0,1)*X)`.
- The intrinsic function `ATAN` now has an extra form `ATAN(Y,X)`, with exactly the same semantics as `ATAN2(Y,X)`.
- [6.2] The intrinsic functions `MAXLOC` and `MINLOC` now have an additional optional argument `BACK` following the `KIND` argument. It is scalar and of type Logical; if present with the value `.True.`, if there is more than one element that has the maximum value (for `MAXLOC`) or minimum value (for `MINLOC`), the array element index returned is for the last element with that value rather than the first.

  For example, the value of

             MAXLOC( [ 5,1,5 ], BACK=.TRUE.)

  is the array `[ 3 ]`, rather than `[ 1 ]`.
- The intrinsic function `SELECTED_REAL_KIND` now has a third argument `RADIX`; this specifies the desired radix of the Real kind requested. Note that the function `IEEE_SELECTED_REAL_KIND` in the intrinsic module `IEEE_ARITHMETIC` also has this new third argument, and will allow requesting IEEE decimal floating-point kinds if they become available in the future.

### 10.6.5 `ISO_C_BINDING` additions [6.2]

The standard intrinsic module `ISO_C_BINDING` contains an additional procedure as follows.

    INTERFACE c_sizeof
      PURE INTEGER(c_size_t) FUNCTION c_sizeof...(x) ! Specific name not visible
        TYPE(*) :: x(..)
      END FUNCTION
    END INTERFACE

The actual argument `x` must be interoperable. The result is the same as the C `sizeof` operator applied to the conceptually corresponding C entity; that is, the size of `x` in bytes. If `x` is an array, it is the size of the whole array, not just one element. Note that `x` cannot be an assumed-size array.

### 10.6.6 `ISO_FORTRAN_ENV` additions

[5.3] The standard intrinsic module `ISO_FORTRAN_ENV` contains additional named constants as follows.

- The additional scalar integer constants `INT8`, `INT16`, `INT32`, `INT64`, `REAL32`, `REAL64` and `REAL128` supply the kind type parameter values for integer and real kinds with the indicated bit sizes.
- The additional named array constants `CHARACTER_KINDS`, `INTEGER_KINDS`, `LOGICAL_KINDS` and `REAL_KINDS` list the available kind type parameter values for each type (in no particular order).

[6.1] The standard intrinsic module `ISO_FORTRAN_ENV` contains two new functions as follows.

- `COMPILER_VERSION`. This function is pure, has no arguments, and returns a scalar default character string that identifies the version of the compiler that was used to compile the source file. This function may be used in a constant expression, e.g. to initialise a variable or named constant with this information. For example,

        Module version_info
          Use Iso_Fortran_Env
          Character(Len(Compiler_Version())) :: compiler = Compiler_Version()
        End Module
        Program show_version_info
          Use version_info
          Print *,compiler
        End Program

  With release 6.1 of the NAG Fortran Compiler, this program will print something like

       NAG Fortran Compiler Release 6.1(Tozai) Build 6105

- `COMPILER_OPTIONS`. This function is pure, has no arguments, and returns a scalar default character string that identifies the options supplied to the compiler when the source file was compiled. This function may be used in a constant expression, e.g. to initialise a variable or named constant with this information. For example,

        Module options_info
          Use Iso_Fortran_Env
          Character(Len(Compiler_Options())) :: compiler = Compiler_Options()
        End Module
        Program show_options_info
          Use options_info
          Print *,compiler
        End Program

  If compiled with the options -C=array -C=pointer -O, this program will print something like

       -C=array -C=pointer -O