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 strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problems storing variable values within nested if loop

Status
Not open for further replies.

dac5039

Programmer
Aug 12, 2009
22
US
Hello,

The subroutine below receives an array of derived type data and uses the data within to run logical tests. I've been successful in writing the results to a text file, but am unable to store them in an array within the subroutine and print it to the terminal.

***Derived Type Definition***
Code:
module my_temps
	type temps
		integer :: dates, hi, lo, av
		real :: hinorms, lonorms
	end type temps
	
	contains
[...]
*********

The input 'array' below contains some 40k+ lines of data of type 'temps'. The lines added since I've been having problems are in bold.

Code:
subroutine high_norm_runs(array)
			implicit none
			type(temps), allocatable :: array(:)
			integer :: i, n, upcount, downcount, maxuprun, maxdownrun
			integer :: upbins(0:50) = (0), downbins(0:50) = 0
			integer, allocatable :: allups(:), alldowns(:), [b]allruns(:,:)[/b]
			
			n = size(array)
			allocate(allups(n))
			allocate(alldowns(n))
			[b]allocate(allruns(n,3))[/b]
			upcount = 0
			downcount = 0
			maxuprun = 0
			maxdownrun = 0
			
			do i = 1, n
				if(array(i)%hinorms /= 99.99) then
					if(array(i)%hi > array(i)%hinorms) then
						if(downcount > maxdownrun) then
							maxdownrun = downcount
						endif
						downbins(downcount) = downbins(downcount) + 1
						upcount = upcount + 1
						if(downcount /= 0) then
							alldowns(i) = downcount
							[b]allruns(i,1) = array(i)%dates
							allruns(i,2) = 0
							allruns(i,3) = downcount[/b]
							!write(3,*) array(i)%dates, '-',downcount 
						end if
						downcount = 0
					else
						if (upcount > maxuprun) then
							maxuprun = upcount
						end if
						upbins(upcount) = upbins(upcount) + 1
						downcount = downcount + 1
						if(upcount /= 0) then
							allups(i) = upcount
							[b]allruns(i,1) = array(i)%dates
							allruns(i,2) = 1
							allruns(i,3) = upcount[/b]
							!write(3,*) array(i)%dates, ' ',upcount
						end if
						upcount = 0						
					end if
				end if
			end do
			
			!do i = 1, 50
			!	write(*,*) '[',i,']:', upbins(i), downbins(i)
			!	write(2,*) upbins(i), downbins(i)
			!end do
			
			write (*,*) maxuprun, maxdownrun
			!write (2,*) maxuprun, maxdownrun
			!write (2,*)
			
			[b]do i = 1, 100
				write(*,*) allruns(i,1), allruns(i,2), allruns(i,3)
			end do[/b]
			
		end subroutine high_norm_runs

And here's the problem output:

[...]
Histogram of Tmax above/below Tnorm
32 42
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
[...]

Obviously not what I want. I think this is a problem of my understanding of either if loops or subroutines.

The entire script is attached, in case it is needed. The successfully written text file (the data within which I want to store to an array instead) is attached also.

Thanks for any input,

Dave
 
Hi dac5039,
I cannot run your program because you didn't post all files which the program reads, for example
'c:\perl\scripts\496\rescraped_trend_space.txt'
 
The problem is, how you fill the values into your array
allruns(i,j).
In the do loop you fill the array, only when a condition is fulfilled. That causes that your array is not filled for every value of the index i, i.e. there are empty holes in your array.
When you write on the 2 places of your do loop this debug printout
Code:
 write(*,*) '*dbg:', i, allruns(i,1), allruns(i,2), allruns(i,3)
you will get
Code:
 *dbg: 10965 19260108 1 7
 *dbg: 10968 19260111 0 3
 *dbg: 10970 19260113 1 2
 *dbg: 10972 19260115 0 2
...
 *dbg: 41447 20090623 0 6
 *dbg: 41451 20090627 1 4
 *dbg: 41471 20090717 0 20
So, your array is filled only for some value of index, starting with index 10965 and ending with index 41471.

And now at end you try to print the first 100 values so
Code:
            do i = 1, 100
                write(*,*) allruns(i,1), allruns(i,2), allruns(i,3)
            end do
And that's your problem. Print them so
Code:
			do i = 1, n
				write(*,*) allruns(i,1), allruns(i,2), allruns(i,3)
			end do
and you will see, that, there are some non zero values
:)
 
Oh, I forgot. Here is the subroutine I inspected
Code:
		subroutine high_norm_runs(array)
			implicit none
			type(temps), allocatable :: array(:)
			integer :: i, n, upcount, downcount, maxuprun, maxdownrun
			integer :: upbins(0:50) = (0), downbins(0:50) = 0
			integer, allocatable :: allups(:), alldowns(:), allruns(:,:)
			
			n = size(array)
			allocate(allups(n))
			allocate(alldowns(n))
			allocate(allruns(n,3))
			upcount = 0
			downcount = 0
			maxuprun = 0
			maxdownrun = 0
			
			do i = 1, n
				if(array(i)%hinorms /= 99.99) then
					if(array(i)%hi > array(i)%hinorms) then
						if(downcount > maxdownrun) then
							maxdownrun = downcount
						endif
						downbins(downcount) = downbins(downcount) + 1
						upcount = upcount + 1
						if(downcount /= 0) then
							alldowns(i) = downcount
							allruns(i,1) = array(i)%dates
							allruns(i,2) = 0
							allruns(i,3) = downcount
							!write(3,*) array(i)%dates, '-',downcount
              write(*,*) '*dbg:', i, allruns(i,1), allruns(i,2), allruns(i,3)
						end if
						downcount = 0
					else
						if (upcount > maxuprun) then
							maxuprun = upcount
						end if
						upbins(upcount) = upbins(upcount) + 1
						downcount = downcount + 1
						if(upcount /= 0) then
							allups(i) = upcount
							allruns(i,1) = array(i)%dates
							allruns(i,2) = 1
							allruns(i,3) = upcount
							!write(3,*) array(i)%dates, ' ',upcount
              write(*,*) '*dbg:', i, allruns(i,1), allruns(i,2), allruns(i,3)
						end if
						upcount = 0						
					end if
				end if
			end do
			
			!do i = 1, 50
			!	write(*,*) '[',i,']:', upbins(i), downbins(i)
			!	write(2,*) upbins(i), downbins(i)
			!end do
			
			write (*,*) maxuprun, maxdownrun
			!write (2,*) maxuprun, maxdownrun
			!write (2,*)
			
			do i = 1, n
				write(*,*) allruns(i,1), allruns(i,2), allruns(i,3)
			end do
			
		end subroutine high_norm_runs
 
To fill your array without index holes I introduced a new index k.
Here is the corrected source of your subroutine
Code:
		subroutine high_norm_runs(array)
			implicit none
			type(temps), allocatable :: array(:)
			integer :: i, n, upcount, downcount, maxuprun, maxdownrun, k
			integer :: upbins(0:50) = (0), downbins(0:50) = 0
			integer, allocatable :: allups(:), alldowns(:), allruns(:,:)
			
			n = size(array)
			allocate(allups(n))
			allocate(alldowns(n))
			allocate(allruns(n,3))
			upcount = 0
			downcount = 0
			maxuprun = 0
			maxdownrun = 0
			k=1
			do i = 1, n
				if(array(i)%hinorms /= 99.99) then
					if(array(i)%hi > array(i)%hinorms) then
						if(downcount > maxdownrun) then
							maxdownrun = downcount
						endif
						downbins(downcount) = downbins(downcount) + 1
						upcount = upcount + 1
						if(downcount /= 0) then
							alldowns(i) = downcount
							allruns(k,1) = array(i)%dates
							allruns(k,2) = 0
							allruns(k,3) = downcount
							!write(3,*) array(i)%dates, '-',downcount
							k = k + 1
						end if
						downcount = 0
					else
						if (upcount > maxuprun) then
							maxuprun = upcount
						end if
						upbins(upcount) = upbins(upcount) + 1
						downcount = downcount + 1
						if(upcount /= 0) then
							allups(i) = upcount
							allruns(k,1) = array(i)%dates
							allruns(k,2) = 1
							allruns(k,3) = upcount
							!write(3,*) array(i)%dates, ' ',
							k = k + 1              
						end if
						upcount = 0						
					end if
				end if
			end do
			
			!do i = 1, 50
			!	write(*,*) '[',i,']:', upbins(i), downbins(i)
			!	write(2,*) upbins(i), downbins(i)
			!end do
			
			write (*,*) maxuprun, maxdownrun
			!write (2,*) maxuprun, maxdownrun
			!write (2,*)
			
			do i = 1, 100
				write(*,*) allruns(i,1), allruns(i,2), allruns(i,3)
			end do
			
		end subroutine high_norm_runs
Now you can look at your 100 values. The output is:
Code:
 Histogram of Tmax above/below Tnorm
 32 42
 19260108 1 7
 19260111 0 3
 19260113 1 2
 19260115 0 2
 19260122 1 7
 19260126 0 4
 19260127 1 1
 19260130 0 3
 19260204 1 5
 19260205 0 1
 19260209 1 4
 19260212 0 3
 19260213 1 1
 19260214 0 1
 19260216 1 2
 19260217 0 1
 19260220 1 3
 19260221 0 1
 19260223 1 2
 19260224 0 1
 19260227 1 3
 19260228 0 1
 19260303 1 3
 19260306 0 3
 19260308 1 2
 19260318 0 10
 19260326 1 8
 19260329 0 3
 ...
 
I'm pained by my oversight haha. Thank you for the help.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top