| ! { dg-do run } |
| ! Check that eoshift works for three-dimensional arrays. |
| module x |
| implicit none |
| contains |
| subroutine eoshift_1 (array, shift, boundary, dim, res) |
| real, dimension(:,:,:), intent(in) :: array |
| real, dimension(:,:,:), intent(out) :: res |
| integer, dimension(:,:), intent(in) :: shift |
| real, optional, intent(in) :: boundary |
| integer, optional, intent(in) :: dim |
| integer :: s1, s2, s3 |
| integer :: n1, n2, n3 |
| integer :: sh |
| real :: b |
| integer :: d |
| |
| if (present(boundary)) then |
| b = boundary |
| else |
| b = 0.0 |
| end if |
| |
| if (present(dim)) then |
| d = dim |
| else |
| d = 1 |
| end if |
| |
| n1 = size(array,1) |
| n2 = size(array,2) |
| n3 = size(array,3) |
| |
| select case(dim) |
| case(1) |
| do s3=1,n3 |
| do s2=1,n2 |
| sh = shift(s2,s3) |
| if (sh > 0) then |
| sh = min(sh, n1) |
| do s1= 1, n1 - sh |
| res(s1,s2,s3) = array(s1+sh,s2,s3) |
| end do |
| do s1 = n1 - sh + 1,n1 |
| res(s1,s2,s3) = b |
| end do |
| else |
| sh = max(sh, -n1) |
| do s1=1,-sh |
| res(s1,s2,s3) = b |
| end do |
| do s1= 1-sh,n1 |
| res(s1,s2,s3) = array(s1+sh,s2,s3) |
| end do |
| end if |
| end do |
| end do |
| case(2) |
| do s3=1,n3 |
| do s1=1,n1 |
| sh = shift(s1,s3) |
| if (sh > 0) then |
| sh = min (sh, n2) |
| do s2=1, n2 - sh |
| res(s1,s2,s3) = array(s1,s2+sh,s3) |
| end do |
| do s2=n2 - sh + 1, n2 |
| res(s1,s2,s3) = b |
| end do |
| else |
| sh = max(sh, -n2) |
| do s2=1,-sh |
| res(s1,s2,s3) = b |
| end do |
| do s2=1-sh,n2 |
| res(s1,s2,s3) = array(s1,s2+sh,s3) |
| end do |
| end if |
| end do |
| end do |
| |
| case(3) |
| do s2=1, n2 |
| do s1=1,n1 |
| sh = shift(s1, s2) |
| if (sh > 0) then |
| sh = min(sh, n3) |
| do s3=1,n3 - sh |
| res(s1,s2,s3) = array(s1,s2,s3+sh) |
| end do |
| do s3=n3 - sh + 1, n3 |
| res(s1,s2,s3) = b |
| end do |
| else |
| sh = max(sh, -n3) |
| do s3=1,-sh |
| res(s1,s2,s3) = b |
| end do |
| do s3=1-sh,n3 |
| res(s1,s2,s3) = array(s1,s2,s3+sh) |
| end do |
| end if |
| end do |
| end do |
| |
| case default |
| stop "Illegal dim" |
| end select |
| end subroutine eoshift_1 |
| subroutine fill_shift(x, n) |
| integer, intent(out), dimension(:,:) :: x |
| integer, intent(in) :: n |
| integer :: n1, n2, s1, s2 |
| integer :: v |
| v = -n - 1 |
| n1 = size(x,1) |
| n2 = size(x,2) |
| do s2=1,n2 |
| do s1=1,n1 |
| x(s1,s2) = v |
| v = v + 1 |
| if (v > n + 1) v = -n - 1 |
| end do |
| end do |
| end subroutine fill_shift |
| end module x |
| |
| program main |
| use x |
| implicit none |
| integer, parameter :: n1=20,n2=30,n3=40 |
| real, dimension(n1,n2,n3) :: a,b,c |
| real, dimension(2*n1,n2,n3) :: a2, c2 |
| integer :: dim |
| integer, dimension(n2,n3), target :: sh1 |
| integer, dimension(n1,n3), target :: sh2 |
| integer, dimension(n1,n2), target :: sh3 |
| real, dimension(n2,n3), target :: b1 |
| real, dimension(n1,n3), target :: b2 |
| real, dimension(n1,n2), target :: b3 |
| |
| integer, dimension(:,:), pointer :: sp |
| real, dimension(:,:), pointer :: bp |
| |
| call random_number(a) |
| call fill_shift(sh1, n1) |
| call fill_shift(sh2, n2) |
| call fill_shift(sh3, n3) |
| |
| do dim=1,3 |
| if (dim == 1) then |
| sp => sh1 |
| else if (dim == 2) then |
| sp => sh2 |
| else |
| sp => sh3 |
| end if |
| b = eoshift(a,shift=sp,dim=dim,boundary=-0.5) |
| call eoshift_1 (a, shift=sp, dim=dim, boundary=-0.5,res=c) |
| if (any (b /= c)) then |
| print *,"dim = ", dim |
| print *,"sp = ", sp |
| print '(99F8.4)',b |
| print '(99F8.4)',c |
| STOP 1 |
| end if |
| a2 = 42. |
| a2(1:2*n1:2,:,:) = a |
| b = eoshift(a2(1:2*n1:2,:,:), shift=sp, dim=dim, boundary=-0.5) |
| if (any(b /= c)) then |
| STOP 2 |
| end if |
| c2 = 43. |
| c2(1:2*n1:2,:,:) = eoshift(a, shift=sp, dim=dim, boundary=-0.5) |
| if (any(c2(1:2*n1:2,:,:) /= c)) then |
| STOP 3 |
| end if |
| if (any(c2(2:2*n1:2,:,:) /= 43.)) then |
| STOP 4 |
| end if |
| end do |
| end program main |