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!

allocatable arrays problem!

Status
Not open for further replies.

milenko76

Technical User
Mar 26, 2010
100
PT
I got this:
Subscript #2 of the array X has value 3 which is greater than the upper bound of 2
How to set up bounds?

integer :: i,j,k,c,n,a
real,dimension:),:),allocatable :: x
Then comes main program:
read(10,*)n,c
a=n*c
allocate(x(n,c))
Reads 4,2 but latter values of array elements will be greater then 2.
How to solve this?
 
Don't understand what you want. If you allocate x(4, 2) you cannot later use x:),3). I think you didn't post the relevant part of the code.
 
program pr7
use def
use face
implicit none
real :: func
open(10,file='pch.dat',status='old')
open(11,file='cl.dat',status='old')
open(12,file='lj.dat',status='old')
open(14,file='b.dat',status='old')

read(10,*)n,c
a=n*c

allocate(x(n,c))
allocate(pp(a))

do i=1,n
read(11,*)(x(i,j),j=1,c)
end do

read(12,*)(pp(j),j=1,a)

allocate(work_s(a))
allocate(work_p(a))

write(*,*)x
write(*,*)pp
write(*,*)work_s
func=getvalue(pp)
write(*,*)func

deallocate(x)
deallocate(pp)
deallocate(work_s)
deallocate(work_p)
end program

function getvalue(vector)
use def
implicit none
real(kind(1d0)) getvalue
real(kind(1d0)) row_sum, total
real,dimension(n,c) :: vv
real,dimension:)), pointer:: vector
real,dimension:)), pointer :: dist_ik
vv = reshape(vector, (/ n,c /))
vector => work_p
dist_ik => work_s
total = 0d0
row_sum = 0d0
do i = 1, n
dist_ik = vv(i,:)-x(i,:)
row_sum = 1.0/dot_product(dist_ik, dist_ik) + row_sum
end do
total = 1d0/row_sum + total
getvalue= total
end function
So the problem is HERE:dist_ik = vv(i,:)-x(i,:),but how?
 
What you posted doesn't work for me. I get an error:
Code:
  func=getvalue(pp)
               1
Error: Actual argument for 'vector' must be a pointer at (1)
To get it work I used this:
Code:
  ptr_pp => pp
  func=getvalue(ptr_pp)
where the variable declarations are:
Code:
   real, dimension(:), allocatable, target :: pp
   real, dimension(:), pointer::  ptr_pp

The other problem is, how you compute dist_ik:
Code:
do i = 1, n
  dist_ik = vv(i,:) - x(i,:)
end do
When you have for example n=4 and c=2, then your matrices have dimension 4 x 2 and your array dist_ik has dimension 4*2=8.
So because the matrices have 2 columns, then the substraction above computes every time only the first 2 elements of dist_ik and other 6 elements contain junk (because you did not initialize dist_ik). Then when you compute the dot product of dist_ik (which contains junk data) you get junk result.

To demonstrate it - consider, I have:
Code:
 X=
 1. 5.
 2. 6.
 3. 7.
 4. 8.

 PP=
 10.
 10.
 10.
 10.
 10.
 10.
 10.
 10.
Then I get
Code:
 VV=
 10. 10.
 10. 10.
 10. 10.
 10. 10.
and the loop inside of the function
Code:
    do i = 1, n
      dist_ik = vv(i,:) - x(i,:)
      ...
    end do
delivers for example this:
Code:
 for i=1:
 DIST_IK=
 9.
 5.
 -9.1749E-41
 6.337112E-10
 -9.999255
 3.3926558E+27
 9.40217E-39
 1.3790198E+11

 for i=2:
 DIST_IK=
 8.
 4.
 9.458795E-39
 1.7657385E+22
 7.8996415E+34
 -10.
 816213.1
 8.442228E+8

 for i=3:
 DIST_IK=
 7.
 3.
 -1.1905E-41
 1.8176815E+31
 -10.
 -10.
 5.8524984E+7
 12.773255

 for i=4:
 DIST_IK=
 6.
 2.
 -1.2208E-41
 2.2869996E+14
 7.185757E+28
 7.6830766E+31
 0.048658613
 893.11414

IMHO, how you compute is wrong.
 
No,it gives me the same message again.The code now:
program pr7
use def
implicit none
real :: func
real(kind(1d0)) getvalue
open(10,file='pch.dat',status='old')
open(11,file='cl.dat',status='old')
open(12,file='lj.dat',status='old')
open(14,file='b.dat',status='old')
read(10,*)n,c
a=n*c

allocate(x(n,c))
allocate(pp(a))

do i=1,n
read(11,*)(x(i,j),j=1,c)
end do

read(12,*)(pp(j),j=1,a)

allocate(work_s(a))
allocate(work_p(a))

ptr_pp => pp
func=getvalue(ptr_pp)
write(*,*)func

deallocate(x)
deallocate(pp)
deallocate(work_s)
deallocate(work_p)
end program

function getvalue(vector)
use def
implicit none
real(kind(1d0)) getvalue
real(kind(1d0)) row_sum, total
real,dimension(n,c) :: vv
real,dimension:)), pointer :: vector
real,dimension:)), pointer :: dist_ik
vv = reshape(vector, (/ n,c /))
vector => work_p
dist_ik => work_s
total = 0d0
do k=1,n
row_sum = 0d0
do i = 1, c
dist_ik = vv(i,:)-x(i,:)
row_sum = 1.0/dot_product(dist_ik, dist_ik) + row_sum
end do
total = 1d0/row_sum + total
end do
getvalue= total
end function getvalue
 
module def

implicit none

integer :: i,j,k,a,n,c
real, dimension:)), allocatable, target :: work_s
real, dimension:)), allocatable, target :: work_p
real, dimension:)), allocatable, target :: pp
real, dimension:)), pointer:: ptr_pp
real, dimension:),:), allocatable :: x

end module
 
I have manage to solve the problem,mikrom you were right it was issue of initialiasing dist_ik.
 
The quick workaround with minimal code changes could be something like this:
Code:
do i = 1, n
  dist_ik = vv(i,:) - x(i,:)
  ! correction: initialize all elements from c+1 which contain junk
  dist_ik(c+1:) = 0
  ...
end do
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top