program test
integer, parameter :: nMax=5
double precision :: A(nMax,nMax)
double precision :: x(nMax*nMax)
equivalence (A, x)
(manipulations on A and on x)
end program test
In other words, an array and a vector are EQUIVALENCE'd and manipulated.
I was wondering if one can do this kind in F95. Of course I could skip
the EQUIVALENCE statement, allocate both A and x and then use e.g.
x = RESHAPE(A, /nMAX*nMAX/)
but this would need twice the RAM as both A and x need to be stored.
I think the best solution would be to avoid this kind of things at all,
but I'd like to know if there is a more modern way of achieving the same
result as the old EQUIVALENCE without using twice the memory.
Lorenzo
Yes.
...
> I think the best solution would be to avoid this kind of things at all,
> but I'd like to know if there is a more modern way of achieving the same
> result as the old EQUIVALENCE without using twice the memory.
In general, I'd agree w/ the former but I'd not worry about it too much
in existing code.
As for the latter, EQUIVALENCE is still in the Standard (and will stay
as there's simply too much existent code in use that relies on it to
make any chance of it being removed nonexistent) so there's no need.
I don't know of any other way to achieve the result any more simply
other than by dummy arguments and subroutines that move the alternate
variables to a different name space but there would be many code
constructions where that would be far more convoluted than simply the
EQUIVALENCE.
All in all, maybe I'm showing my age here ( :) ), but I'd probably leave
it alone unless it were just as simple to simply remove one variable
entirely.
--
Equivalence is still alive and well and living in Fortran! Most uses
of it are to be avoided but most is not the same as all. So "It depends!".
The real question is whether this is just memory usage saving where
A and x are used separately and never mixed or is there some reason why
two alternate indexing schemes are being used for the same data? In the
first case you can just omit the equivalence as an ancient untidiness but
in the second case you will need to understand the fine details of the
program.
"Manipulations on A and x" does not answer the question so you will need to
say more.
As long as you don't need dynamic allocation, EQUIVALENCE should
be fine. There are some restrictions on EQUIVALENCE using Fortran 90
features that you might run into.
> but this would need twice the RAM as both A and x need to be stored.
> I think the best solution would be to avoid this kind of things at all,
> but I'd like to know if there is a more modern way of achieving the same
> result as the old EQUIVALENCE without using twice the memory.
You don't say how you use either A or x, which could make a difference
in the answer. If you use RESHAPE in an array expression, it is
possible, maybe even likely, that you get a temporary array, but
in some cases one might not be needed. Unless you are on a very
small processor, if nMAX is 5 I wouldn't worry about it.
Temporary arrays can be slow, and can surprise you with the
needed memory, but sometimes they really are needed.
-- glen
> x = RESHAPE(A, /nMAX*nMAX/)
It wouldn't save you the RAM, but I would use
x = TRANSFER(A,x)
That's not just syntax!
With RESHAPE source and destination must be arrays of the same type,
e.g. arrays of REAL(R4KIND).
With TRANSFER only the size in BYTES must match.
Suppose you have this in your subroutine:
CHARACTER*4 :: DumStr
INTEGER*4 :: J
EQUIVALENCE(J,DumStr)
This cannot be resolved with RESHAPE (I think). With TRANSFER it would
be:
CHARACTER*4 :: DumStr
INTEGER*4 :: J
DumStr = TRANSFER(J,DumStr)
I use this often to convert to and from BIT-representations,
e.g. when reading binary files with a pathological structure.
Regards,
Arjan
> > double precision :: A(nMax,nMax)
> > double precision :: x(nMax*nMax)
> > equivalence (A, x)
>
> > x = RESHAPE(A, /nMAX*nMAX/)
>
> It wouldn't save you the RAM, but I would use
>
> x = TRANSFER(A,x)
I wouldn't - not for this.
> With RESHAPE source and destination must be arrays of the same type,
> e.g. arrays of REAL(R4KIND).
But in the OP's case, the types (and kinds) do match. All that is
changing is the shape. It perfectly fits the definition of RESHAPE, so
why use something more esoteric?
> With TRANSFER only the size in BYTES must match.
If I recall, not even that has to match. The fact that transfer is
allowed for many more caes is one of the reasons why I would not use it.
That means that it is less likely to give you an error message if
something is wrong. I see no evidence that the OP has those esoteric
cases. Sure, one can take something like a simplee assignment
real :: x, y
x = y
and turn it into a TRANSFER. But I wouldn't.
I'd probably go more for the suggestion made by others of leaving it
alone if it isn't broken. The code is valid f90 (and f95, f2003, and
f2008 draft) It isn't obvious that it is broken. It probably isn't the
way I'd code something new, but I'd need more specifics to know what I
would do instead.
If I were coding something new or if there was some reason that the code
really needed to be changed. two other possibilities occur to me that
have not been otherwise mentioned.
The pointer remapping feature of f2003 is right up this line. I can't
tell without more data whether it fits perfectly, but it does seem
plausible. That does need f2003. Alternatively, you can do related
things with sequence argument association. That is valid with any
version of Fortran, but it requires that the use of one of the forms be
separated into a subroutine, which might or might not be practical for
the application.
--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
Thank you all for your replies. The object in question is a scalar field
defined over three coordinates r1,r2 theta. In the program at hand it is
treated as a long array (this is because there is a symmetry in r1/r2
which allows to neglect half of the element on the r1/r2 plane). I have
to manipulate the elements in a certain way and so I need to convert
from the single vector index to three indexes, and then back to a single
vector. Creating a three-index array is not strictly indispensable as I
could write whenever necessary three expressions which given the vector
index give back (say) ir1,ir2,itheta (knowing r1MAX, etc.), but it's
just simpler to use an object which has the same structure as the data.
Lorenzo