0

First time post here, and I had a (likely very simple) question.

I wanted to assign the values of elements in one array (A) based on the corresponding values in another array(B), eg if A(1)=2 assign 4 to B(1).

I imagined this would be achieved using DO loops and some if statements. However the If staments I'm using seem to refering to the loop index rather than the specific element at that point.

Can anyone point me in the right direction ?

2
  • 2
    It's not clear what you're trying to do. Can you provide some code and an example of what it's supposed to do? Commented Sep 10, 2014 at 23:29
  • There is nothing bad with loops. I am always surprised to see people inventing very clever array expressions, just to avoid loops which are probably more efficient. Commented Sep 11, 2014 at 13:26

2 Answers 2

2

You could also try a construct with merge... merge constructs a new array from two existing arrays using a mask to choose the correct value:

program test
  integer,parameter :: LENGTH=5
  integer :: A(LENGTH)
  integer :: B(LENGTH)
  real    :: R(LENGTH)
  integer :: i

  call random_number(R)
  A = int( R*3 )
  B = [ ( i,i=1,LENGTH) ]

  print *,'A:',A

  print *,'B:',B
  B = merge( 4, B, A == 2 )
  print *,'B:',B
end program

Output:

 A:           2           1           2           2           1
 B:           1           2           3           4           5
 B:           4           2           4           4           5

Explanation:

  B = merge( 4, B, A == 2 )
  • A == 2 constructs a temporary logical array which is .true. at i if A(i) == 2
  • 4 in this case is a temporary array with the same length as B
  • So, merge choses the value from 4 if the temporary logical array is .true., and the correspond value from B, otherwise.
  • The resulting vector is written back to B (=)
Sign up to request clarification or add additional context in comments.

Comments

1

You might be able to use masked array assignment. Given two arrays, A and B, of the same shape (ie same number of ranks, same size in each dimension), and if you wanted to set elements of B to 4 where the corresponding element of A equals 2 you could simply write

where(A==2) B = 4

where teams up with elsewhere, rather like if and else if, and there is an end where too. Consult your favourite documentation for further details.

If you can't express your operation with where you might (if you have an up to date compiler) be interested in the do concurrent construct. And, if all else fails, there are good old-fashioned do and if to fall back on.

1 Comment

I ought to add, in recognition of the point Francois Jacq makes above, that too much of modern Fortran programming time is indeed spent devising very clever array expressions, comparing them with equivalent loop-based code (which would have taken about 1/10th the time to devise), and then learning that the loop-based approach is faster. where is neat, but don't be surprised if do gets to the prize.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.