arrays - Pointer to subarray defined by a map -
i want define pointer subarray. simple range done pointer => array(i:j), can't figure out how map k=[k1,k2,k3]. if define array utilize loop array2=[(array1(k(j)),j=1,size(k,1))]. isn't possible assign pointer in similar way (pointer => [(array1(k(j)),j=1,size(k,1))]) since r.h.s. of look seems define variabel not has target attribute. simple tasks, trick around this, first assign pointer total array utilize map on readout. in case doesn't seem possible.
i attach examples: first 1 shows described above. sec 1 more complicated example, trick doesn't work anymore. , in add-on 2 dimensional map required.
minimal example:
program test integer, parameter :: n=10,n_k=3 real,target :: a(1:n) real :: b(1:n_k) integer :: k(1:n_k) integer :: j real,pointer :: p(:) ! fill array , define map k: a=[(real(j),j=1,n)] k=[((j+1)*2,j=1,n_k)] ! can used print arrays: !write(*,*) !write(*,*) k ! can used write part of defined k: !write(*,*) (a(k(j)),j=1,n_k) ! similar things didn't work: !p(1:n_k) => [(a(k(j)),j=1,n_k)] ! works, not generally: p => write(*,*) (p(k(j)),j=1,n_k) ! works, arrays: b=(/(a(k(j)),j=1,n_k)/) write(*,*) b end programme more complicated (but kind of minimal) illustration shows (hopefully) problem have. easy understanding explanation leads through it. there plenty of write commands print arrays. appreciate amount of code, don't see how create shorter , understandable working example:
module mod1 type base of operations real :: end type type,extends(base) :: type1 end type type,extends(base) :: type2 type(type1),allocatable :: b(:) end type type(type2),allocatable,target :: c(:) contains subroutine printer(z) class(*),pointer,dimension(:) :: z integer :: j,a_z,n_z character(len=40) :: f,ff='(f10.2,1x))',form_z ! define format printing: a_z=lbound(z,1) n_z=ubound(z,1) write(f,'(i0)') (n_z-a_z+1) form_z="("//trim(adjustl(f))//ff ! writing: select type(z) class (base) write(*,form_z) (z(j)%a,j=a_z,n_z) end select end subroutine end module programme test utilize mod1 integer,parameter :: n_b=8,n_c=6,n_js=3,n_ls=2 integer :: js(1:n_js),ls(1:n_ls) integer :: j,l class(*),pointer :: p(:) character(len=40) :: f,ff='(f10.2,1x))',form_c,form_b ! define format printing: write(f,'(i0)') n_b form_b="("//trim(adjustl(f))//ff write(f,'(i0)') n_c form_c="("//trim(adjustl(f))//ff ! creating , filling arrays: allocate(c(n_c)) c%a=[(2d0*real(j),j=1,n_c)] j=1,n_c allocate(c(j)%b(n_b)) c(j)%b%a=[(real(l)*1d1**(j-1),l=1,n_b)] end ! write arrays compare later: write(*,form_c) c%a write(*,*) write(*,form_b) (c(j)%b%a,j=1,n_c) write(*,*) ! denfining 2 maps (size , entries input in final program): js=[1,4,6] ls=[2,7] ! using maps print desired entries: write(*,*) (c(js(j))%a,j=1,n_js) write(*,*) write(*,*) ((c(js(j))%b(ls(l))%a,j=1,n_js),l=1,n_ls) write(*,*) ! !!! here want utilize maps well, far know how utilize ranges: p => c(1:4) phone call printer(p) write(*,*) p => c(2)%b(3:6) phone call printer(p) write(*,*) end programme edit: record, solved problem using arrays of derived types including pointers , changing calling subroutines.
you cannot pointer association (e.g. pointer1 => array1(vector_subscript). section 7.2.2.2 of fortran 2008 standard disallows is:
r733 pointer-assignment-stmt is data-pointer-object [ (bounds-spec-list) ] => data-target
there 2 other forms, not match use, nor alter outcome. reading further:
r737 data-target is variable c724 (r737) variable shall have either target or pointer attribute, , shall not array section vector subscript.
this why cannot perform pointer association attempting. can work around , pointer allocation. see code:
n_k = 3 k = [((j+1)*2,j=1,n_k)] ! vector subscript p => a(k) ! not ok. violates c724 allocate(p(n_k)) ! associate pointer way p = a(k) ! ok. write(*,*) p which yields (wrapped in illustration program):
% ./ptrtest 4.00000000 6.00000000 8.00000000 this allocates p proper size , assigns a vector subscript. gets around issue of straight associating p map of a. snippet assumes variables declared , initialized per illustration code. shows can assign vector subscript of array pointer, 1 associated, not during association.
as noted in comment q, if have regular stride, can create pointer association directly. first test case, equivalent , work:
p => a(4:2:8) ! allocation strided array allowed if however, have irregular vector subscript method in reply need utilize accomplish pointer association.
another workaround can utilize passing pointer , map procedure. consider next code:
program test implicit none integer, parameter :: nx = 10, nx_m = 3 integer,dimension(nx_m) :: x_map integer :: real, dimension(nx),target :: real, dimension(:), pointer :: p ! initialize array = [(real(i*2),i=1,10)] write (*,'(10(f5.1 x))') !define map x_map = [1, 9, 4] ! associate pointer p => phone call print_map(p, x_map) contains subroutine print_map(apointer, map) implicit none real, dimension(:), pointer :: apointer integer, dimension(:) :: map write (*,*) apointer(map) end subroutine print_map end programme test in case, p "knows" a , map of elements in a can calculated in caller. rather associating (=>) p map of a (which cannot done), p associated a , map passed along it.
this code produces output:
% ./ptrtest3 2.0 4.0 6.0 8.0 10.0 12.0 14.0 16.0 18.0 20.0 2.00000000 18.0000000 8.00000000 arrays pointers fortran
No comments:
Post a Comment