Manual Reference Pages  - cmplx (3fortran)

NAME

CMPLX(3) - [TYPE:NUMERIC] Conversion to a complex type

SYNOPSIS

result = cmplx(x [,kind]) | cmplx(x [,y] [,kind])

         elemental complex(kind=KIND) function cmplx( x, y, kind )

type(TYPE(kind=**)),intent(in) :: x type(TYPE(kind=**)),intent(in),optional :: y integer(kind=**),intent(in),optional :: KIND

CHARACTERISTICS

o X may be integer, real, or complex.
o Y may be integer or real. Y is allowed only if X is not complex.
o KIND is a constant integer initialization expression indicating the kind parameter of the result.
The type of the arguments does not affect the kind of the result except for a complex X value.
o if KIND is not present and X is complex the result is of the kind of X.
o if KIND is not present and X is not complex the result if of default complex kind.
NOTE: a kind designated as ** may be any supported kind for the type

DESCRIPTION

The CMPLX(3) function converts numeric values to a complex value.

Even though constants can be used to define a complex variable using syntax like

          z = (1.23456789, 9.87654321)

this will not work for variables. So you cannot enter

          z = (a, b)  ! NO ! (unless a and b are constants, not variables)

so to construct a complex value using non-complex values you must use the CMPLX(3) function:

          z = cmplx(a, b)

or assign values separately to the imaginary and real components using the %IM and %RE designators:

          z%re = a
          z%im = b

If X is complex Y is not allowed and CMPLX essentially returns the input value except for an optional change of kind, which can be useful when passing a value to a procedure that requires the arguments to have a different kind (and does not return an altered value):

          call something(cmplx(z,kind=real64))

would pass a copy of a value with kind=real64 even if z had a different kind

but otherwise is equivalent to a simple assign. So if z1 and z2 were complex:

          z2 = z1        ! equivalent statements
          z2 = cmplx(z1)

If X is not complex X is only used to define the real component of the result but Y is still optional -- the imaginary part of the result will just be assigned a value of zero.

If Y is present it is converted to the imaginary component.

CMPLX(3) AND DOUBLE PRECISION

Primarily in order to maintain upward compatibility you need to be careful when working with complex values of higher precision that the default.

It was necessary for Fortran to continue to specify that CMPLX(3) always return a result of the default kind if the KIND option is absent, since that is the behavior mandated by FORTRAN 77.

It might have been preferable to use the highest precision of the arguments for determining the return kind, but that is not the case. So with arguments with greater precision than default values you are required to use the KIND argument or the greater precision values will be reduced to default precision.

This means CMPLX(D1,D2), where D1 and D2 are doubleprecision, is treated as:

          cmplx(sngl(d1), sngl(d2))

which looses precision.

So Fortran 90 extends the CMPLX(3) intrinsic by adding an extra argument used to specify the desired kind of the complex result.

          integer,parameter :: dp=kind(0.0d0)
          complex(kind=dp) :: z8
! wrong ways to specify constant values ! note this was stored with default real precision ! z8 = cmplx(1.2345678901234567d0, 1.2345678901234567d0) print *, ’NO, Z8=’,z8,real(z8),aimag(z8)

z8 = cmplx(1.2345678901234567e0_dp, 1.2345678901234567e0_dp) ! again, note output components are just real print *, ’NO, Z8=’,z8,real(z8),aimag(z8) ! ! YES ! ! kind= makes it work z8 = cmplx(1.2345678901234567d0, 1.2345678901234567d0,kind=dp) print *, ’YES, Z8=’,z8,real(z8),aimag(z8)

A more recent alternative to using CMPLX(3) is "F2018 component syntax" where real and imaginary parts of a complex entity can be accessed independently:

    value%RE     ! %RE specifies the real part
    or
    value%IM     ! %IM specifies the imaginary part

Where the designator value is of course of complex type.

The type of a complex-part-designator is real, and its kind and shape are those of the designator. That is, you retain the precision of the complex value by default, unlike with CMPLX.

The following are examples of complex part designators:

           impedance%re           !-- Same value as real(impedance)
           fft%im                 !-- Same value as AIMAG(fft)
           x%im = 0.0             !-- Sets the imaginary part of x to zero
           x(1:2)%re=[10,20]      !-- even if x is an array

NOTE for I/O

Note that if format statements are specified a complex value is treated as two real values.

For list-directed I/O (ie. using an asterisk for a format) and NAMELIST output the values are expected to be delimited by "(" and ")" and of the form "(real_part,imaginary_part)". For NAMELIST input parenthesized values or lists of multiple real values are acceptable.

OPTIONS

o X : The value assigned to the real component of the result when X is not complex.

If X is complex, the result is the same as if the real part of the input was passed as X and the imaginary part as Y.

         result = CMPLX (REAL (X), AIMAG (X), KIND).

That is, a complex X value is copied to the result value with a possible change of kind.
o Y : Y is only allowed if X is not complex. Its value is assigned to the imaginary component of the result and defaults to a value of zero if absent.
o KIND : An integer initialization expression indicating the kind parameter of the result.

RESULT

The return value is of complex type, with magnitudes determined by the values X and Y.

The common case when X is not complex is that the real component of the result is assigned the value of X and the imaginary part is zero or the value of Y if Y is present.

When X is complex Y is not allowed and the result is the same value as X with a possible change of kind. That is, the real part is REAL(X, KIND) and the imaginary part is REAL(Y, KIND).

EXAMPLES

Sample program:

    program demo_aimag
    implicit none
    integer,parameter :: dp=kind(0.0d0)
    real(kind=dp)     :: precise
    complex(kind=dp)  :: z8
    complex           :: z4, zthree(3)
       precise=1.2345678901234567d0

! basic z4 = cmplx(-3) print *, ’Z4=’,z4 z4 = cmplx(1.23456789, 1.23456789) print *, ’Z4=’,z4 ! with a format treat a complex as two real values print ’(1x,g0,1x,g0,1x,g0)’,’Z4=’,z4

! working with higher precision values ! using kind=dp makes it keep DOUBLEPRECISION precision ! otherwise the result would be of default kind z8 = cmplx(precise, -precise ) print *, ’lost precision Z8=’,z8 z8 = cmplx(precise, -precise ,kind=dp) print *, ’kept precision Z8=’,z8

! assignment of constant values does not require cmplx(3)00 ! The following is intuitive and works without calling cmplx(3) ! but does not work for variables just constants z8 = (1.1111111111111111d0, 2.2222222222222222d0 ) print *, ’Z8 defined with constants=’,z8

! what happens when you assign a complex to a real? precise=z8 print *, ’LHS=’,precise,’RHS=’,z8

! elemental zthree=cmplx([10,20,30],-1) print *, ’zthree=’,zthree

! descriptors are an alternative zthree(1:2)%re=[100,200] print *, ’zthree=’,zthree

end program demo_aimag

Results:

        Z4= (-3.000000,0.0000000E+00)
        Z4= (1.234568,1.234568)
        Z4= 1.234568 1.234568
        lost precision Z8= (1.23456788063049,-1.23456788063049)
        kept precision Z8= (1.23456789012346,-1.23456789012346)
        Z8 defined with constants= (1.11111111111111,2.22222222222222)
        LHS=   1.11111111111111      RHS= (1.11111111111111,2.22222222222222)
        zthree= (10.00000,-1.000000) (20.00000,-1.000000) (30.00000,-1.000000)
        zthree= (100.0000,-1.000000) (200.0000,-1.000000) (30.00000,-1.000000)

STANDARD

FORTRAN 77, KIND added in Fortran 90.

SEE ALSO

o AIMAG(3) - Imaginary part of complex number
o CONJG(3) - Complex conjugate function
o REAL(3) - Convert to real type
Fortran has strong support for complex values, including many intrinsics that take or produce complex values in addition to algebraic and logical expressions:

ABS(3), ACOSH(3), ACOS(3), ASINH(3), ASIN(3), ATAN2(3), ATANH(3), ATAN(3), COSH(3), COS(3), CO_SUM(3), DBLE(3), DOT_PRODUCT(3), EXP(3), INT(3), IS_CONTIGUOUS(3), KIND(3), LOG(3), MATMUL(3), PRECISION(3), PRODUCT(3), RANGE(3), RANK(3), SINH(3), SIN(3), SQRT(3), STORAGE_SIZE(3), SUM(3), TANH(3), TAN(3), UNPACK(3),

fortran-lang intrinsic descriptions (license: MIT) @urbanjost


Nemo Release 3.1 cmplx (3fortran) April 28, 2024
Generated by manServer 1.08 from 67dece0d-76b4-4a46-927e-9686da8b7242 using man macros.