Is the storage of COMPLEX in fortran guaranteed to

2019-01-20 13:29发布

问题:

Many FFT algorithms take advantage of complex numbers stored with alternating real and imaginary part in the array. By creating a COMPLEX array and passing it to a FFT routine, is it guaranteed that it can be cast to a REAL array (of twice the size) with alternating real and imaginary components?

    subroutine fft (data, n, isign)
      dimension data(2*n)

      do 1 i=1,2*n,2
        data(i) = ..
        data(i+1) = ..
 1    continue
    return
    end

    ...
    complex s(n)
    call fft (s, n, 1)
    ...

(and, btw, is dimension data(2*n) the same as saying it is a REAL?)

回答1:

I'm only writing this answer because experience has taught me that as soon as I do write this sort of answer one of the real Fortran experts hereabouts piles in to correct me.

I don't think that the current standard, nor any of its predecessors, states explicitly that a complex is to be implemented as two neighbouring-in-memory reals. However, I think that this implementation is a necessary consequence of the standard's definitions of equivalence and of common. I don't think I have ever encountered an implementation in which a complex was not implemented as a pair of reals.

The standard does guarantee, though that a complex can be converted into a pair of reals. So, given some definitions:

complex :: z
complex, dimension(4) :: zarr
real :: r1, r2
real, dimension(8) :: rarr

the following will do what you might expect

r1 = real(z)
r2 = aimag(z)

Both those functions are elemental and here comes a wrinkle:

real(zarr)

returns a 4-element array of reals, as does

aimag(zarr)

while

[real(zarr), aimag(zarr)]

is an 8-element array of reals with the real parts of zarr followed by the complex parts. Perhaps

rarr(1:8:2) = real(zarr)
rarr(2:8:2) = aimag(zarr)

will be OK for you. I'm not sure of any neater way to do this though.

Alexander's not the only one able to quote the standard ! The part he quotes left me wondering about non-default complex scalars. So I read on, and I think that para 6 of the section he points us towards is germane

a nonpointer scalar object of any type not specified in items (1)-(5) occupies a single unspecified storage unit that is different for each case and each set of type parameter values, and that is different from the unspecified storage units of item (4),

I don't think that this has any impact at all on any of the answers here.



回答2:

To append to Mark's answer this is indeed stated in the Standard: Clause 16.5.3.2 "Storage sequence":

2 In a storage association context

[...]

(2) a nonpointer scalar object that is double precision real or default complex occupies two contiguous numeric storage units,

emphasis mine.

As for storage association context: Clause 16.5.3.1 "General" reads

1 Storage sequences are used to describe relationships that exist among variables, common blocks, and result variables. Storage association is the association of two or more data objects that occurs when two or more storage sequences share or are aligned with one or more storage units.

So this occurs for common blocks, explicit equivalence, and result variables. As Mark's said, there is no explicit statement for the general case. My guess is, that it is most convenient to follow this always to ensure compatibility.

Thanks to IanH to pointing this out!



回答3:

No, as far as I know.

You can have storage association between a real single precision array and a complex single precision array by EQUIVALENCE, COMMON, and ENTRY statement.

But in general you cannot pass a complex array to a subroutine that expects a real array.



标签: fortran fft