roygvib
roygvib

Reputation: 7395

Generic and specific functions to get real and imaginary parts of complex variables

In Fortran, I always work with double precision, so I have been using specific functions like dble and dimag to get real and imaginary parts of complex variables. However, for other functions like sin, I no longer use dsin because the former returns a value of proper kind (i.e., sin is a generic function). The same seems to hold for complex variables. So my question is:

1) What are the most recommended generic functions for getting real and imaginary parts?

-- It seems that real(z), aimag(z), and conjg(z) return a proper kind always (via experiments with gfortran), i.e., if z is double precision, those functions return double precision. Is this guaranteed? Also, is the behavior dependent on the standard used by the compiler? (i.e., Fortran 77 vs 90 or later, particularly for real(z)?)

2) If I (nevertheless) want to use specific functions that receives only double precision arguments and always return double precision values, what are the specific functions?

-- I have been using dble(z) and dreal(z), dimag(z), dconjg(z) up to now, but some web pages say that they are vendor extensions (though commonly supported by many compilers).

I have read various pages but the information is rather confusing (i.e., it is not very clear what is the "standard" way), so I would appreciate any advice on the choice of such functions.

Upvotes: 4

Views: 7300

Answers (1)

francescalus
francescalus

Reputation: 32406

As background, what do we mean by kinds of real and complex variables? Of course, you know what is meant by the kind of a real object.

A complex object consists of a real and an imaginary part. If a complex object has a given kind then each component is a real of kind corresponding to the kind of the complex object.

That's a long way of saying, if

complex(kind=k) z

then KIND(z%re) and KIND(z%im) both evaluate to k (using the complex part designators introduced by Fortran 2008 for clarity).

Now, the real intrinsic generic takes a complex expression and returns its real component. It does so subject to the following F2008 rule (13.7.138), where A is the argument:

If A is of type complex and KIND is not present, the kind type parameter is the kind type parameter of A.

So, yes: in current Fortran real without a requested kind will always give you a real of kind that of the complex's real component. Whether that's double precision or otherwise.

Similarly, aimag returns a real (corresponding to the imaginary part) of kind that of the complex number. Unlike real, aimag doesn't accept a kind= argument controlling the result kind.

Things are different for Fortran 77: there was no similar concept of kind, and just one complex.

dble is a standard intrinsic. Although this always returns a double precision it is still generic and will accept any numeric. dble(a) is the same as real(a,kind(0d0)), whatever the type of a. There is no (standard) specific.

dreal, dimag and dconjg are not standard intrinsics.

I suppose one could create specific wrappers around real if one cared greatly.

Upvotes: 5

Related Questions