

In nearly 30 years, I have found only one bona fide need for EQUIVALENCE, and it was easily replaced by passing the array twice to a subroutine with suitably declared array dimensions.
Code examples
program tequiv ! ! the only time an EQUIVALENCE statement was needed was to ! map a 3xN array to a 2x(3N/2) array for convenience ! and even then,this trick of passing the array as ! an argument twice handled the need. ! implicit none integer, parameter :: MAXDIM3 = 2000 real, dimension(3,MAXDIM3) :: vector3 real, dimension(MAXDIM3) :: radial3 integer, dimension(21) :: rbin integer :: i call gausspdf(vector3=vector3, radial3=radial3, gauss2=vector3) call binrad(bin=rbin, radvec=radial3) ! write output suitable for piping into GNUPLOT open(unit=11, file="equiv.dat", status='UNKNOWN') do i=1,MAXDIM3 write(11,'(1x,4f15.5)') vector3(1:3,i), radial3(i) enddo close(unit=11) open(unit=11, file="equivrad.dat", status='UNKNOWN') do i=1,21 write(11,'(1x,2f15.5)') real(i-1)*.25, rbin(i)/real(MAXDIM3) enddo close(unit=11) write(6,*) 'set nokey' write(6,*) 'set title "x-y distribution"' write(6,*) 'plot "equiv.dat" using 1:2' write(6,*) 'pause 5 "x-y distribution"' write(6,*) 'set title "x-z distribution"' write(6,*) 'plot "equiv.dat" using 1:3' write(6,*) 'pause 5 "x-z distribution"' write(6,*) 'set title "y-z distribution"' write(6,*) 'plot "equiv.dat" using 2:3' write(6,*) 'pause 5 "y-z distribution"' write(6,*) 'set title "r distribution"' write(6,*) 'plot "equivrad.dat" using 1:2 with lines' write(6,*) 'pause 5 "r distribution"' write(6,*) 'quit' contains subroutine gausspdf(vector3, radial3, gauss2) implicit none real, dimension(:,:), intent(inout) :: vector3 ! 3-N vector ! we need vector3 inout because we use the size of it,hence "in" real, dimension(:), intent(out) :: radial3 ! radii real, dimension(2,*), intent(out) :: gauss2 ! convenience vector ! same as vector3 ! automatic arrays and local variables real, dimension(size(vector3)/2) :: r2gauss2 real, dimension(2,size(vector3)/2) :: ranvec logical, dimension(size(vector3)/2) :: maskgauss2 ! don't use initialization here, else the value will be SAVE'd across calls integer :: maxg ! dimension of gauss2 maskgauss2 = .TRUE. maxg = size(vector3)/2 ! compute the Gaussian distribution using the Box-Muller method ! as described by Forsythe, Malcolm, and Moler generate: do call random_number(ranvec) ! create random number in range [-1.0,1.0) ! use vector masking, must have same shape where (maskgauss2) gauss2(1,1:maxg) = (2.0*ranvec(1,1:maxg) - 1.0) gauss2(2,1:maxg) = (2.0*ranvec(2,1:maxg) - 1.0) r2gauss2 = gauss2(1,1:maxg)**2 + gauss2(2,1:maxg)**2 end where where (r2gauss2 > 1.0) maskgauss2 = .TRUE. else where maskgauss2 = .FALSE. end where ! if not within range, go back and do it again for the afflicted entries if (.not. any(maskgauss2)) exit generate end do generate where (r2gauss2 .ne. 0.0) r2gauss2 = sqrt(-2.0*log(r2gauss2)/r2gauss2) gauss2(1,1:maxg) = gauss2(1,1:maxg) * r2gauss2 gauss2(2,1:maxg) = gauss2(2,1:maxg) * r2gauss2 end where radial3 = vector3(1,:)**2 + vector3(2,:)**2 + vector3(3,:)**2 radial3 = sqrt(radial3) end subroutine gausspdf subroutine binrad(bin, radvec) integer, dimension(:) :: bin real, dimension(:) :: radvec ! initialize bin count bin = 0 ! bin size = .25 where (radvec < 5.0) bin(int(radvec/.25)+1) = bin(int(radvec/.25)+1) + 1 end where return end subroutine binrad end program tequiv

