On 4/20/19 10:45 AM, FortranFan wrote:
> On Saturday, April 20, 2019 at 8:19:20 AM UTC-4, Thomas Koenig wrote:
>
>> ..
>> subroutine foo
>> complex (kind=8) :: a(5)
>> call bar(a,10)
>> end
>> ..
>> subroutine bar(a,n)
>> real(kind=8) :: a(n)
>> end
>>
>> .. probably a common idiom (or it would probably not have
>> made it into LAPACK) ..
>
>
> One would guess codes such as LAPACK, if they employed such idioms, either used ASSUMED SIZE array e.g., a(*) in the dummy argument declaration in 'bar' or automatic arrays of twice the size e.g., a(2*n).
No, they worked mostly as the poster described. The actual array was
declared as 5 and the dummy argument is declared as 10. It was up to the
programmer to put in the factor of 2.
They also worked the other way around, with a REAL actual argument and a
COMPLEX dummy argument. Again, it was up to the programmer to get the
factor of 1/2 right in the calling sequence.
>
> And if a subprogram such as 'bar' only intended to work with REAL part of the complex data, then it must have had logic to explicitly skip over the imaginary parts in the array 'a'.
>
The storage sequence rules required the odd indexes to be the real part
and the even indexes to be the complex part.
The reason for all of this type punning is that many compilers had
notoriously poor implementations of complex arithmetic, both with
protections against unnecessary overflow and underflow and with
efficiency. Some operations, such as division of a complex by a real
were especially inefficient. So it was often the case that the
programmer could take the real and imaginary parts of the complex number
and do the work himself much better than the compiler could do it.
Another reason was that it was not possible to reference just the real
or imaginary part of a complex number in f77, or prior to f2003, for
that matter. So if you wanted to do, for example, a simple assignment of
just the imaginary part, leaving the real part unchanged, that was not
possible. Instead, you had to assign the whole complex value,
overwriting the real part unnecessarily with its original value. This
was a design flaw in the language, it was not just a matter of compiler
efficiency. This was finally corrected in f2003, but of course that was
decades after millions of lines of code had been written in various
linear algebra and signal processing libraries that had been based on
the storage sequence trick.
And as others have pointed out, f77 only had single precision COMPLEX
type, it did not define the behavior of anything corresponding to double
precision or other extended precision types. Although double precision
complex, or the alternative complex*16, were common extensions, they
were not standard. So that was yet another reason for writing complex
arithmetic libraries in terms of real variables and arrays.
$.02 -Ron Shepard