How to Search and Replace Values in Fortran Arrays?

Click For Summary

Discussion Overview

The discussion revolves around a Fortran programming problem involving two data sets. Participants are attempting to modify a program to search for specific values in one data set and compute averages based on corresponding values from another data set. The focus is on correcting the logic to ensure values are searched rather than using line numbers.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant describes their data sets and the intended operation of averaging values based on searches in another data set.
  • Another participant points out confusion regarding the use of line numbers instead of values for searching, suggesting a need for clarity in the program's logic.
  • There is a suggestion to improve variable naming for better code readability.
  • Participants discuss the need to implement a search mechanism that finds values in the first column of the second data set rather than relying on line numbers.
  • A proposed solution involves iterating through the first column of the second data set to find matching values and then using the corresponding second column values for averaging.
  • One participant attempts to implement a replacement operation but reports that it does not work as intended, seeking further assistance.

Areas of Agreement / Disagreement

Participants generally agree on the need to search for values rather than using line numbers, but there is no consensus on the specific implementation details or whether the proposed solutions are effective.

Contextual Notes

There are unresolved issues regarding the correct implementation of the search functionality and the logic for replacing values in the arrays. Participants have expressed confusion over the structure of their data and the intended operations.

timewilltell
Messages
13
Reaction score
0
hi i have two data sets one(data1) containing

3
8 2 1 5 7 9
9 2 2 5 7 7
10 3 6 6 6 6

and other(data2) containing

5
1 10
5 20
7 30
6 40
9 50

now i want my program to search the values 1 5 7 9 from (data1) in data 2 column 1 and then take the average of the corresoinding values in column 2, for example for first line of data1 the avg of (1 5 7 9) will be

(10+20+30+50)/4=27.5

then write

8 2 27.5
and so on... till now i have written the following program,

program test
implicit none
integer :: pn,en
integer :: i
real ,allocatable, dimension (:,:) :: y
integer,allocatable,dimension (:,:) :: ix
REAL ,DIMENSION (:) :: avg(10000000)
open (11, file='data1.dat')
read (11,*) pn
allocate (y(pn,2))
do i=1,pn
read(11,*) y(i,:)
enddo
close(11)

c *************************
open(12,file='data2.dat')
read (12,*) en
allocate (ix(en,6))
do i=1,en
read(12,*) ix(i,:)
enddo
close(12)

c *************************
do i=1,en
avg(i)=(y(ix(i,3),2)+y(ix(i,4),2)+y(ix(i,5),2)+
& y(ix(i,6),2))/4
end do
do i=1,en
write(*,*) ix(i,1:2),avg(i)

enddo
end program

this gives me output

8 2 15
9 2 17.5
10 3 0

which is wrong. instead of searching for value it searches for line number ... so what to change in it to search for value not line number
 
Physics news on Phys.org
timewilltell said:
hi i have two data sets one(data1) containing

3
8 2 1 5 7 9
9 2 2 5 7 7
10 3 6 6 6 6

and other(data2) containing

5
1 10
5 20
7 30
6 40
9 50

now i want my program to search the values 1 5 7 9 from (data1) in data 2 column 1 and then take the average of the corresoinding values in column 2, for example for first line of data1 the avg of (1 5 7 9) will be

(10+20+30+50)/4=27.5
OK, I sort of get what you're doing here. For the set of values in data1 -- {1, 5, 7, 9} -- use each value as the line number, and take the value in data 2 from that line.
timewilltell said:
then write

8 2 27.5

and so on...
And so on? You need to be clearer in what you're trying to do here. I see where 27.5 is coming from, but where are the 8 and 2 coming from? They happen to be the first two numbers in the line in data 1 where you found 1, 5, 7, and 9, but I'm not sure that's it.

It would be helpful if you explained what each line of data in each file represents.


timewilltell said:
till now i have written the following program,

program test
implicit none
integer :: pn,en
integer :: i
real ,allocatable, dimension (:,:) :: y
integer,allocatable,dimension (:,:) :: ix
REAL ,DIMENSION (:) :: avg(10000000)
open (11, file='data1.dat')
read (11,*) pn
allocate (y(pn,2))
do i=1,pn
read(11,*) y(i,:)
enddo
close(11)

c *************************
open(12,file='data2.dat')
read (12,*) en
allocate (ix(en,6))
do i=1,en
read(12,*) ix(i,:)
enddo
close(12)

c *************************
do i=1,en
avg(i)=(y(ix(i,3),2)+y(ix(i,4),2)+y(ix(i,5),2)+
& y(ix(i,6),2))/4
end do
do i=1,en
write(*,*) ix(i,1:2),avg(i)

enddo
end program

this gives me output

8 2 15
9 2 17.5
10 3 0

which is wrong. instead of searching for value it searches for line number ... so what to change in it to search for value not line number
 
yes you are right in the output

8 and 2 are first two numbers from data1 and 27.5 is the average.
ok i will explain

for example the first line in data1

Code:
8    2    1    5    7    9
, 8 and 2 are just selected and printed in the output as it is no operation on them. Now the program should take value 1 find this value in the column 1 of data two and similarly 5 , 7 and 9 and then take the average of the corresponsing values in column 2 of data2.

Code:
(10+20+30+50)/4=27.5

i have made the program but instead of searching for value it searches for line number and take average... so what to change in it to search for value not line number
 
I'm not sure, but I think you have your files and arrays switched around.

Unit 11 is your data 1 file, but the array you're working with has only two columns. It needs six columns.
Your code:
Code:
open (11, file='data1.dat')
read (11,*) pn
allocate (y(pn,2))

Your other array is read from unit 12, which is associated with data 2. This array needs to have two columns, not six.

Your code:
Code:
open(12,file='data2.dat')
read (12,*) en
allocate (ix(en,6))

It would also be helpful if you used array names that were more meaningful than "ix" and "y" and file names more meaningful than data1.dat and data2.dat. Give each array a name that suggests where its data is coming from. Having poorly chosen names confused you, and makes understanding your code more difficult than it needs to be.
 
O sorry for that, yup i have switched it in confusion

Let this data set be "xdata.dat"

Code:
 3
 8    2    1     5     7     9
 9    2    2     5     7     7
 10  3    6     6     6     6

and this data set be "ydata.dat

Code:
5 
1    10
5    20
7    30 
6    40
9    50

Code:
 program test
 implicit none
 integer :: pn,en
 integer :: i 
 real ,allocatable, dimension (:,:) :: y
 integer,allocatable,dimension (:,:) :: x
 REAL ,DIMENSION (:) :: avg(10000000)
 open (11, file='ydata.dat')
 read (11,*) pn
 allocate (y(pn,2)) 
 do i=1,pn
 read(11,*) y(i,:)
 enddo
 close(11)

 c *************************
 open(12,file='xdata.dat')
 read (12,*) en
 allocate (x(en,6))
 do i=1,en
 read(12,*) x(i,:)
 enddo
 close(12)
 
c *************************
 do i=1,en 
 avg(i)=(y(x(i,3),2)+y(x(i,4),2)+y(x(i,5),2)+
 & y(x(i,6),2))/4
 end do 
 do i=1,en
 write(*,*) x(i,1:2),avg(i)
 
 enddo
 end program
 
Does it work now?

BTW, thanks for putting your code in [ code ] tags. Makes it much easier to read.
 
No, i coz i have changed nothing in the code... the file names i have switched by mistake when posting here... i am getting average with respect to line number not with respect to value of the array.
 
timewilltell said:
No, i coz i have changed nothing in the code... the file names i have switched by mistake when posting here... i am getting average with respect to line number not with respect to value of the array.
I don't see anything wrong in your code.

After you read in your x array, add a loop that prints the values. Put a write statement in your next to last loop (where you calculate avg) to make sure that you're getting what you think you're getting with y(x(i, 3), 2), y(x(i, 4), 2), and so on. If there's something wrong here, I'm not seeing it, but having the program print the values it's using will help in understanding what's going on.
 
Ok ill try to explain the problem more elaborately

for instance i select 5 from first line of file xdata.dat

Code:
8    2    1     5     7     9

now its fourth element is 5. When i am taking the average the program should search for this value "5" in the first column of file "ydata.dat" but instead of searching it select the second column element on line number 5. i want the program to search for this value
 
  • #10
OK, I get it. I understand what it's supposed to be doing.

Using your example, x(1, 4) == 5. Now search through the first column of your y array until you find an entry that equals 5. In this case, it's y(2, 1). When you find it, get the value in the second column, which in this case would be y(2, 2), which is 20 in this case. That's the value you want to use for the average.
 
  • #11
yup this is i have tried to do this

Code:
do i=1,5
do j=3,6
if (x(i,j)==y(i,1)) then
x(i,j)=y(i,2)
end if
end do
end do

but this don't work... wha i am trying to do is replace the matching values with the corresponding values in the second column that is change this file

Code:
3
 8    2    1     5     7     9
 9    2    2     5     7     7
 10  3    6     6     6     6

to this

Code:
3
 8    2    10     20    30    50
 9    2    0       20    30    30
 10  3    40     40    40    40

any help in how to to this?
 
  • #12
Mark44 said:
OK, I get it. I understand what it's supposed to be doing.

Using your example, x(1, 4) == 5. Now search through the first column of your y array until you find an entry that equals 5. In this case, it's y(2, 1). When you find it, get the value in the second column, which in this case would be y(2, 2), which is 20 in this case. That's the value you want to use for the average.

timewilltell said:
yup this is i have tried to do this

Code:
do i=1,5
do j=3,6
if (x(i,j)==y(i,1)) then
x(i,j)=y(i,2)
end if
end do
end do
This isn't what I said. I didn't say anything about changing the values in the x array.

Suppose you're reading the first row of the x array, and you see that x(1, 3) == 1.

Iterate through the first column of the y array in a do loop until you find a value that is 1.
Code:
do j = 1,5
  if x(1, 3) .eq. y(j, 1) avg = avg + y(j, 2)
end do

You need to do this for each of the last four values in a row of the x array.

Mark44 said:
but this don't work... wha i am trying to do is replace the matching values with the corresponding values in the second column that is change this file

Code:
3
 8    2    1     5     7     9
 9    2    2     5     7     7
 10  3    6     6     6     6

to this

Code:
3
 8    2    10     20    30    50
 9    2    0       20    30    30
 10  3    40     40    40    40

any help in how to to this?
 

Similar threads

  • · Replies 4 ·
Replies
4
Views
2K
Replies
7
Views
3K
  • · Replies 10 ·
Replies
10
Views
3K
  • · Replies 7 ·
Replies
7
Views
2K
  • · Replies 7 ·
Replies
7
Views
2K
  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 21 ·
Replies
21
Views
3K
  • · Replies 2 ·
Replies
2
Views
6K
  • · Replies 7 ·
Replies
7
Views
5K
Replies
2
Views
2K