Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

POINTING TO RAGGED ARRAYS IN FORTRAN 90

Status
Not open for further replies.

simon2010

Technical User
Apr 16, 2009
7

Hi there. I am trying to modularize my code as it is getting complicated. However, the code is causing me problems. Below is a simplified version of the problem. It would be great if anyone knows a solution or even a completely alternative approach. Thanks in advance even just for comments!

I have some data. Each set "data_set=1,nset" of data has "idata=1,npoints(data_set)" data points. For each data point there corresponds a 5 dimensional array of numbers which I use for a calculation related to that data point.

So to store all these numbers I use the object "numbers_data(5,nset)", whose type is an rank-1 allocatable
array "nd_part:))", by allocating "numbers_data(i,data_set)%nd_part", "i=1,5", for each value of "data_set" to have "npoints(data_set)" components. Here is the program:

module type_nd
type nd
complex*16, allocatable :: nd_part:))
end type
end module type_nd

use type_nd

implicit none

integer nset
parameter(nset=2)

type(nd) :: numbers_data(5,nset)

integer data_set,idata,npoints(nset),i

npoints(1)=3
npoints(2)=9

do data_set=1,nset
do i=1,5
allocate(numbers_data(i,data_set)%nd_part(npoints(data_set)))
enddo
enddo

c Now let's assign the components of the arrays to something

do data_set=1,nset
do i=1,5
do idata=1,npoints(data_set)
numbers_data(i,data_set)%nd_part(idata)=dfloat(idata)
enddo
enddo
enddo

c Now print some out to check (the result should be equal to 4 in each case)

do i=1,5
print*, 'numbers_data=',numbers_data(i,2)%nd_part(4)
enddo

end

The above program works with no problem. However, I want to do something more involved. As I said, the 5-dimensional array corresponding to each data point needs to go into a calculation which is independent of the value of "idata" and "data_set". What I could do is, for each value of "idata" and "data_set", copy the 5 components of numbers_data to a simple 5 dimensional array which is to be used in the calculation. However, this takes up too much valuable time. So instead I use a pointer, "numbers". Now in the declaration above, "type(nd) :: numbers_data(5,nset)",
"numbers_data" becomes a "target":

type(nd), target :: numbers_data(5,nset)

and I add the declaration

complex*16, pointer :: numbers:))

So now suppose I want to pick out the 5 numbers for the data point "data_set=2", "idata=4". Then, at the end of the above program, I insert

data_set=2
idata=2

numbers=>numbers_data(1:5,data_set)%nd_part(idata)

Now when I print them out I should get the answer "2" again (because "idata=2"):

do i=1,5
print*, 'dd=',numbers(i)
enddo

But I don't (actually I get 0, 5, 0, 4, 0 in that order!), and I have no idea why.

Furthermore, I have another problem, maybe related. If I instead take "idata=4" above, i.e.

data_set=2
idata=4

numbers=>numbers_data(1:5,data_set)%nd_part(idata)

then I get the error message "0: Subscript out of range for array numbers_data%nd_part (temp.f: 52) <newline> subscript=4, lower bound=1, upper bound=3, dimension=1"

(I compiled using pgf95_7.1 -Mbounds -Mextend -o temp temp.f. If I omit the "-Mbounds" flag the error message goes away but then I get 0, 7, 0, 6, 0 as output.)

 
0: Subscript out of range for array numbers_data%nd_part (temp.f: 52) <newline> subscript=4, lower bound=1, upper bound=3, dimension=1
It meams that you try to use nd_part(4), but only nd_part(1)..nd_part(3) are available.
If you have a debugger, it could not be so big problem to figure it out.

But, I don't understand your source right - for example what means this
Code:
do data_set=1,nset
  do i=1,5
    allocate(numbers_data(i,data_set)%nd_part(npoints(data_set)))
  enddo
enddo
when nset=2 you are doing
Code:
allocate(numbers_data(1,1)%nd_part(npoints(1)))
allocate(numbers_data(2,1)%nd_part(npoints(1)))
allocate(numbers_data(3,1)%nd_part(npoints(1)))
allocate(numbers_data(4,1)%nd_part(npoints(1)))
allocate(numbers_data(5,1)%nd_part(npoints(1)))
allocate(numbers_data(1,2)%nd_part(npoints(2)))
allocate(numbers_data(2,2)%nd_part(npoints(2)))
allocate(numbers_data(3,2)%nd_part(npoints(2)))
allocate(numbers_data(4,2)%nd_part(npoints(2)))
allocate(numbers_data(5,2)%nd_part(npoints(2)))
when npoints(1)=3 and npoints(2)=9 then it means
Code:
allocate(numbers_data(1,1)%nd_part(3))
allocate(numbers_data(2,1)%nd_part(3))
allocate(numbers_data(3,1)%nd_part(3))
allocate(numbers_data(4,1)%nd_part(3))
allocate(numbers_data(5,1)%nd_part(3))
allocate(numbers_data(1,2)%nd_part(9))
allocate(numbers_data(2,2)%nd_part(9))
allocate(numbers_data(3,2)%nd_part(9))
allocate(numbers_data(4,2)%nd_part(9))
allocate(numbers_data(5,2)%nd_part(9))
What does it mean? And whatfor stands the % here?
 
Firstly, thanks mikrom for responding so quickly.

Secondly, e.g. "allocate(numbers_data(3,2)%nd_part(9))" means to allocate 9 components, i.e. "numbers_data(3,2)%nd_part(i)" is allocated with "i=1,...,9". The "%" means to take the element "nd_part" (which is in fact the only element of a variable of "type(cd)" - see the "type cd" definition at the beginning of the code).

Thirdly, please note that this part of the code you commented on above works perfectly - the problem occurs not with "numbers_data" but with "numbers", in this part of the code:

data_set=2
idata=2

numbers=>numbers_data(1:5,data_set)%nd_part(idata)

Then "numbers(i)" should be equal to "numbers_data(i,data_set)%nd_part(idata)" for "i=1,...,5". But it isn't.
 
Hi simon2010,

I looked at your program. Your data structure is a matrix of 5 x 2 i.e. 5 rows and 2 colums
Code:
  parameter(nset=2)
  !type(nd) :: numbers_data(5,nset)
  type(nd), target :: numbers_data(5,nset)
which elements are of type nd i.e. allocatable complex fields
Code:
  type nd
    complex*16, allocatable :: nd_part(:)
  end type
You allocated these fields for first colum with dimension 3 and for second column with dimension 9.

Now I defined the pointer field in this way
Code:
  !complex*16, pointer :: numbers(:)
  type(nd), pointer :: numbers(:)
because IMHO: the pointer can point at a continuous memory area, e.g. it can point at first column, or second column of the matrix, but it cannot point e.g. at all fifth compnents of second column as you tried with this statement.
Code:
numbers=>numbers_data(1:5,data_set)%nd_part(idata)
It's because the fifth components of column 2 are not ordered consecutively in memory - try to draw your data structure and you will understand.

So I used this association of pointer with the target and this works:
Code:
numbers=>numbers_data(1:5,data_set)

Here is your program I modified a little bit:
simon2010n.f95
Code:
[COLOR=#a020f0]module[/color] type_nd
  [COLOR=#2e8b57][b]type[/b][/color] nd
    [COLOR=#2e8b57][b]complex[/b][/color][COLOR=#804040][b]*[/b][/color][COLOR=#ff00ff]16[/color], [COLOR=#2e8b57][b]allocatable[/b][/color] :: nd_part(:)
  [COLOR=#2e8b57][b]end type[/b][/color]
[COLOR=#a020f0]end module[/color] type_nd

[COLOR=#a020f0]program[/color] simon2010      
  [COLOR=#a020f0]use[/color] type_nd

  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]

  [COLOR=#2e8b57][b]integer[/b][/color] nset
  [COLOR=#2e8b57][b]parameter[/b][/color](nset[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]2[/color])

  [COLOR=#0000ff]!type(nd) :: numbers_data(5,nset)[/color]
  [COLOR=#2e8b57][b]type[/b][/color](nd), [COLOR=#2e8b57][b]target[/b][/color] :: numbers_data([COLOR=#ff00ff]5[/color],nset)
  [COLOR=#0000ff]!complex*16, pointer :: numbers(:)[/color]
  [COLOR=#2e8b57][b]type[/b][/color](nd), [COLOR=#2e8b57][b]pointer[/b][/color] :: numbers(:)

  [COLOR=#2e8b57][b]integer[/b][/color] data_set,idata,npoints(nset),i,data_value

  npoints([COLOR=#ff00ff]1[/color])[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]3[/color]
  npoints([COLOR=#ff00ff]2[/color])[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]9[/color]

  [COLOR=#0000ff]! Now Allocating the components of the array[/color]
  [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]"! Now Allocating the components of the array"[/color]
  [COLOR=#804040][b]do[/b][/color] data_set[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]1[/color],nset
    [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]"data_set ="[/color], data_set   
    [COLOR=#804040][b]do[/b][/color] i[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]1[/color],[COLOR=#ff00ff]5[/color]
      [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]' allocate(numbers_data('[/color],i,[COLOR=#ff00ff]','[/color],data_set,[highlight #ffff00][COLOR=#0000ff]&[/color][/highlight]
               [COLOR=#ff00ff]')%nd_part(npoints('[/color],data_set,[COLOR=#ff00ff]')))'[/color]
      [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]'=allocate(numbers_data('[/color],i,[COLOR=#ff00ff]','[/color],data_set,[highlight #ffff00][COLOR=#0000ff]&[/color][/highlight]
               [COLOR=#ff00ff]')%nd_part('[/color],npoints(data_set),[COLOR=#ff00ff]'))'[/color]
      [COLOR=#804040][b]allocate[/b][/color](numbers_data(i,data_set)%nd_part(npoints(data_set)))
    [COLOR=#804040][b]enddo[/b][/color]
  [COLOR=#804040][b]enddo[/b][/color]

  [COLOR=#0000ff]! Now let's assign the components of the arrays to something[/color]
  [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color],
  [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]"! Now let's assign the components of the arrays to something"[/color]

  [COLOR=#804040][b]do[/b][/color] data_set[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]1[/color],nset
    [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]'data_set ='[/color], data_set 
    [COLOR=#804040][b]do[/b][/color] i[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]1[/color],[COLOR=#ff00ff]5[/color]
       [COLOR=#804040][b]do[/b][/color] idata[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]1[/color],npoints(data_set)
         [COLOR=#804040][b]if[/b][/color] (data_set [COLOR=#804040][b].eq.[/b][/color] [COLOR=#ff00ff]1[/color]) [COLOR=#804040][b]then[/b][/color]
           data_value [COLOR=#804040][b]=[/b][/color] idata[COLOR=#804040][b]*[/b][/color][COLOR=#ff00ff]10[/color]
         [COLOR=#804040][b]else[/b][/color] 
           data_value [COLOR=#804040][b]=[/b][/color] idata
         [COLOR=#804040][b]endif[/b][/color]
         [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]'numbers_data('[/color],i,[COLOR=#ff00ff]','[/color],data_set,[COLOR=#ff00ff]')%nd_part('[/color],idata,[highlight #ffff00][COLOR=#0000ff]&[/color][/highlight]
         [COLOR=#ff00ff]')=dfloat('[/color],idata,[COLOR=#ff00ff]')='[/color],[COLOR=#008080]dfloat[/color](data_value)         
         numbers_data(i,data_set)%nd_part(idata)[COLOR=#804040][b]=[/b][/color][COLOR=#008080]dfloat[/color](data_value)
       [COLOR=#804040][b]enddo[/b][/color]
    [COLOR=#804040][b]enddo[/b][/color]
  [COLOR=#804040][b]enddo[/b][/color]

  [COLOR=#0000ff]! Now print some out to check (the result should be equal to 4 in each case)[/color]
  [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color],
  [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]"! Now print some out to check "[/color],[highlight #ffff00][COLOR=#0000ff]&[/color][/highlight]
           [COLOR=#ff00ff]"(the result should be equal to 4 in each case)"[/color]

  [COLOR=#804040][b]do[/b][/color] i[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]1[/color],[COLOR=#ff00ff]5[/color]
    [COLOR=#804040][b]print[/b][/color][COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]'numbers_data('[/color],i,[COLOR=#ff00ff]',2)%nd_part(4)='[/color],numbers_data(i,[COLOR=#ff00ff]2[/color])%nd_part([COLOR=#ff00ff]4[/color])
  [COLOR=#804040][b]enddo[/b][/color]

  [COLOR=#0000ff]!***************************************************************************[/color]
  [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color],
  [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]'! Now print using pointer'[/color]

  data_set[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]2[/color]
  idata[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]4[/color]
  [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]'All '[/color],idata,[COLOR=#ff00ff]'-th components from '[/color],data_set,[COLOR=#ff00ff]'column'[/color]
  
  [COLOR=#0000ff]!numbers=>numbers_data(1:5,data_set)%nd_part(idata)[/color]
  numbers[COLOR=#804040][b]=>[/b][/color]numbers_data([COLOR=#ff00ff]1[/color]:[COLOR=#ff00ff]5[/color],data_set)

  [COLOR=#804040][b]do[/b][/color] i[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]1[/color],[COLOR=#ff00ff]5[/color]
    [COLOR=#804040][b]print[/b][/color][COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]'numbers('[/color],i,[COLOR=#ff00ff]')%nd_part('[/color],idata,[COLOR=#ff00ff]')='[/color], numbers(i)%nd_part(idata)
  [COLOR=#804040][b]enddo[/b][/color]

  data_set[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]1[/color]
  idata[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]3[/color]
  [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]'All '[/color],idata,[COLOR=#ff00ff]'-th components from '[/color],data_set,[COLOR=#ff00ff]'column'[/color]
  
  numbers[COLOR=#804040][b]=>[/b][/color]numbers_data(:,data_set)

  [COLOR=#804040][b]do[/b][/color] i[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]1[/color],[COLOR=#ff00ff]5[/color]
    [COLOR=#804040][b]print[/b][/color][COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]'numbers('[/color],i,[COLOR=#ff00ff]')%nd_part('[/color],idata,[COLOR=#ff00ff]')='[/color], numbers(i)%nd_part(idata)
  [COLOR=#804040][b]enddo[/b][/color]
  
[COLOR=#a020f0]end program[/color] simon2010
Output:
Code:
$ g95 simon2010n.f95 -o simon2010n

$ simon2010n
 ! Now Allocating the components of the array
 data_set = 1
  allocate(numbers_data( 1 , 1 )%nd_part(npoints( 1 )))
 =allocate(numbers_data( 1 , 1 )%nd_part( 3 ))
  allocate(numbers_data( 2 , 1 )%nd_part(npoints( 1 )))
 =allocate(numbers_data( 2 , 1 )%nd_part( 3 ))
  allocate(numbers_data( 3 , 1 )%nd_part(npoints( 1 )))
 =allocate(numbers_data( 3 , 1 )%nd_part( 3 ))
  allocate(numbers_data( 4 , 1 )%nd_part(npoints( 1 )))
 =allocate(numbers_data( 4 , 1 )%nd_part( 3 ))
  allocate(numbers_data( 5 , 1 )%nd_part(npoints( 1 )))
 =allocate(numbers_data( 5 , 1 )%nd_part( 3 ))
 data_set = 2
  allocate(numbers_data( 1 , 2 )%nd_part(npoints( 2 )))
 =allocate(numbers_data( 1 , 2 )%nd_part( 9 ))
  allocate(numbers_data( 2 , 2 )%nd_part(npoints( 2 )))
 =allocate(numbers_data( 2 , 2 )%nd_part( 9 ))
  allocate(numbers_data( 3 , 2 )%nd_part(npoints( 2 )))
 =allocate(numbers_data( 3 , 2 )%nd_part( 9 ))
  allocate(numbers_data( 4 , 2 )%nd_part(npoints( 2 )))
 =allocate(numbers_data( 4 , 2 )%nd_part( 9 ))
  allocate(numbers_data( 5 , 2 )%nd_part(npoints( 2 )))
 =allocate(numbers_data( 5 , 2 )%nd_part( 9 ))

 ! Now let's assign the components of the arrays to something
 data_set = 1
 numbers_data( 1 , 1 )%nd_part( 1 )=dfloat( 1 )= 10.
 numbers_data( 1 , 1 )%nd_part( 2 )=dfloat( 2 )= 20.
 numbers_data( 1 , 1 )%nd_part( 3 )=dfloat( 3 )= 30.
 numbers_data( 2 , 1 )%nd_part( 1 )=dfloat( 1 )= 10.
 numbers_data( 2 , 1 )%nd_part( 2 )=dfloat( 2 )= 20.
 numbers_data( 2 , 1 )%nd_part( 3 )=dfloat( 3 )= 30.
 numbers_data( 3 , 1 )%nd_part( 1 )=dfloat( 1 )= 10.
 numbers_data( 3 , 1 )%nd_part( 2 )=dfloat( 2 )= 20.
 numbers_data( 3 , 1 )%nd_part( 3 )=dfloat( 3 )= 30.
 numbers_data( 4 , 1 )%nd_part( 1 )=dfloat( 1 )= 10.
 numbers_data( 4 , 1 )%nd_part( 2 )=dfloat( 2 )= 20.
 numbers_data( 4 , 1 )%nd_part( 3 )=dfloat( 3 )= 30.
 numbers_data( 5 , 1 )%nd_part( 1 )=dfloat( 1 )= 10.
 numbers_data( 5 , 1 )%nd_part( 2 )=dfloat( 2 )= 20.
 numbers_data( 5 , 1 )%nd_part( 3 )=dfloat( 3 )= 30.
 data_set = 2
 numbers_data( 1 , 2 )%nd_part( 1 )=dfloat( 1 )= 1.
 numbers_data( 1 , 2 )%nd_part( 2 )=dfloat( 2 )= 2.
 numbers_data( 1 , 2 )%nd_part( 3 )=dfloat( 3 )= 3.
 numbers_data( 1 , 2 )%nd_part( 4 )=dfloat( 4 )= 4.
 numbers_data( 1 , 2 )%nd_part( 5 )=dfloat( 5 )= 5.
 numbers_data( 1 , 2 )%nd_part( 6 )=dfloat( 6 )= 6.
 numbers_data( 1 , 2 )%nd_part( 7 )=dfloat( 7 )= 7.
 numbers_data( 1 , 2 )%nd_part( 8 )=dfloat( 8 )= 8.
 numbers_data( 1 , 2 )%nd_part( 9 )=dfloat( 9 )= 9.
 numbers_data( 2 , 2 )%nd_part( 1 )=dfloat( 1 )= 1.
 numbers_data( 2 , 2 )%nd_part( 2 )=dfloat( 2 )= 2.
 numbers_data( 2 , 2 )%nd_part( 3 )=dfloat( 3 )= 3.
 numbers_data( 2 , 2 )%nd_part( 4 )=dfloat( 4 )= 4.
 numbers_data( 2 , 2 )%nd_part( 5 )=dfloat( 5 )= 5.
 numbers_data( 2 , 2 )%nd_part( 6 )=dfloat( 6 )= 6.
 numbers_data( 2 , 2 )%nd_part( 7 )=dfloat( 7 )= 7.
 numbers_data( 2 , 2 )%nd_part( 8 )=dfloat( 8 )= 8.
 numbers_data( 2 , 2 )%nd_part( 9 )=dfloat( 9 )= 9.
 numbers_data( 3 , 2 )%nd_part( 1 )=dfloat( 1 )= 1.
 numbers_data( 3 , 2 )%nd_part( 2 )=dfloat( 2 )= 2.
 numbers_data( 3 , 2 )%nd_part( 3 )=dfloat( 3 )= 3.
 numbers_data( 3 , 2 )%nd_part( 4 )=dfloat( 4 )= 4.
 numbers_data( 3 , 2 )%nd_part( 5 )=dfloat( 5 )= 5.
 numbers_data( 3 , 2 )%nd_part( 6 )=dfloat( 6 )= 6.
 numbers_data( 3 , 2 )%nd_part( 7 )=dfloat( 7 )= 7.
 numbers_data( 3 , 2 )%nd_part( 8 )=dfloat( 8 )= 8.
 numbers_data( 3 , 2 )%nd_part( 9 )=dfloat( 9 )= 9.
 numbers_data( 4 , 2 )%nd_part( 1 )=dfloat( 1 )= 1.
 numbers_data( 4 , 2 )%nd_part( 2 )=dfloat( 2 )= 2.
 numbers_data( 4 , 2 )%nd_part( 3 )=dfloat( 3 )= 3.
 numbers_data( 4 , 2 )%nd_part( 4 )=dfloat( 4 )= 4.
 numbers_data( 4 , 2 )%nd_part( 5 )=dfloat( 5 )= 5.
 numbers_data( 4 , 2 )%nd_part( 6 )=dfloat( 6 )= 6.
 numbers_data( 4 , 2 )%nd_part( 7 )=dfloat( 7 )= 7.
 numbers_data( 4 , 2 )%nd_part( 8 )=dfloat( 8 )= 8.
 numbers_data( 4 , 2 )%nd_part( 9 )=dfloat( 9 )= 9.
 numbers_data( 5 , 2 )%nd_part( 1 )=dfloat( 1 )= 1.
 numbers_data( 5 , 2 )%nd_part( 2 )=dfloat( 2 )= 2.
 numbers_data( 5 , 2 )%nd_part( 3 )=dfloat( 3 )= 3.
 numbers_data( 5 , 2 )%nd_part( 4 )=dfloat( 4 )= 4.
 numbers_data( 5 , 2 )%nd_part( 5 )=dfloat( 5 )= 5.
 numbers_data( 5 , 2 )%nd_part( 6 )=dfloat( 6 )= 6.
 numbers_data( 5 , 2 )%nd_part( 7 )=dfloat( 7 )= 7.
 numbers_data( 5 , 2 )%nd_part( 8 )=dfloat( 8 )= 8.
 numbers_data( 5 , 2 )%nd_part( 9 )=dfloat( 9 )= 9.

 ! Now print some out to check (the result should be equal to 4 in each case)
 numbers_data( 1 ,2)%nd_part(4)= (4.,0.)
 numbers_data( 2 ,2)%nd_part(4)= (4.,0.)
 numbers_data( 3 ,2)%nd_part(4)= (4.,0.)
 numbers_data( 4 ,2)%nd_part(4)= (4.,0.)
 numbers_data( 5 ,2)%nd_part(4)= (4.,0.)

 ! Now print using pointer
 All  4 -th components from  2 column
 numbers( 1 )%nd_part( 4 )= (4.,0.)
 numbers( 2 )%nd_part( 4 )= (4.,0.)
 numbers( 3 )%nd_part( 4 )= (4.,0.)
 numbers( 4 )%nd_part( 4 )= (4.,0.)
 numbers( 5 )%nd_part( 4 )= (4.,0.)
 All  3 -th components from  1 column
 numbers( 1 )%nd_part( 3 )= (30.,0.)
 numbers( 2 )%nd_part( 3 )= (30.,0.)
 numbers( 3 )%nd_part( 3 )= (30.,0.)
 numbers( 4 )%nd_part( 3 )= (30.,0.)
 numbers( 5 )%nd_part( 3 )= (30.,0.)

 
Hi Mikron,

Thanks again, for taking the time to write a detailed reply.
I see exactly what you mean, and I think your method is probably my only option.

The problem is, the part of my code that uses "numbers" is some numerical calculation which doesn't care or know about the data, including data labels such as idata. This numerical calculation just needs these 5 numbers, i.e. it should be possible to run this numerical calculation in other applications where data sets are not given. My reason for using the pointer "numbers" was just to feed in these 5 numbers from a given data point idata into this numerical calculation as efficiently as possible while keeping the code modular.

So, in other words I can achieve code modularisation by the following interface between the data sets and the numerical calculation:

! numbers=>numbers_data(1:5,data_set)%nd_part(idata)
do i=1,5
numbers(i)=numbers_data(i,data_set)%nd_part(idata)
enddo

but this copying gives unusably slow code. Or I can achieve efficiency by using your method

! numbers=>numbers_data(1:5,data_set)%nd_part(idata)
numbers=>numbers_data(1:5,data_set)

but then in the numerical calculation I have to refer explicitly to the data point, i.e. "numbers( i )%nd_part( idata )" refers to data point idata, which ruins the modularisation of the code.
 
Hi Simon,

You can write your numerical calculation as a standalone function to separate data from computation
e.g.

1) define function with fixed number of parameters, e.g. 5
Code:
real function my_calculation(n1, n2, n3, n4, n5)
  implicit none
  complex*16 :: n1, n2, n3, n4, n5
  ...
  
end function my_calculation
and pass the components as a parameter
Code:
! without pointer fields
data_set=2
idata=4
my_result = &
  my_calculation(numbers_data(1,data_set)%nd_part(idata),
                 numbers_data(2,data_set)%nd_part(idata),
                 numbers_data(3,data_set)%nd_part(idata),
                 numbers_data(4,data_set)%nd_part(idata),
                 numbers_data(5,data_set)%nd_part(idata))

! with pointer field
data_set=1
idata=3
numbers=>numbers_data(:,data_set)
my_result = &
  my_calculation(numbers(1)%nd_part(idata),
                 numbers(2)%nd_part(idata),
                 numbers(3)%nd_part(idata),
                 numbers(4)%nd_part(idata),
                 numbers(5)%nd_part(idata))

2) Or you can define your function with array of n elements as an argument
Code:
real function my_calculation(my_array, n)
  implicit none
  integer :: n
  complex*16 :: my_array(n)
  ...

end function my_calculation
and try to pass the arguments at similar way like this:
Code:
! without pointer fields
data_set=2
idata=4
my_result = &
  my_calculation(numbers_data(1:5,data_set)%nd_part(idata), 5)

! with pointer field
data_set=2
idata=4
numbers=>numbers_data(:,data_set)
my_result = &
  my_calculation(numbers(1:5)%nd_part(idata), 5)

I'm not at 100% sure if it works but it must be a way to do something like this.

 
Hi Mikron,

Thanks for continuing to help. The problem in these cases you just gave is that the code becomes slow. I have to avoid copying explicit numbers (in my actual code it is not 5 numbers but more like 1 million!) which is why I wanted to use pointers. As far as I can tell, in all cases in your last reply the 5 numbers have to be explicitly copied from one place to another, even where you used pointers(?)

I was hoping to keep to the spirit of my original code. It seems the pointing of "numbers" is not being does as intended, instead "numbers" points to random, perhaps unallocated parts of memory instead. The reason for this, as I understand from your second reply, is that I am trying to point to array components which are not consecutively ordered in memory.

I was hoping the solution would be something like "declare as numbers_data(nset,5) instead of as numbers_data(5,nset)" (that example doesn't work though).
 
>The reason for this, as I understand from your second reply, is that I am trying to point to array components which are not consecutively ordered in memory.
Yes it was my opinion, but I was possibly wrong, because I found now this
and here is an example given in a file
that you can pick up a rectangular portion of a rank 2 array
e.g. when original array is
Code:
a(1:10,1:10) =                  
row   1  1001.  1002.  1003.  1004.  1005.  1006.  1007.  1008.  1009.  1010.
row   2  2001.  2002.  2003.  2004.  2005.  2006.  2007.  2008.  2009.  2010.
row   3  3001.  3002.  3003.  3004.  3005.  3006.  3007.  3008.  3009.  3010.
row   4  4001.  4002.  4003.  4004.  4005.  4006.  4007.  4008.  4009.  4010.
row   5  5001.  5002.  5003.  5004.  5005.  5006.  5007.  5008.  5009.  5010.
row   6  6001.  6002.  6003.  6004.  6005.  6006.  6007.  6008.  6009.  6010.
row   7  7001.  7002.  7003.  7004.  7005.  7006.  7007.  7008.  7009.  7010.
row   8  8001.  8002.  8003.  8004.  8005.  8006.  8007.  8008.  8009.  8010.
row   9  9001.  9002.  9003.  9004.  9005.  9006.  9007.  9008.  9009.  9010.
row  10 10001. 10002. 10003. 10004. 10005. 10006. 10007. 10008. 10009. 10010.
so you can pick with
Code:
p2 => a(3:6,7:9)
this portion
Code:
row   1  3007.  3008.  3009.
row   2  4007.  4008.  4009.
row   3  5007.  5008.  5009.
row   4  6007.  6008.  6009.
...And I would wonder if these array elements are consecutively ordered in memory (how ?)

But I can remember, when I tried your pointer approach
Code:
numbers=>numbers_data(1:5,data_set)%nd_part(idata)
I got an compiler error (g95 and gforran), something like that
...%nd_part(idata) cannot be allocatable...
 
I would say, try to define your nd_part:)) not as allocatable, if it then works or not?

In your array you have only 2 columns (data sets), the elements of first data set have 3 components and the elements of second data sets have 9 elements.
Would it not be possible to define instead 2 simple arrays (one with 3-components elements and other with 9-components elements? Maybe then the pointer approach would work as you want...
 
Unfortunately the required size of nd_part:)) varies - if I just chose the largest size, my code would be too big. Also, your method would work for 2 data sets, but what an arbitrary number of data sets and / or not necessarily 3 and 9 points in each set?

I'm wondering if someone hasn't written some code that provides for pointing to components of an array which are not consecutively ordered in memory(?)
 
Hi Simon,

In one dataset you can only have elements of the same number of parts, e.g. as in the above example?
Or can you have mixed elements e.g. could in data set 1 occur some elemnts with 3 parts and other elements with 9 parts?



 
Hi Mikron,

In "numbers_data(i,data_set)%nd_part(idata)" for a given "i" and a given "data_set", we have "idata=1,...,npoints(data_set)", where "npoints(data_set)" is independent of "i" (i.e. the same for all values of "i").

I think you were asking whether it is possible for e.g. "numbers_data(i,1)%nd_part(idata)" to have idata=1,...,3 for one value of i and idata=1,...,9 for another value of i. The answer then is no. The range of "idata" is the same for all "i", but this range ("idata=1,...,npoints(data_set)") does depend on "data_set".
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top